bypass_config_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/bypass/config/bypass_config_example.c Source File
bypass_config_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  * @example bypass/config/bypass_config_example.c
44  * @section Description Description
45  *
46  * This source file is an example of how to use the @ref ConfigStream
47  * "Configuration stream" interface in NTAPI for Napatech bypass accelerator and port configuration.
48  *
49  * This example switches the state of the relays every time it is run.
50  *
51  * The following NTAPI functions are used:
52  * - @ref NT_Init()
53  * - @ref NT_InfoOpen()
54  * - @ref NT_InfoRead()
55  * - @ref NT_InfoClose()
56  * - @ref NT_ConfigOpen()
57  * - @ref NT_ConfigWrite()
58  * - @ref NT_ConfigRead()
59  * - @ref NT_ConfigClose()
60  * - @ref NT_Done()
61  * - @ref NT_ExplainError()
62  *
63  * <hr>
64  * @section Prerequisites_l Prerequisites
65  * A working system is needed with a Napatech bypass accelerator.
66  *
67  * @section Flow Program flow
68  * @{
69  * The following is required to perform read and write operations on
70  * the @ref ConfigStream "configuration stream":
71  *
72  * - \#include/nt.h - Applications/Tools only need to include @ref
73  * nt.h to obtain prototypes, macros etc. from NTAPI.
74  * - @ref NT_Init(@ref NTAPI_VERSION) - Initialize the NTAPI
75  * library. @ref NTAPI_VERSION is a define that describes the version
76  * of the API described in the header files included by @ref
77  * nt.h. NT_Init() will ask the NTAPI library to convert return data
78  * to the @ref NTAPI_VERSION if possible. This will ensure that
79  * applications can run on NTAPI libraries of newer versions.
80  *
81  * - @ref NT_InfoOpen() - Open an info stream.
82  * - @ref NT_InfoRead() - Read info stream.
83  * - @ref NT_InfoClose() - Close the stream when terminating.
84  * - @ref NT_ConfigOpen() - Open a configuration stream.
85  * - @ref NT_ConfigRead() - Read configuration.
86  * - @ref NT_ConfigWrite() - Write configuration.
87  * - @ref NT_ConfigClose() - Close the stream when terminating.
88  * - @ref NT_Done() - Close down the NTAPI library.
89  * - @ref NT_ExplainError() - Explain an error code returned by NTAPI functions.
90  *
91  *<hr>
92  * @}
93  */
94 
95 
96 // Include this in order to access the Napatech API
97 #include <nt.h>
98 
99 #if defined(__linux__) || defined(__FreeBSD__)
100  #include <unistd.h>
101 #endif
102 
103 #include <stdlib.h>
104 #include <stdio.h>
105 #include <errno.h>
106 
107 
108 //
109 // main()
110 //
111 int main(void)
112 {
113  NtError_t status;
114  char errBuf[NT_ERRBUF_SIZE];
115  //
116  NtInfoStream_t hInfo;
117  NtInfo_t infoSystem;
118  NtInfo_t infoAdapter;
119  NtInfo_t infoPort;
120  //
121  NtConfigStream_t hConfig;
122  NtConfig_t configPort;
123  //
124  uint8_t adapter;
125  uint8_t port;
126  //
127  const char* aBpState[] = {"NA", "Normal", "Bypass"};
128  const char* aBpFlags[] = {"Off", "On"};
129 
130  //
131  //
132  //
133 
134  // Initialize NTAPI library
135  if ((status = NT_Init(NTAPI_VERSION)) != NT_SUCCESS) {
136  NT_ExplainError(status, errBuf, sizeof(errBuf));
137  fprintf(stderr, "ERROR: NT_Init failed. Code 0x%x = %s\n", status, errBuf);
138  return status;
139  }
140 
141  // Open the information stream
142  if ((status = NT_InfoOpen(&hInfo, "bypass_config_example")) != NT_SUCCESS) {
143  NT_ExplainError(status, errBuf, sizeof(errBuf));
144  fprintf(stderr, ">>> Error: NT_InfoOpen failed. Code 0x%x = %s\n", status, errBuf);
145  return status;
146  }
147 
148  // Read system information
149  infoSystem.cmd = NT_INFO_CMD_READ_SYSTEM;
150  if ((status = NT_InfoRead(hInfo, &infoSystem)) != NT_SUCCESS) {
151  NT_ExplainError(status, errBuf, sizeof(errBuf));
152  fprintf(stderr, "ERROR: NT_InfoRead failed. Code 0x%x = %s\n", status, errBuf);
153  return status;
154  }
155 
156  printf("System: %d.%d.%d.%d\n\n", infoSystem.u.system.data.version.major,
157  infoSystem.u.system.data.version.minor,
158  infoSystem.u.system.data.version.patch,
159  infoSystem.u.system.data.version.tag);
160  printf("Adapters: %u\n", infoSystem.u.system.data.numAdapters);
161  printf("Ports: %u\n", infoSystem.u.system.data.numPorts);
162  printf("\n");
163 
164  // Open the config stream
165  status = NT_ConfigOpen(&hConfig, "bypass_config_example");
166  if (status != NT_SUCCESS) {
167  NT_ExplainError(status, errBuf, sizeof(errBuf));
168  fprintf(stderr, ">>> Error: NT_ConfigOpen failed. Code 0x%x = %s\n", status, errBuf);
169  return status;
170  }
171 
172  for (adapter = 0; adapter < infoSystem.u.system.data.numAdapters; adapter++) {
173  infoAdapter.cmd = NT_INFO_CMD_READ_ADAPTER_V7;
174  infoAdapter.u.adapter_v7.adapterNo = adapter;
175  if ((status = NT_InfoRead(hInfo, &infoAdapter)) != 0) {
176  NT_ExplainError(status, errBuf, sizeof(errBuf));
177  fprintf(stderr, "ERROR: NT_InfoRead failed. Code 0x%x = %s\n", status, errBuf);
178  return status;
179  }
180  printf("Adapter %u (%u ports):\n", infoAdapter.u.adapter_v7.adapterNo, infoAdapter.u.adapter_v7.data.numPorts);
181 
182  configPort.parm = NT_CONFIG_PARM_BYPASS_ADAPTER;
183  configPort.u.bypassConfig.u.adapterNo = adapter;
184  status = NT_ConfigRead(hConfig, &configPort);
185  if (status != 0) {
186  NT_ExplainError(status, errBuf, sizeof(errBuf));
187  fprintf(stderr, "ERROR: NT_ConfigRead failed. Code 0x%x = %s\n", status, errBuf);
188  continue; // skip this and continue to next adapter
189  }
190  else {
191  //
192  // Invert bypass adapter state - based on the current bypass adapter state
193  // Skip this step if the already read bypass adapter state is unknown - this means that the ports can be individually configured.
194  //
201  } else {
206  }
207  }
208  //
209  // Then write the changed configuration back...
210  //
211  configPort.parm = NT_CONFIG_PARM_BYPASS_ADAPTER;
212  configPort.u.bypassConfig.u.adapterNo = adapter;
213  if ((status = NT_ConfigWrite(hConfig, &configPort)) != 0) {
214  NT_ExplainError(status, errBuf, sizeof(errBuf));
215  fprintf(stderr, "ERROR: NT_ConfigWrite failed. Code 0x%x = %s\n", status, errBuf);
216  return status;
217  }
218 
219  //
220  // Display bypass configuration for the adapter
221  //
222  configPort.parm = NT_CONFIG_PARM_BYPASS_ADAPTER;
223  configPort.u.bypassConfig.u.adapterNo = adapter;
224  if ((status = NT_ConfigRead(hConfig, &configPort)) != 0) {
225  NT_ExplainError(status, errBuf, sizeof(errBuf));
226  fprintf(stderr, "ERROR: NT_ConfigRead failed. Code 0x%x = %s\n", status, errBuf);
227  return status;
228  }
229 
230  printf(" bypass adapter current state: %s\n", aBpState[configPort.u.bypassConfig.data.currentBypassPortState]);
231  printf(" bypass adapter onInit state: %s\n", aBpState[configPort.u.bypassConfig.data.onInitBypassPortState]);
232  printf(" bypass adapter onPwrFail state: %s\n", aBpState[configPort.u.bypassConfig.data.onPowerFailBypassPortState]);
233  printf(" bypass adapter onWdtFail state: %s\n", aBpState[configPort.u.bypassConfig.data.onWatchdogFailBypassPortState]);
234  printf(" bypass adapter onPwrFail detect trigger: %s\n", aBpFlags[((configPort.u.bypassConfig.data.bypassTriggerModes & NT_BYPASS_TRIGGER_PWRFAIL)==0?0:1)]);
235  }
236  printf("\n");
237 
238  for (port = 0; port < infoAdapter.u.adapter_v7.data.numPorts; port++) {
239  infoPort.cmd = NT_INFO_CMD_READ_PORT_V10;
240  infoPort.u.port_v10.portNo = (uint8_t)(infoAdapter.u.adapter_v7.data.portOffset + port);
241  if ((status = NT_InfoRead(hInfo, &infoPort)) != 0) {
242  NT_ExplainError(status, errBuf, sizeof(errBuf));
243  fprintf(stderr, "ERROR: NT_InfoRead failed. Code 0x%x = %s\n", status, errBuf);
244  return status;
245  }
246 
247  printf(" Port %i (adapter #%i port #%i):\n", infoPort.u.port_v10.portNo, infoPort.u.port_v10.data.adapterNo, port);
248 
250  //
251  // There is no need to configure both ports in a bypass portset pair.
252  // You only need configure one of the ports in a bypass portset pair.
253  // The other port automatically will mirror the bypass configuration of the first port.
254  //
255  if ((port & 0x01) == 0) {
256  //
257  // Read current configuration
258  //
259  configPort.parm = NT_CONFIG_PARM_BYPASS_PORT;
260  configPort.u.bypassConfig.u.portNo = (uint8_t)(infoAdapter.u.adapter_v7.data.portOffset + port);
261  if ((status = NT_ConfigRead(hConfig, &configPort)) != 0) {
262  NT_ExplainError(status, errBuf, sizeof(errBuf));
263  fprintf(stderr, "ERROR: NT_ConfigRead failed. Code 0x%x = %s\n", status, errBuf);
264  return status;
265  }
266 
267  //
268  // Invert bypass portset state - based on the current bypass portset state
269  //
275  } else {
280  }
281  //
282  // Then write the changed configuration back...
283  //
284  configPort.parm = NT_CONFIG_PARM_BYPASS_PORT;
285  configPort.u.bypassConfig.u.portNo = (uint8_t)(infoAdapter.u.adapter_v7.data.portOffset + port);
286  if ((status = NT_ConfigWrite(hConfig, &configPort)) != 0) {
287  NT_ExplainError(status, errBuf, sizeof(errBuf));
288  fprintf(stderr, "ERROR: NT_ConfigWrite failed. Code 0x%x = %s\n", status, errBuf);
289  return status;
290  }
291  }
292 
293 
294  //
295  // Display result of configuration for all ports in a bypass portset
296  // The second port in a bypass portset should have mirrored the settings applied to the first port.
297  //
298  configPort.parm = NT_CONFIG_PARM_BYPASS_PORT;
299  configPort.u.bypassConfig.u.portNo = (uint8_t)(infoAdapter.u.adapter_v7.data.portOffset + port);
300  if ((status = NT_ConfigRead(hConfig, &configPort)) != 0) {
301  NT_ExplainError(status, errBuf, sizeof(errBuf));
302  fprintf(stderr, "ERROR: NT_ConfigRead failed. Code 0x%x = %s\n", status, errBuf);
303  return status;
304  }
305 
306  printf(" bypass port current state: %s\n", aBpState[configPort.u.bypassConfig.data.currentBypassPortState]);
307  printf(" bypass port onInit state: %s\n", aBpState[configPort.u.bypassConfig.data.onInitBypassPortState]);
308  printf(" bypass port onPwrFail state: %s\n", aBpState[configPort.u.bypassConfig.data.onPowerFailBypassPortState]);
309  printf(" bypass port onWdtFail state: %s\n", aBpState[configPort.u.bypassConfig.data.onWatchdogFailBypassPortState]);
310  printf(" bypass port onPwrFail detect trigger: %s\n", aBpFlags[((configPort.u.bypassConfig.data.bypassTriggerModes & NT_BYPASS_TRIGGER_PWRFAIL)==0?0:1)]);
311 
312  configPort.parm = NT_CONFIG_PARM_BYPASS_PORT;
313  configPort.u.bypassConfig.u.portNo = (uint8_t)(infoAdapter.u.adapter_v7.data.portOffset + port);
314  if ((status = NT_ConfigWrite(hConfig, &configPort)) != 0) {
315  NT_ExplainError(status, errBuf, sizeof(errBuf));
316  fprintf(stderr, "ERROR: NT_ConfigWrite failed. Code 0x%x = %s\n", status, errBuf);
317  return status;
318  }
319 
320  }
321  printf("\n");
322  }
323  printf("\n");
324  }
325  printf("\n");
326 
327  // Close down the NTAPI library
328  NT_Done();
329 
330  return 0;
331 }
332 
333 //
334 // EOF
335 //