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