statUsage_example.c Source File

Reference Documentation

Platform
Napatech SmartNIC
Content Type
Reference Information
Capture Software Version
Link™ Capture Software 12.15
Napatech Software Suite: examples/statUsage/statUsage_example.c Source File
statUsage_example.c
Go to the documentation of this file.
1 /*
2  *
3  * Copyright 2025 Napatech A/S. All Rights Reserved.
4  *
5  * 1. Copying, modification, and distribution of this file, or executable
6  * versions of this file, is governed by the terms of the Napatech Software
7  * license agreement under which this file was made available. If you do not
8  * agree to the terms of the license do not install, copy, access or
9  * otherwise use this file.
10  *
11  * 2. Under the Napatech Software license agreement you are granted a
12  * limited, non-exclusive, non-assignable, copyright license to copy, modify
13  * and distribute this file in conjunction with Napatech SmartNIC's and
14  * similar hardware manufactured or supplied by Napatech A/S.
15  *
16  * 3. The full Napatech Software License Agreement is included in this
17  * distribution, please see "NA-0009 Software License Agreement.pdf"
18  *
19  * 4. Redistributions of source code must retain this copyright notice,
20  * list of conditions and the following disclaimer.
21  *
22  * THIS SOFTWARE IS PROVIDED "AS IS" WITHOUT ANY WARRANTIES, EXPRESS OR
23  * IMPLIED, AND NAPATECH DISCLAIMS ALL IMPLIED WARRANTIES INCLUDING ANY
24  * IMPLIED WARRANTY OF TITLE, MERCHANTABILITY, NONINFRINGEMENT, OR OF
25  * FITNESS FOR A PARTICULAR PURPOSE. TO THE EXTENT NOT PROHIBITED BY
26  * APPLICABLE LAW, IN NO EVENT SHALL NAPATECH BE LIABLE FOR PERSONAL INJURY,
27  * OR ANY INCIDENTAL, SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES WHATSOEVER,
28  * INCLUDING, WITHOUT LIMITATION, DAMAGES FOR LOSS OF PROFITS, CORRUPTION OR
29  * LOSS OF DATA, FAILURE TO TRANSMIT OR RECEIVE ANY DATA OR INFORMATION,
30  * BUSINESS INTERRUPTION OR ANY OTHER COMMERCIAL DAMAGES OR LOSSES, ARISING
31  * OUT OF OR RELATED TO YOUR USE OR INABILITY TO USE NAPATECH SOFTWARE OR
32  * SERVICES OR ANY THIRD PARTY SOFTWARE OR APPLICATIONS IN CONJUNCTION WITH
33  * THE NAPATECH SOFTWARE OR SERVICES, HOWEVER CAUSED, REGARDLESS OF THE THEORY
34  * OF LIABILITY (CONTRACT, TORT OR OTHERWISE) AND EVEN IF NAPATECH HAS BEEN
35  * ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. SOME JURISDICTIONS DO NOT ALLOW
36  * THE EXCLUSION OR LIMITATION OF LIABILITY FOR PERSONAL INJURY, OR OF
37  * INCIDENTAL OR CONSEQUENTIAL DAMAGES, SO THIS LIMITATION MAY NOT APPLY TO YOU.
38  *
39  *
40 
41  */
42 
43 /**
44  * @example statUsage/statUsage_example.c
45  * @section statUsage_example_description Description
46  *
47  * This source file is an example of how to use the @ref StatStream
48  * "statistics stream" interface in NTAPI to read hostbuffer usage
49  * statistics.
50  *
51  * The following NTAPI functions are used:
52  * - @ref NT_Init()
53  * - @ref NT_StatOpen()
54  * - @ref NT_StatRead()
55  * - @ref NT_StatClose()
56  * - @ref NT_Done()
57  * - @ref NT_ExplainError()
58  *
59  * <hr>
60  * @section statUsage_example_prerequisites Prerequisites
61  * A working system is needed.
62  *
63  * @section statUsage_example_flow Program flow
64  * @{
65  * The following is required to use the @ref StatStream
66  * "statistics stream" interface in NTAPI:
67  * - \#include/nt.h - Applications/Tools only need to include @ref
68  * nt.h to obtain prototypes, macros etc. from NTAPI.
69  * - @ref NT_Init(@ref NTAPI_VERSION) - Initialize the NTAPI
70  * library. @ref NTAPI_VERSION is a define that describes the version
71  * of the API described in the header files included by @ref
72  * nt.h. NT_Init() will ask the NTAPI library to convert return data
73  * to the @ref NTAPI_VERSION if possible. This will ensure that
74  * applications can run on NTAPI libraries of newer versions.
75  * - @ref NT_StatOpen() - Open an statistics stream.
76  * - @ref NT_StatRead() - Read usage statistics for the chosen stream ID.
77  * - @ref NT_StatClose() - Close the stream when terminating.
78  * - @ref NT_Done() - Close down the NTAPI library.
79  * - @ref NT_ExplainError() - Explain an error code returned by NTAPI functions.
80  *
81  *<hr>
82  * @}
83  */
84 
85 // Include this in order to access the Napatech API
86 #include <nt.h>
87 
88 #if defined(WIN32) || defined (WIN64)
89  #include <winsock2.h> // Sleep()
90 #else
91  #include <unistd.h> // sleep()
92  #include <signal.h>
93  #include <stdatomic.h>
94 #endif
95 
96 #include <stdlib.h>
97 #include <argparse.h>
98 
99 #define MAX_NUM_STREAM_IDS (1*256)
100 
101 #if defined(WIN32) || defined (WIN64)
102 static volatile int appRunning = 1; // The application will run as long as appRunning == 1
103 #else
104 static atomic_int appRunning = 1; // The application will run as long as appRunning == 1
105 #endif
106 
107 /**
108  * Print command line info
109  */
110 static const char *usageText[] = {
111  "Syntax:\n"
112  "statUsage_example [-h][-s <stream ID>]\n"
113  "\nCommands:\n",
114  NULL};
115 
116 static int opt_streamid = -1;
117 
118 /**
119  * Table of valid options.
120  */
122  OPT_HELP(),
123  OPT_INTEGER('s', "streamid", &opt_streamid, "Stream ID", NULL, 0, 0, "streamid"),
124  OPT_END(),
125 };
126 
127 /**
128  * The function called when user is pressing CTRL-C
129  */
130 #if defined(WIN32) || defined (WIN64)
131 static BOOL WINAPI StopApplication(int sig)
132 {
133  (void) sig;
134  appRunning = 0;
135  return TRUE;
136 }
137 #else
138 static void StopApplication(int sig)
139 {
140  if (sig == SIGINT)
141  appRunning = 0;
142 }
143 #endif
144 
145 int main(int argc, const char *argv[])
146 {
147  NtStatStream_t hStatStream; // Statistics stream handle
148  NtStatistics_t hStat; // Stat handle.
149  char errorBuffer[NT_ERRBUF_SIZE]; // Error buffer
150  int status; // Status variable
151  struct argparse argparse;
152 
153  printf("\nNapatech example: Display hostbuffer usage\n");
154  printf("--------------------------------------------------------------------------------\n\n");
155 
156  // Register ctrl+c handler so we are able to stop again
157 #if defined(WIN32) || defined (WIN64)
158  SetConsoleCtrlHandler((PHANDLER_ROUTINE)StopApplication, TRUE);
159 #else
160  struct sigaction newaction; // Ctrl+c signal handler container
161  memset(&newaction, 0, sizeof(newaction));
162  newaction.sa_handler = StopApplication;
163  if (sigaction(SIGINT, &newaction, NULL) < 0) {
164  fprintf(stderr, "Failed to register SIGINT sigaction.\n");
165  exit(EXIT_FAILURE);
166  }
167 #endif
168 
169  // Read the command line options
170  argparse_init(&argparse, arg_options, usageText, 0);
171  argparse_parse(&argparse, argc, argv);
172 
173  if (opt_streamid == -1) {
174  // If no streamid is specefied, then exit with an error
175  fprintf(stderr, "ERROR: Stream ID must be specified\n\n");
176  return 1;
177  }
178 
180  // If streamid is to large, then exit with an error
181  fprintf(stderr, "ERROR: Stream ID must be less or equal to %d\n\n", MAX_NUM_STREAM_IDS);
182  return 1;
183  }
184 
185  // Initialize the NTAPI library and thereby check if NTAPI_VERSION can be used together with this library
186  if ((status = NT_Init(NTAPI_VERSION)) != NT_SUCCESS) {
187  // Get the status code as text
188  NT_ExplainError(status, errorBuffer, sizeof(errorBuffer));
189  fprintf(stderr, "NT_Init() failed: %s\n", errorBuffer);
190  return -1;
191  }
192 
193  // Open the stat stream
194  if ((status = NT_StatOpen(&hStatStream, "ExampleStatUsage")) != NT_SUCCESS) {
195  // Get the status code as text
196  NT_ExplainError(status, errorBuffer, sizeof(errorBuffer));
197  fprintf(stderr, "NT_StatOpen() failed: %s\n", errorBuffer);
198  return -1;
199  }
200 
201  // Read usage data
202  while (appRunning == 1) {
203  uint32_t hbCount;
204 
205  // Read usage data for the chosen stream ID
207  hStat.u.usageData_v0.streamid = (uint8_t)opt_streamid; // HB256: TODO:
208  if ((status = NT_StatRead(hStatStream, &hStat)) != NT_SUCCESS) {
209  // Get the status code as text
210  NT_ExplainError(status, errorBuffer, sizeof(errorBuffer));
211  fprintf(stderr, "NT_StatRead() failed: %s\n", errorBuffer);
212  return -1;
213  }
214 
215  // Print the usage data for each hostbuffer used by the chosen stream ID
216  printf("Number of hostbuffers used by stream ID %u: %u\n", opt_streamid, hStat.u.usageData_v0.data.numHostBufferUsed);
217  printf("================================================================================\n");
218  for (hbCount = 0; hbCount < hStat.u.usageData_v0.data.numHostBufferUsed; hbCount++) {
219  // The hostbuffer is used by this adapter
220  printf("Adapter number: %u\n", hStat.u.usageData_v0.data.hb[hbCount].adapterNo);
221 
222  // The percentage of the onbord sdram buffer allocated for this hostbuffer that is used
223  printf("SDRAM fill level: %3u %%\n",
224  (unsigned)(100U * hStat.u.usageData_v0.data.hb[hbCount].onboardBuffering.used / hStat.u.usageData_v0.data.hb[hbCount].onboardBuffering.size));
225 
226  // The size of the onbord sdram buffer allocated for this hostbuffer
227  printf("Onbord buffer size: %6llu MByte\n", (long long unsigned int)(hStat.u.usageData_v0.data.hb[hbCount].onboardBuffering.size)/1024/1024);
228 
229  // The size of the hostbuffer
230  printf("Hostbuffer size: %6llu MByte\n", (long long unsigned int)(hStat.u.usageData_v0.data.hb[hbCount].hostBufferSize)/1024/1024);
231 
232  // The numanode that the hostbuffer is allocated from.
233  printf("Numa node: %2u\n", hStat.u.usageData_v0.data.hb[hbCount].numaNode);
234 
235  // Number of streams (apps) that are using the hostbuffer
236  printf("Number of connected streams: %3u\n", hStat.u.usageData_v0.data.hb[hbCount].numStreams);
237 
238  // The hostbuffer status
239  // deQueued: Number of bytes available or in use by the streams
240  // enQueued: Number of bytes available to the host buffer handler
241  // enQueuedAdapter: Number of bytes currently in the adapter
242  printf("\nDequeued: %6llu, Enqueued driver: %6llu, Enqueued adapter: %6llu\n", (long long unsigned int)hStat.u.usageData_v0.data.hb[hbCount].deQueued/1024,
243  (long long unsigned int)(hStat.u.usageData_v0.data.hb[hbCount].enQueued-
244  hStat.u.usageData_v0.data.hb[hbCount].enQueuedAdapter)/1024,
245  (long long unsigned int)hStat.u.usageData_v0.data.hb[hbCount].enQueuedAdapter/1024);
246 
247  // Number of received and dropped packet for this hostbuffer
248  printf("Received packets: %8llu, Dropped packets: %8llu\n", (long long unsigned int)hStat.u.usageData_v0.data.hb[hbCount].stat.rx.frames,
249  (long long unsigned int)hStat.u.usageData_v0.data.hb[hbCount].stat.drop.frames);
250 
251  printf("--------------------------------------------------------------------------------\n\n");
252  }
253 
254 #if defined(WIN32) || defined (WIN64)
255  Sleep(1000); // sleep 1000 milliseconds = 1 second
256 #else
257  sleep(1); // sleep 1 sec
258 #endif
259  }
260 
261  // Close the stat stream
262  if ((status = NT_StatClose(hStatStream)) != NT_SUCCESS) {
263  // Get the status code as text
264  NT_ExplainError(status, errorBuffer, sizeof(errorBuffer));
265  fprintf(stderr, "NT_StatClose() failed: %s\n", errorBuffer);
266  return -1;
267  }
268 
269  // Close down the NTAPI library
270  NT_Done();
271 
272  printf("Done.\n");
273  return 0;
274 }