bRAWcap 1.1.0
b-plus Technologies - Ethernet Performance Transmitter Receiver
Loading...
Searching...
No Matches
08_receive_timestamp_inspector_f.c

This example shows how to configure the different timestamp modes and read timestamp information from single received packets. It opens a handle to the first available bRAWcap adapter, creates a bRAWcap packet to store received data to and applies the configured timestamp mode. For each received packet it will print it´s applied timestamp info.

1/**
2 * @file 08_receive_timestamp_inspector_f.c
3 *
4 * @brief bRAWcap Example - Demonstrates how to use bRAWcap to use different receive timestamp modes.
5 *
6 * It shows how to:
7 * - Open a handle to the first available adapter
8 * - Configure the receive timestamp mode
9 * - Create a bRAWcap packet object
10 * - Receive single packets from the adapter
11 * - Access received packet timestamp.
12 *
13 * This example makes use of C only.
14 *
15 * @version 1.1
16 *
17 * @date 2023-03-30
18 *
19 * HISTORY:
20 * - 2023-03-30: Initial version
21 * - 2023-08-10: Set all indentation to 4 spaces
22 *
23 *
24 * @copyright
25 * <b> © 2021 - b-plus technologies GmbH. All rights reserved!</b>
26 *
27 * All rights exclusively reserved for b-plus GmbH, unless expressly otherwise agreed.
28 *
29 * Redistribution in source or any other form, with or without modification, is not permitted.
30 *
31 * You may use this code under the according license terms of b-plus.
32 * Please contact b-plus at services@b-plus.com to get the appropriate terms and conditions.
33 */
34// Include bRAWcap
35#include "libbrawcap.h"
36
37// C STD
38#include <stdio.h> // for printf
39#include <time.h> // for converting to readable time (gmtime)
40
41/* Check command line parameters if a custom timestamp mode or accuracy is specified
42 * The timestamp mode can be configured with the "-m" parameter.
43 * Possible values are:
44 * - No: Create no timestamp
45 * - DriverSysLow: Timestamp by driver from system time (low precision)
46 * - DriverSysHigh: Timestamp by driver from system time (high precision)
47 * - DriverSw: Timestamp by driver from software (QPC)
48 * - AdapterSys: Timestamp by adapter driver from system time
49 * - AdapterSw: Timestamp by adapter from software (QPC)
50 * - AdapterHw: Timestamp by adapter from hardware clock
51 *
52 * The timestamp accuracy can be configured with the "-r" parameter.
53 * Possible values are:
54 * - ns: Nanoseconds
55 * - us: Microseconds
56 * - ms: Miliseconds
57 */
58void ParseArgs(int argc, char** argv, brawcap_timestamp_mode_t* pMode, int* pAccuracy)
59{
60 for(int index = 0; index < argc; ++index)
61 {
62 if(!memcmp(argv[index], "-m", 2))
63 {
64 if(!strcmp(argv[index + 1], "No"))
66 else if(!strcmp(argv[index + 1], "DriverSysLow"))
68 else if(!strcmp(argv[index + 1], "DriverSysHigh"))
70 else if(!strcmp(argv[index + 1], "DriverSw"))
72 else if(!strcmp(argv[index + 1], "AdapterSys"))
74 else if(!strcmp(argv[index + 1], "AdapterSw"))
76 else if(!strcmp(argv[index + 1], "AdapterHw"))
78 else
79 printf("[WARNING] Unknown timestamp mode - will use default mode.\n");
80 }
81 else if(!memcmp(argv[index], "-r", 2))
82 {
83 if(!strcmp(argv[index + 1], "ns"))
84 *pAccuracy = 1;
85 else if(!strcmp(argv[index + 1], "us"))
86 *pAccuracy = 2;
87 else if(!strcmp(argv[index + 1], "ms"))
88 *pAccuracy = 3;
89 else
90 printf("[WARNING] Unknown accuracy - will use default accuracy.\n");
91 }
92 }
93}
94
95int main(int argc, char** argv)
96{
97 // Set console title
98 SetConsoleTitleA("bRAWcap Example - Receive Timestamp Inspector");
99
100 // Some generic helper locals...
101 int retVal = 0;
102 unsigned char demoModeLogged = 0;
103 unsigned long long packetCounter = 0;
104 int accuracy = 1;
105
106 // Set the default timestamp mode to system low precision
108
109 // Here we will store the status of any bRAWcap function
111
112 // Here we store the number of available bRAWcap adapters
113 brawcap_adapter_count_t numberAdapters = 0;
114 // This will contain our bRAWcap handle to the adapter we want to receive from
115 brawcap_handle_t* pHandle = 0;
116 // Our local packet for storing received data
117 brawcap_packet_t* pPacket = 0;
118
119 // Parse command line argument for selected timestamp mode
120 ParseArgs(argc, argv, &timestampMode, &accuracy);
121
122 do
123 {
124 // First check if we have any bRAWcap adapters available.
125 // --> This function can only fail if we did something wrong.
126 // But we are sure that we did everything right...
127 // therefore we do not check it�s status.
128 brawcap_adapter_list_count(&numberAdapters);
129
130 // No adapters... nothing do receive from... lets exit ...
131 if (!numberAdapters)
132 {
133 printf("[WARNING] No bRAWcap adapter available... Will stop now.\n");
134 break;
135 }
136
137 // Get the name of the first adapter.
138 // To not overload the example with complex stuff,
139 // we always go for the first available adapter.
140 brawcap_adapter_name_t name = { '\0' };
142 {
143 printf("[ERROR] Unexpected status while retrieving adapter name: %d\n", brawcap_last_status());
144 retVal = -1;
145 break;
146 }
147
148 // Open a handle to the adapter by using the retrieved name.
149 if (!BRAWCAP_SUCCESS(brawcap_open(name, &pHandle)))
150 {
151 printf("[ERROR] Unexpected status while opening handle: %d\n", brawcap_last_status());
152 retVal = -1;
153 break;
154 }
155
156 // Lets see what timestamp modes we have on the specified adapter
157 brawcap_timestamp_capabilities_t timestampCapabilities;
158 if(!BRAWCAP_SUCCESS(brawcap_rx_timestamp_capabilities(pHandle, &timestampCapabilities)))
159 {
160 printf("[ERROR] Unexpected status while retrieving timestamp capabilities: %d\n", brawcap_last_status());
161 retVal = -1;
162 break;
163 }
164
165 // Print available adapter timestamp capabilities to console before we start reading packets
166 // We only check for adapter modes explicitly because all other modes are always available.
167 printf("ADAPTER TIMESTAMP CAPABILITIES: \n");
168 printf(" - System: %s\n", timestampCapabilities & BRAWCAP_TIMESTAMP_MODE_ADAPTER_SYSTEM ? "yes" : "no");
169 printf(" - Software: %s\n", timestampCapabilities & BRAWCAP_TIMESTAMP_MODE_ADAPTER_SOFTWARE ? "yes" : "no");
170 printf(" - Hardware: %s\n", timestampCapabilities & BRAWCAP_TIMESTAMP_MODE_ADAPTER_HARDWARE ? "yes" : "no");
171 printf("\n");
172
173 // Check if configured timestamp mode is available... if not exit now...
174 if(timestampMode && !(timestampMode & timestampCapabilities))
175 {
176 printf("[ERROR] Specified timestamp mode is not available on the adapter... will exit now.\n");
177 retVal = -1;
178 break;
179 }
180
181 // Apply the configured timestamp mode to the previously opened handle.
182 if(!BRAWCAP_SUCCESS(brawcap_rx_timestamp_mode_set(pHandle, timestampMode)))
183 {
184 printf("[ERROR] Unexpected status while applying configured timestamp mode: %d\n", brawcap_last_status());
185 retVal = -1;
186 break;
187 }
188
189 // Create a packet object
190 // For simplicity and to make sure that we get all packets,
191 // we set the payload size to the max supported value.
193 {
194 printf("[ERROR] Unexpected status while creating packet: %d\n", brawcap_last_status());
195 retVal = -1;
196 break;
197 }
198
199 // Some local variables to buffer the timestamp info, later on.
200 brawcap_timestamp_t* pTimestamp = 0;
203 UINT64 sec = 0;
204 UINT32 ns = 0;
205
206 // Our receive loop, we stay in here until we should stop receiving.
207 while(1)
208 {
209 // Now lets see if we have received a packet...
210 status = brawcap_rx_packet(pHandle, pPacket);
211
212 // Seems like we had success and got some packet data to look at. :-)
213 if(BRAWCAP_SUCCESS(status))
214 {
215 // Check if we made it out of the demo limitation... :-D
216 // ... notify the user and go ahead with receiving.
217 if (demoModeLogged)
218 {
219 printf("[NOTICE] DEMO MODE: Limitation period elapsed, receiving is available again.\n");
220 demoModeLogged = 0;
221 }
222
223 // --> The bRAWcap functions below can only fail if we did something wrong.
224 // But we are sure that we did everything right...
225 // therefore we do not check their status.
226 brawcap_packet_timestamp_get(pPacket, &pTimestamp);
227 brawcap_timestamp_mode_get(pTimestamp, &source);
228 brawcap_timestamp_resolution_ns_get(pTimestamp, &resolution);
229 switch(accuracy)
230 {
231 case 1:
232 brawcap_timestamp_value_ns_get(pTimestamp, &sec, &ns);
233 break;
234 case 2:
235 brawcap_timestamp_value_us_get(pTimestamp, &sec, &ns);
237 break;
238 case 3:
239 brawcap_timestamp_value_ms_get(pTimestamp, &sec, &ns);
241 break;
242 }
243 struct tm tmpStruct;
244 struct tm *tmp = &tmpStruct;
245 gmtime_s(tmp, (time_t*)&sec);
246
247 // Print the packet timestamp info to console
248 printf("%llu. Received Packet Timestamp:\n", ++packetCounter);
249 printf(" - Source/Mode: ");
250 switch(source)
251 {
252 case BRAWCAP_TIMESTAMP_MODE_NO_TIMESTAMP: printf("No Timestamp\n"); break;
253 case BRAWCAP_TIMESTAMP_MODE_SYSTEM_LOWPREC: printf("Driver System Low Precision\n"); break;
254 case BRAWCAP_TIMESTAMP_MODE_SYSTEM_HIGHPREC: printf("Driver System High Precision\n"); break;
255 case BRAWCAP_TIMESTAMP_MODE_SOFTWARE: printf("Driver Software (QPC)\n"); break;
256 case BRAWCAP_TIMESTAMP_MODE_ADAPTER_SYSTEM: printf("Adapter System\n"); break;
257 case BRAWCAP_TIMESTAMP_MODE_ADAPTER_SOFTWARE: printf("Adapter Software (QPC)\n"); break;
258 case BRAWCAP_TIMESTAMP_MODE_ADAPTER_HARDWARE: printf("Adapter Hardware\n"); break;
259 }
260 printf(" - Resolution: ");
262 ? printf("%09u ns\n", resolution)
263 : printf(" UNKNOWN\n");
264 printf(" - Timestamp: %llu %09u ns (<=> %02u.%02u.%04u %02u:%02u:%02u.%09u)\n\n", sec, ns,
265 tmp->tm_mday, tmp->tm_mon+1, tmp->tm_year+1900,
266 tmp->tm_hour, tmp->tm_min, tmp->tm_sec, ns);
267 }
268 // Hm... we got a very silent connection...
269 // ... lets try again...
270 else if (status == BRAWCAP_STATUS_INFO_NO_DATA)
271 continue;
272 // Sad but we do not have a bRAWcap license for this feature... yet. :-(
273 // Notify our user about this sad information and
274 // wait some time to check if we are allowed to receive again...
275 else if (status == BRAWCAP_STATUS_WARNING_DEMO_MODE)
276 {
277 if (!demoModeLogged)
278 {
279 demoModeLogged = 1;
280 printf("[WARNING] DEMO MODE: Receiving not available.\n");
281 }
282 Sleep(1000);
283 }
284 // Ok... Something strange happened here... :-O
285 // Better stop now if we do not know how to handle it.
286 else
287 {
288 printf("[ERROR] Unexpected status while receiving packet: %d\n", brawcap_last_status());
289 retVal = -1;
290 break;
291 }
292 }
293 }while(0);
294
295 // We do not want to produce any memory leaks...
296 // ... so always cleanup what we have created
297 // --> The functions here can only fail if we did something wrong.
298 // But we are sure that we did everything right...
299 // therefore we do not check their status.
300 if (pPacket)
301 brawcap_packet_free(pPacket);
302 if (pHandle)
303 brawcap_close(pHandle);
304
305 return retVal;
306}
bRAWcap main header.
struct _brawcap_handle brawcap_handle_t
A bRAWcap handle.
Definition: brawcap_types_um.h:184
brawcap_status_t brawcap_close(brawcap_handle_t *pHandle)
Closes the specified bRAWcap handle.
brawcap_status_t brawcap_open(const brawcap_adapter_name_t name, brawcap_handle_t **const pHandle)
Opens a new bRAWcap handle on the adapter, specified by it´s name.
brawcap_status_t brawcap_last_status()
Reads the last status appeared in bRAWcap, for the calling thread.
brawcap_status_t
bRAWcap status/return codes.
Definition: brawcap_types_shared.h:140
#define BRAWCAP_SUCCESS(status)
Checks if the returned status indicates a success with no additional info.
Definition: brawcap_types_shared.h:112
@ BRAWCAP_STATUS_SUCCESS
Definition: brawcap_types_shared.h:142
@ BRAWCAP_STATUS_INFO_NO_DATA
Indicates that a function returns without any data.
Definition: brawcap_types_shared.h:329
@ BRAWCAP_STATUS_WARNING_DEMO_MODE
The operation was not executed due to demo mode limitations.
Definition: brawcap_types_shared.h:252
UINT32 brawcap_timestamp_capabilities_t
Type used for indicating the supported timestamp modes.
Definition: brawcap_types_shared.h:520
#define BRAWCAP_TIMESTAMP_NS_PER_MS
Number of nanoseconds per millisecond.
Definition: brawcap_types_shared.h:512
brawcap_status_t brawcap_timestamp_value_us_get(brawcap_timestamp_t *const pTimestamp, UINT64 *const pSeconds, UINT32 *const pMicroseconds)
Reads out the timestamp value in seconds and microseconds.
brawcap_status_t brawcap_timestamp_value_ms_get(brawcap_timestamp_t *const pTimestamp, UINT64 *const pSeconds, UINT32 *const pMilliseconds)
Reads out the timestamp value in seconds and milliseconds.
brawcap_status_t brawcap_timestamp_resolution_ns_get(brawcap_timestamp_t *const pTimestamp, brawcap_timestamp_resolution_ns_t *const pResolution_ns)
Reads out the timestamp resolution of the specified timestamp.
struct _brawcap_timestamp brawcap_timestamp_t
bRAWcap timestamp object.
Definition: brawcap_types_shared.h:608
brawcap_status_t brawcap_timestamp_value_ns_get(brawcap_timestamp_t *const pTimestamp, UINT64 *const pSeconds, UINT32 *const pNanoseconds)
Reads out the timestamp value in seconds and nanoseconds.
UINT32 brawcap_timestamp_resolution_ns_t
Represents the timestamp resolution in nanoseconds.
Definition: brawcap_types_shared.h:529
#define BRAWCAP_TIMESTAMP_RESOLUTION_UNKNOWN
If a timestamp resolution is set to this value, it´s resolution is unknown - could not be resolved.
Definition: brawcap_types_shared.h:487
brawcap_timestamp_mode_t
List of different timestamp modes.
Definition: brawcap_types_shared.h:570
brawcap_status_t brawcap_timestamp_mode_get(brawcap_timestamp_t *const pTimestamp, brawcap_timestamp_mode_t *const pMode)
Reads out the mode of the specified timestamp.
#define BRAWCAP_TIMESTAMP_NS_PER_US
Number of nanoseconds per microsecond.
Definition: brawcap_types_shared.h:507
@ BRAWCAP_TIMESTAMP_MODE_SYSTEM_HIGHPREC
A high precision system timestamp created by bRAWcap driver.
Definition: brawcap_types_shared.h:582
@ BRAWCAP_TIMESTAMP_MODE_ADAPTER_HARDWARE
A hardware timestamp created by the network adapter hardware/firmware.
Definition: brawcap_types_shared.h:598
@ BRAWCAP_TIMESTAMP_MODE_SOFTWARE
A software timestamp created by bRAWcap driver.
Definition: brawcap_types_shared.h:586
@ BRAWCAP_TIMESTAMP_MODE_ADAPTER_SYSTEM
A system timestamp created by the network adapter driver.
Definition: brawcap_types_shared.h:590
@ BRAWCAP_TIMESTAMP_MODE_ADAPTER_SOFTWARE
A software timestamp created by the network adapter driver.
Definition: brawcap_types_shared.h:594
@ BRAWCAP_TIMESTAMP_MODE_NO_TIMESTAMP
No timestamp.
Definition: brawcap_types_shared.h:574
@ BRAWCAP_TIMESTAMP_MODE_SYSTEM_LOWPREC
A low precision system timestamp created by bRAWcap driver.
Definition: brawcap_types_shared.h:578
brawcap_status_t brawcap_packet_create(brawcap_packet_t **const pPacket, const brawcap_packet_size_t maxSize)
Creates a new packet.
struct _brawcap_packet brawcap_packet_t
bRAWcap packet object.
Definition: brawcap_types_shared.h:675
#define BRAWCAP_PACKET_SIZE_MAX
The maximum supported (byte) size for a single packet payload.
Definition: brawcap_types_shared.h:645
brawcap_status_t brawcap_packet_timestamp_get(brawcap_packet_t *const pPacket, brawcap_timestamp_t **const pTimestamp)
Reads out the timestamp object for the specified packet.
brawcap_status_t brawcap_packet_free(brawcap_packet_t *pPacket)
Frees the specified packet. When this function is called the specified packet becomes invalid and it´...
brawcap_status_t brawcap_adapter_list_at(const brawcap_adapter_count_t index, brawcap_adapter_name_t name)
Reads out the adapter name of the adapter at the adapter list index.
brawcap_status_t brawcap_adapter_list_count(brawcap_adapter_count_t *const pCount)
Reads out the current number of supported adapters in the adapter list.
char brawcap_adapter_name_t[BRAWCAP_ADAPTER_NAME_LENGTH]
Fixed size array containing a adapter name.
Definition: brawcap_types_um.h:301
UINT8 brawcap_adapter_count_t
Type used for counting the available/supported adapters on a machine.
Definition: brawcap_types_um.h:286
brawcap_status_t brawcap_rx_packet(brawcap_handle_t *const pHandle, brawcap_packet_t *const pPacket)
Receives a single packet from the specified handle.
brawcap_status_t brawcap_rx_timestamp_capabilities(brawcap_handle_t *const pHandle, brawcap_timestamp_capabilities_t *const pCapabilities)
Reads out the available receive timestamp modes for the specified handle.
brawcap_status_t brawcap_rx_timestamp_mode_set(brawcap_handle_t *const pHandle, const brawcap_timestamp_mode_t mode)
Configures the used receive time stamping mode for the specified handle.