Integrator Resources

The official home for NAI Support

Not sure where to start? Try Quick Start Guide or ask a question below!

Toggle Components with Visual Button
JavaScript Form Processing

EtherTDRCommands

EtherTDRCommands Sample Application (SSK 1.x)

Overview

The EtherTDRCommands sample application demonstrates how to use Ethernet Time Driven Response (TDR) commands on NAI boards using the NAI Software Support Kit (SSK 1.x). TDR allows you to configure a set of Ethernet commands on the board that the board executes automatically at a periodic interval, sending the results to a designated IP address and port via TCP or UDP. This eliminates the need for the host to repeatedly poll the board — the board autonomously reads (and optionally writes) registers and pushes the response data to your application at a regular cadence.

TDR is well suited for continuous monitoring scenarios where you need periodic snapshots of board or module state — for example, reading status registers every 5 seconds and forwarding the results to a monitoring application. The board handles the timing and execution; your application simply listens for incoming data.

This is a board-level sample — it is not specific to any module type. It works with any NAI board that supports Generation 4 (or later) Ethernet commands.

Prerequisites

Before running this sample, make sure you have:

  • An NAI board connected via Ethernet that supports Gen4 Ethernet commands.

  • SSK 1.x installed on your development host.

  • The sample applications built. Refer to the SSK 1.x build instructions for your platform if you have not already compiled them.

  • Network configuration that allows TCP or UDP traffic from the board to the host on the configured response port (default: 52801).

How to Run

Launch the EtherTDRCommands executable from your build output directory. On startup the application looks for a configuration file (default_Ether_TDR.txt). On the first run, this file will not exist — the application will present an interactive board menu where you configure a board connection and card index. You can save this configuration so that subsequent runs skip the menu and connect automatically. Once connected, configure a TDR with the "Set" command, start it with "Run," and observe the periodic responses arriving at your listener.

Board Connection

Note
This startup sequence is common to all NAI sample applications. The board connection code shown here is not specific to any module type. For details on board connection configuration, see the First Time Setup Guide.

The main() function follows the standard SSK 1.x startup flow. No module selection is needed because TDR commands operate at the board level.

  1. Call naiapp_RunBoardMenu() to load a saved configuration file (if one exists) or present the interactive board menu. The configuration file (default_Ether_TDR.txt) is not included with the SSK — it is created when you save your connection settings from the board menu. On the first run, the menu will always appear.

  2. Query the user for a card index with naiapp_query_CardIndex().

  3. Check Gen4 support with SupportsGen4Ether() and enter the command loop.

#if defined (__VXWORKS__)
int32_t EtherTDRCommands(void)
#else
int32_t main(void)
#endif
{
   bool_t stop = FALSE;
   int32_t cardIndex;
   int8_t inputBuffer[80];
   int32_t inputResponseCnt;

   if (naiapp_RunBoardMenu(CONFIG_FILE) == TRUE)
   {
      while (stop != TRUE)
      {
         stop = naiapp_query_CardIndex(naiapp_GetBoardCnt(), 0, &cardIndex);
         if (stop != TRUE)
         {
            Run_EtherTDRCommands(cardIndex);
         }
         printf("\nType Q to quit or Enter key to restart application:\n");
         stop = naiapp_query_ForQuitResponse(sizeof(inputBuffer), NAI_QUIT_CHAR, inputBuffer, &inputResponseCnt);
      }
   }

   printf("\nType the Enter key to exit the program: ");
   naiapp_query_ForQuitResponse(sizeof(inputBuffer), NAI_QUIT_CHAR, inputBuffer, &inputResponseCnt);
   naiapp_access_CloseAllOpenCards();

   return 0;
}
Important

Common connection errors you may encounter at this stage:

  • No board found — verify that the board is powered on and connected via Ethernet. Check that the configuration file lists the correct interface and IP address.

  • Connection timeout — confirm IP address and network configuration. Firewalls and IP mismatches are frequent causes.

  • Invalid card index — indices are zero-based for cards. Ensure the value you pass matches your hardware setup.

  • Gen4 not supported — the connected board does not support Generation 4 Ethernet commands. TDR commands require Gen4 or later.

Program Structure

Entry Point

On standard platforms the entry point is main(). On VxWorks the entry point is EtherTDRCommands() — the SSK 1.x build system selects the correct variant via a preprocessor guard:

#if defined (__VXWORKS__)
int32_t EtherTDRCommands(void)
#else
int32_t main(void)
#endif

The startup flow is the same in both cases:

  1. Attempt to load the saved configuration file via naiapp_RunBoardMenu(CONFIG_FILE). If the file does not yet exist, the interactive board menu is presented instead.

  2. Enter a loop that queries for card index.

  3. Call Run_EtherTDRCommands() to enter the interactive command loop.

  4. On exit, close all open board connections with naiapp_access_CloseAllOpenCards().

Application Parameters

The Run_EtherTDRCommands() function populates an naiapp_AppParameters_t struct that is passed to every command handler. For TDR commands, only the card index is needed:

naiapp_AppParameters_t  tdr_params;
p_naiapp_AppParameters_t tdrcommands_params = &tdr_params;
tdrcommands_params->cardIndex = cardIndex;

bGen4TDRCommands = SupportsGen4Ether(cardIndex);

Command Loop

Run_EtherTDRCommands() drives the interactive command loop. On each iteration it displays the command menu and dispatches the user’s selection to the matching handler function:

Command Description

Set

Configure a TDR (assign commands, response destination, and period)

Get

Retrieve the current TDR configuration

Clear

Remove a TDR configuration

Run

Start a TDR (begin periodic execution and launch the response listener)

Halt

Stop a running TDR and terminate the listener thread

The menu-driven structure is a convenience of the sample application. In your own application, you would call the same underlying naibrd_Ether_*TDR*() API functions directly.

TDR Configuration

This section covers configuring, retrieving, and clearing TDR definitions. A TDR associates a set of Ethernet commands with a response destination and a periodic execution interval.

Set TDR Configuration

To configure a TDR in your own application, you need to specify three things: the Ethernet commands to execute on each cycle, the destination for the response data (IP address, port, and protocol), and the execution period. Call naibrd_Ether_SetTDRConfig() with all of these parameters.

The sample first prompts for the response IP address and port, then prompts for the TDR ID:

uint8_t commands[MAX_ETHER_TDR_CMD_CNT * MAX_ETHER_BLOCK_REG_CNT];
uint16_t cmdcount = 0;
uint16_t cmdlength = 0;
uint16_t protocol = DEF_RESPONSE_PROTOCOL;   /* UDP */
uint16_t iplen = DEF_RESPONSE_IP_LEN;        /* 4 for IPv4 */
uint16_t period = DEF_ETHER_TDR_PERIOD;      /* 5000 ms */
uint8_t ip[DEF_RESPONSE_IP_LEN];
uint16_t port;

/* Build the command sequence */
InitTDRCommands(commands, &cmdcount, &cmdlength);

/* Copy response IP and port from defaults (or user input) */
for (i = 0; i < DEF_RESPONSE_IP_LEN; i++)
   ip[i] = DEF_TDR_RESPONSE_IP_ADDR[i];
port = DEF_TDR_RESPONSE_PORT;

/* Configure the TDR */
nai_status_t status = naibrd_Ether_SetTDRConfig(cardIndex, (uint16_t)tdrid,
   protocol, iplen, ip, port, period, cmdcount, cmdlength, commands);
  • tdrid — a numeric ID that identifies this TDR configuration.

  • protocol — ETHER_GEN4_TCP_PROTOCOL (0) or ETHER_GEN4_UDP_PROTOCOL (1). The sample defaults to UDP.

  • iplen — the length of the IP address: 4 for IPv4, 6 for IPv6.

  • ip[] — the IP address bytes of the host that will receive the TDR responses. The sample defaults to 192.168.1.100.

  • port — the TCP or UDP port on the host. The sample defaults to 52801.

  • period — the execution interval in milliseconds. The sample defaults to 5000 ms (5 seconds).

  • cmdcount / cmdlength / commands[] — the number of commands, their total byte length, and the serialized command data.

The sample’s InitTDRCommands() function builds four demonstration commands: a ReadRegs, a WriteRegs, a ReadBlock, and a WriteBlock. Each command is constructed using the low-level Ethernet message API functions:

/* ReadRegs command: read 4 registers starting at 0x0190, stride 4, onboard, 32-bit */
msgIndex = (uint16_t)nai_ether_MakeReadMessage(&commands[startIndex],
   seqno, NAI_ETHER_GEN4, NAI_INTF_ONBOARD, regaddr, stride, count, NAI_REG32);

/* WriteRegs command: write 4 registers with test data */
msgIndex = (uint16_t)nai_ether_BeginWriteMessage(&commands[startIndex],
   seqno, NAI_ETHER_GEN4, NAI_INTF_ONBOARD, regaddr, stride, count, NAI_REG32);
msgIndex = (uint16_t)nai_ether_WriteMessageData(&commands[startIndex],
   msgIndex, NAI_REG32, data, NAI_REG32, count);
msgIndex = (uint16_t)nai_ether_FinishMessage(&commands[startIndex],
   msgIndex, NAI_ETHER_GEN4);

/* ReadBlock command: read block ID 1 */
msgIndex = (uint16_t)nai_ether_MakeReadBlockMessage(&commands[startIndex],
   seqno, NAI_ETHER_GEN4, blockid);

/* WriteBlock command: write data to block ID 1 */
msgIndex = (uint16_t)nai_ether_MakeWriteBlockMessage(&commands[startIndex],
   seqno, NAI_ETHER_GEN4, blockid, NAI_REG32, blkregcount, data);

In your own application, include only the commands relevant to your monitoring needs. You do not need all four command types — a TDR that only reads registers is a common and valid configuration.

Note
If your TDR includes ReadBlock or WriteBlock commands, the referenced block must be configured first using naibrd_Ether_SetBlock() (see the EtherBlockCommands sample). The TDR references blocks by ID — if the block is not configured, those commands will fail during execution.

Get TDR Configuration

To retrieve the current configuration of a TDR, call naibrd_Ether_GetTDRConfig(). This returns all parameters: protocol, IP address, port, period, and the stored command sequence.

uint16_t protocol, iplen, port, period;
uint8_t ip[MAX_ETHER_IP_LEN];
uint32_t arraysize = MAX_ETHER_TDR_CMD_CNT * MAX_ETHER_BLOCK_REG_CNT;
uint8_t commands[MAX_ETHER_TDR_CMD_CNT * MAX_ETHER_BLOCK_REG_CNT];
uint16_t cmdcount;

nai_status_t status = naibrd_Ether_GetTDRConfig(cardIndex, (uint16_t)tdrid,
   &protocol, &iplen, ip, &port, &period, &cmdcount, arraysize, commands);

The sample then parses each command using ParseTDRCommand() and displays a decoded view using DisplayDecodedEthCommand(). These functions locate individual commands within the byte stream by searching for Gen4 preamble and postamble markers, then decode the command type (ReadRegs, WriteRegs, ReadBlock, WriteBlock), flags (onboard/offboard, register size), register address, count, stride, and any write data.

Clear TDR Configuration

To remove a TDR configuration from the board and free the TDR ID for reuse, call naibrd_Ether_ClearTDRConfig():

nai_status_t status = naibrd_Ether_ClearTDRConfig(cardIndex, (uint16_t)tdrid);
Important

Common Errors

  • TDR ID not configured — Attempting to get, run, or halt a TDR that has not been configured returns an error. Always call naibrd_Ether_SetTDRConfig() first.

  • Block commands in TDR fail — If the TDR includes ReadBlock or WriteBlock commands, the referenced block must be configured first using naibrd_Ether_SetBlock().

  • Invalid response IP or port — If the response destination is unreachable, the board will still execute the commands but the response data will be lost. Verify network connectivity.

TDR Execution

Once a TDR is configured, you start and stop it using the Run and Halt commands. While running, the board executes the stored commands at the configured interval and sends the results to the response destination.

Start TDR

To start a TDR in your own application, call naibrd_Ether_StartTDR():

nai_status_t status = naibrd_Ether_StartTDR(cardIndex, (uint16_t)tdrid);

After calling this, the board begins executing the configured commands at the specified period and sending results to the response IP address and port.

The sample then spawns a listener thread (UPR_Handler) that creates either a TCP server or UDP server (depending on DEF_RESPONSE_PROTOCOL) to receive the periodic response messages. In your own application, you will need a similar listener to receive and process TDR data:

/* Windows */
CreateThread(NULL, 0, UPR_Handler, NULL, 0, NULL);

/* VxWorks */
taskSpawn("uprHandler", 100, 0, 10000, (FUNCPTR)UPR_Handler,
   NULL, 0, 0, 0, 0, 0, 0, 0, 0, 0);

/* Linux */
pthread_create(&interruptThread, NULL, (void*)UPR_Handler, NULL);

The listener thread creates a socket bound to the response port, accepts incoming connections (TCP) or receives datagrams (UDP), and calls DecodeUPRTDRMessages() to parse each response. The response messages contain the results of each command in the TDR — for read commands, this includes the register values; for write commands, the response confirms success.

Stop TDR

To stop a running TDR, call naibrd_Ether_StopTDR():

nai_status_t status = naibrd_Ether_StopTDR(cardIndex, (uint16_t)tdrid);

The sample also sets a flag (terminateThread = TRUE) to signal the listener thread to exit gracefully.

Important

Common Errors

  • No responses received after starting TDR — The response IP address or port is incorrect, or a firewall is blocking traffic on the configured port. Verify that the response IP matches the host running the listener, and check firewall rules for the response port (default: 52801).

  • TDR period too fast — If the period is shorter than the time required to execute all commands in the TDR, responses may overlap or be dropped. Increase the period value.

  • Listener socket bind failure — The response port is already in use by another application, or the previous instance of the listener did not shut down cleanly. Close any conflicting applications or use a different port.

  • TCP listener does not receive data — TCP requires the board to connect to the listener. Ensure the listener is started and listening before starting the TDR. The sample starts the listener thread after calling naibrd_Ether_StartTDR(), so there may be a brief window where early responses are missed.

TDR Response Handling

The sample implements two response receivers: a TCP server (CreateTDRTCPServer()) and a UDP server (CreateTDRUDPServer()). The protocol used is determined by the DEF_RESPONSE_PROTOCOL constant (default: UDP).

Both servers follow the same pattern:

  1. Create a socket and bind it to the configured response port.

  2. Listen for incoming data (TCP: accept a connection then recv; UDP: recvfrom).

  3. Pass received data to DecodeUPRTDRMessages() for parsing.

  4. Continue receiving until the terminateThread flag is set.

The DecodeUPRTDRMessages() function parses the response stream, which contains individual Ethernet command responses framed with Gen4 preamble and postamble markers. Each response includes a typecode indicating the original command type and the response data (register values for reads, confirmation for writes).

In your own application, you can use whatever socket infrastructure fits your architecture. The key requirement is that you listen on the IP address and port that you specified in the TDR configuration, using the same protocol (TCP or UDP).

Troubleshooting Reference

This table summarizes common errors and symptoms covered in the sections above. For detailed context on each entry, refer to the relevant section.

Error / Symptom Possible Causes Suggested Resolution

No board found or connection timeout

Board not powered, incorrect or missing configuration file, network issue

Verify hardware is powered and connected via Ethernet. If default_Ether_TDR.txt exists, check that it lists the correct interface and IP address.

Gen4 not supported

Board uses pre-Generation 4 Ethernet protocol

TDR commands require Gen4 or later. Verify your board’s firmware version.

No TDR responses received

Response IP/port incorrect, firewall blocking traffic, listener not running

Verify that the response IP matches the host running the listener. Check firewall rules for the response port. Ensure the listener is started.

Block commands in TDR fail

Referenced block ID not configured

Configure blocks using naibrd_Ether_SetBlock() before setting the TDR.

TDR period too fast, responses overlapping

Period shorter than combined command execution time

Increase the period value in naibrd_Ether_SetTDRConfig().

Listener socket bind fails

Port already in use or previous listener did not shut down cleanly

Close conflicting applications or use a different response port.

"Ethernet TDR Command Support Prior to Generation 4 Ethernet commands currently not supported"

Board does not support Gen4 Ethernet

Use a board with Gen4+ Ethernet support.

TCP listener misses early responses

Listener thread started after TDR begins executing

Start the listener before calling naibrd_Ether_StartTDR(), or use UDP which does not require a pre-established connection.

Full Source

The complete source for this sample is provided below for reference. The sections above explain each part in detail.

Full Source — EtherTDRCommands.c (SSK 1.x)
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <ctype.h>

/* Common Sample Program include files */
#include "include/naiapp_boardaccess_menu.h"
#include "include/naiapp_boardaccess_query.h"
#include "include/naiapp_boardaccess_access.h"
#include "include/naiapp_boardaccess_display.h"
#include "include/naiapp_boardaccess_utils.h"

/* naibrd include files */
#include "nai.h"
#include "naibrd.h"
#include "naibrd_ether.h"
#include "advanced/nai_ether_adv.h"

#if defined (WIN32)
#include <winsock2.h>
#include <ws2tcpip.h>
#pragma comment (lib, "Ws2_32.lib")
#pragma warning (disable:4127)
#elif (LINUX)
#include <sys/errno.h>
#include <pthread.h>
typedef int32_t SOCKET;
#define ZeroMemory(S, N)         memset((S), 0, (N))
#define closesocket(SD)          close(SD)
#define INVALID_SOCKET -1
#define SOCKET_ERROR   -1
#define SD_RECEIVE        0
#define SD_SEND           1
#define SD_BOTH           2
#elif (__VXWORKS__)
#include <netinet/ip.h>
#define ZeroMemory(S, N)         memset((S), 0, (N))
#define closesocket(SD)          close(SD)
#define INVALID_SOCKET -1
#define SOCKET_ERROR   -1
#define SD_RECEIVE        0
#define SD_SEND           1
#define SD_BOTH           2
#endif

static const int8_t *CONFIG_FILE = (int8_t *)"default_Ether_TDR.txt";

/* Function prototypes */
static bool_t Run_EtherTDRCommands(int32_t cardIndex);
static bool_t QueryEthTDRIPAddr(void);
static bool_t QueryEthTDRid(int32_t *tdrid);
static void InitTDRCommands(uint8_t commands[], uint16_t *cmdcount, uint16_t *cmdlen);
static void MakeReadRegsCommand(bool_t bGen4Ether, uint16_t startIndex, uint8_t commands[], uint16_t *cmdlen);
static void MakeWriteRegsCommand(bool_t bGen4Ether, uint16_t startIndex, uint8_t commands[], uint16_t *cmdlen);
static void MakeReadBlockCommand(bool_t bGen4Ether, uint16_t startIndex, uint8_t commands[], uint16_t *cmdlen);
static void MakeWriteBlockCommand(bool_t bGen4Ether, uint16_t startIndex, uint8_t commands[], uint16_t *cmdlen);
static nai_status_t SetEthTDRConfig(int32_t paramCount, int32_t* p_params);
static nai_status_t GetEthTDRConfig(int32_t paramCount, int32_t* p_params);
static bool_t ParseTDRCommand(int32_t startIndex, int32_t cmdarraysize, uint8_t command[], uint16_t *tdrcmdlen, int32_t tdrcmdarraysize, uint8_t tdr_command[]);
static void DisplayDecodedEthCommand(uint16_t cmdcount, uint16_t cmdlen, uint8_t tdr_command[]);
static void DecodedEthFlags(uint16_t flags, uint8_t *onoffbrd, uint8_t *regsize);
static nai_status_t ClearEthTDRConfig(int32_t paramCount, int32_t* p_params);
static nai_status_t RunEthTDR(int32_t paramCount, int32_t* p_params);
static nai_status_t HaltEthTDR(int32_t paramCount, int32_t* p_params);
static void CreateTDRTCPServer(void);
static void CreateTDRUDPServer(void);
static void DecodeUPRTDRMessages(const uint8_t msg[], int32_t msgsize);
static bool_t ParseTDRResponse(int32_t startIndex, int32_t rsparraysize, uint8_t response[], uint16_t *tdrrsplen, int32_t tdrrsparraysize, uint8_t tdr_response[]);
static void DisplayDecodedResponse(uint16_t responselen, uint8_t response[]);

static bool_t bGen4TDRCommands = FALSE;
static uint32_t UNUSED_REG_ADDR_FOR_TEST = 0x0190;

#if defined (__VXWORKS__)
 int UPR_Handler( int Param );
#elif LINUX
 pthread_t interruptThread;
 static void* UPR_Handler(void* lpParam );
#else /* Default Windows */
 DWORD WINAPI UPR_Handler( LPVOID lpParam );
#endif
static int terminateThread;

/****** Command Table *******/
enum eth_tdr_commands
{
   ETH_TDR_CMD_SET,
   ETH_TDR_CMD_GET,
   ETH_TDR_CMD_CLEAR,
   ETH_TDR_CMD_RUN,
   ETH_TDR_CMD_HALT,
   ETH_TDR_CMD_COUNT
};

naiapp_cmdtbl_params_t ETH_TDRcmdMenuCmds[] = {
   {"Set",    "Set TDR Configuration",    ETH_TDR_CMD_SET,    SetEthTDRConfig},
   {"Get",    "Get TDR Configuration",    ETH_TDR_CMD_GET,    GetEthTDRConfig},
   {"Clear",  "Clear TDR Configuration",  ETH_TDR_CMD_CLEAR,  ClearEthTDRConfig},
   {"Run",    "Run TDR",                  ETH_TDR_CMD_RUN,    RunEthTDR},
   {"Halt",   "Halt TDR",                 ETH_TDR_CMD_HALT,   HaltEthTDR},
};

#define DEF_ETHER_CMD_COUNT          4
#define DEF_ETHER_TDR_PERIOD         5000
#define DEF_RESPONSE_PROTOCOL        ETHER_GEN4_UDP_PROTOCOL
#define DEF_RESPONSE_IP_LEN          ETHER_GEN4_IPv4_ADDR_LEN

static uint16_t DEF_TDR_RESPONSE_PORT      =  52801;
static uint8_t  DEF_TDR_RESPONSE_IP_ADDR[] = {192,168,1,100};

/**************************************************************************************************************/
#if defined (__VXWORKS__)
int32_t EtherTDRCommands(void)
#else
int32_t main(void)
#endif
{
   bool_t stop = FALSE;
   int32_t cardIndex;
   int8_t inputBuffer[80];
   int32_t inputResponseCnt;

   if (naiapp_RunBoardMenu(CONFIG_FILE) == TRUE)
   {
      while (stop != TRUE)
      {
         stop = naiapp_query_CardIndex(naiapp_GetBoardCnt(), 0, &cardIndex);
         if (stop != TRUE)
         {
            Run_EtherTDRCommands(cardIndex);
         }
         printf("\nType Q to quit or Enter key to restart application:\n");
         stop = naiapp_query_ForQuitResponse(sizeof(inputBuffer), NAI_QUIT_CHAR, inputBuffer, &inputResponseCnt);
      }
   }

   printf("\nType the Enter key to exit the program: ");
   naiapp_query_ForQuitResponse(sizeof(inputBuffer), NAI_QUIT_CHAR, inputBuffer, &inputResponseCnt);
   naiapp_access_CloseAllOpenCards();

   return 0;
}

/**************************************************************************************************************/
static bool_t Run_EtherTDRCommands(int32_t cardIndex)
{
   bool_t bQuit = FALSE;
   bool_t bContinue = TRUE;
   bool_t bCmdFound = FALSE;
   int32_t cmd;
   int8_t inputBuffer[80];
   int32_t inputResponseCnt;

   naiapp_AppParameters_t  tdr_params;
   p_naiapp_AppParameters_t tdrcommands_params = &tdr_params;
   tdrcommands_params->cardIndex = cardIndex;

   bGen4TDRCommands = SupportsGen4Ether(cardIndex);

   while (bContinue)
   {
      naiapp_utils_LoadParamMenuCommands(ETH_TDR_CMD_COUNT, ETH_TDRcmdMenuCmds);
      naiapp_display_ParamMenuCommands((int8_t *)"Ethernet Time Driven Response (TDR) Command Menu");
      printf("\nType Ethernet TDR command or %c to quit : ", NAI_QUIT_CHAR);
      bQuit = naiapp_query_ForQuitResponse(sizeof(inputBuffer), NAI_QUIT_CHAR, inputBuffer, &inputResponseCnt);
      if (!bQuit)
      {
         if (inputResponseCnt > 0)
         {
            bCmdFound = naiapp_utils_GetParamMenuCmdNum(inputResponseCnt, inputBuffer, &cmd);
            if (bCmdFound)
            {
               switch (cmd)
               {
               case ETH_TDR_CMD_SET:
               case ETH_TDR_CMD_GET:
               case ETH_TDR_CMD_CLEAR:
               case ETH_TDR_CMD_RUN:
               case ETH_TDR_CMD_HALT:
                  ETH_TDRcmdMenuCmds[cmd].func(APP_PARAM_COUNT, (int32_t*)tdrcommands_params);
                  break;
               default:
                  printf("Invalid command entered\n");
                  break;
               }
            }
            else
               printf("Invalid command entered\n");
         }
      }
      else
         bContinue = FALSE;
   }
   return bQuit;
}

/**************************************************************************************************************/
static bool_t QueryEthTDRIPAddr(void)
{
   bool_t bQuit = FALSE;
   bool_t bContinue = TRUE;
   int8_t inputBuffer[80];
   int32_t inputResponseCnt;

   if (!bQuit)
   {
      bContinue = TRUE;
      while (bContinue)
      {
         printf("Please Enter TDR Response IP Address: [default=%d.%d.%d.%d]): ",
            DEF_TDR_RESPONSE_IP_ADDR[0],DEF_TDR_RESPONSE_IP_ADDR[1],DEF_TDR_RESPONSE_IP_ADDR[2],DEF_TDR_RESPONSE_IP_ADDR[3]);
         bQuit = naiapp_query_ForQuitResponse(sizeof(inputBuffer), NAI_QUIT_CHAR, inputBuffer, &inputResponseCnt);
         if (bQuit)
            bContinue = FALSE;
         else
         {
            if (inputResponseCnt > NAI_MAX_IP_LEN)
               printf("ERROR: Invalid IP Address.\n");
            else
            {
               if (inputResponseCnt > 0)
                  ParseIPv4Address((char *)inputBuffer, DEF_TDR_RESPONSE_IP_ADDR);
            }
         }
         if (!bQuit)
         {
            printf("Please Enter TDR Response Port: [default=%d]): ", DEF_TDR_RESPONSE_PORT);
            bQuit = naiapp_query_ForQuitResponse(sizeof(inputBuffer), NAI_QUIT_CHAR, inputBuffer, &inputResponseCnt);
            if (bQuit)
               bContinue = FALSE;
            else
            {
               if (inputResponseCnt > 0)
                  DEF_TDR_RESPONSE_PORT = (uint16_t)atol((const char *)inputBuffer);
               bContinue = FALSE;
            }
         }
      }
   }
   return bQuit;
}

/**************************************************************************************************************/
static bool_t QueryEthTDRid(int32_t *tdrid)
{
   bool_t bQuit = FALSE;
   int8_t inputBuffer[80];
   int32_t inputResponseCnt;

   printf("Enter the TDR ID: (default: 1) > ");
   bQuit = naiapp_query_ForQuitResponse(sizeof(inputBuffer), NAI_QUIT_CHAR, inputBuffer, &inputResponseCnt);
   if (!bQuit)
   {
      if (inputResponseCnt == 0)
         *tdrid = 1;
      else
      {
         *tdrid = atol((const char *)inputBuffer);
      }
   }
   return bQuit;
}

/**************************************************************************************************************/
static void InitTDRCommands(uint8_t commands[], uint16_t *cmdcount, uint16_t *cmdlen)
{
   uint16_t msgIndex = 0;
   uint16_t tdrcmdcnt = 0;
   uint16_t ethcmdlen = 0;
   uint16_t tdrcmdlen = 0;

   if (bGen4TDRCommands)
   {
      MakeReadRegsCommand(bGen4TDRCommands, msgIndex, commands, &ethcmdlen);
      msgIndex += ethcmdlen;
      tdrcmdlen += ethcmdlen;
      tdrcmdcnt++;

      MakeWriteRegsCommand(bGen4TDRCommands, msgIndex, commands, &ethcmdlen);
      msgIndex += ethcmdlen;
      tdrcmdlen += ethcmdlen;
      tdrcmdcnt++;

      MakeReadBlockCommand(bGen4TDRCommands, msgIndex, commands, &ethcmdlen);
      msgIndex += ethcmdlen;
      tdrcmdlen += ethcmdlen;
      tdrcmdcnt++;

      MakeWriteBlockCommand(bGen4TDRCommands, msgIndex, commands, &ethcmdlen);
      msgIndex += ethcmdlen;
      tdrcmdlen += ethcmdlen;
      tdrcmdcnt++;

      *cmdlen = tdrcmdlen;
      *cmdcount = tdrcmdcnt;
   }
   else
   {
      printf("Ethernet TDR Command Support Prior to Generation 4 Ethernet commands currently not supported\n");
   }
}

/**************************************************************************************************************/
static nai_status_t SetEthTDRConfig(int32_t paramCount, int32_t* p_params)
{
   p_naiapp_AppParameters_t p_tdr_params = (p_naiapp_AppParameters_t)p_params;
   int32_t cardIndex = p_tdr_params->cardIndex;
   int32_t tdrid;
   bool_t bQuit = FALSE;
   nai_status_t status;
   uint8_t commands[MAX_ETHER_TDR_CMD_CNT*MAX_ETHER_BLOCK_REG_CNT];
   uint16_t cmdcount = 0;
   uint16_t cmdlength = 0;
   int32_t i;
   uint16_t protocol = DEF_RESPONSE_PROTOCOL;
   uint16_t iplen = DEF_RESPONSE_IP_LEN;
   uint16_t period = DEF_ETHER_TDR_PERIOD;
   uint8_t ip[DEF_RESPONSE_IP_LEN];
   uint16_t port;

#if defined (WIN32)
   UNREFERENCED_PARAMETER(paramCount);
#endif

   bQuit = QueryEthTDRIPAddr();
   if (!bQuit)
   {
      bQuit = QueryEthTDRid(&tdrid);
      if (!bQuit)
      {
         InitTDRCommands(commands, &cmdcount, &cmdlength);
         for (i = 0; i < DEF_RESPONSE_IP_LEN; i++)
            ip[i] = DEF_TDR_RESPONSE_IP_ADDR[i];
         port = DEF_TDR_RESPONSE_PORT;
         status = check_status(naibrd_Ether_SetTDRConfig(cardIndex,(uint16_t)tdrid,protocol,iplen,ip,port,period,cmdcount,cmdlength,commands));
         if (status == NAI_SUCCESS)
         {
            printf("TDR ID = %d configured.\n", tdrid);
         }
      }
   }
   return (bQuit) ? NAI_ERROR_UNKNOWN : NAI_SUCCESS;
}

/**************************************************************************************************************/
static nai_status_t ClearEthTDRConfig(int32_t paramCount, int32_t* p_params)
{
   p_naiapp_AppParameters_t p_tdr_params = (p_naiapp_AppParameters_t)p_params;
   int32_t cardIndex = p_tdr_params->cardIndex;
   int32_t tdrid;
   bool_t bQuit = FALSE;
   nai_status_t status;

#if defined (WIN32)
   UNREFERENCED_PARAMETER(paramCount);
#endif

   bQuit = QueryEthTDRid(&tdrid);
   if (!bQuit)
   {
      status = check_status(naibrd_Ether_ClearTDRConfig(cardIndex, (uint16_t)tdrid));
      if (status == NAI_SUCCESS)
      {
         printf("TDR ID = %d cleared\n", tdrid);
      }
   }
   return (bQuit) ? NAI_ERROR_UNKNOWN : NAI_SUCCESS;
}

/**************************************************************************************************************/
static nai_status_t RunEthTDR(int32_t paramCount, int32_t* p_params)
{
   p_naiapp_AppParameters_t p_tdr_params = (p_naiapp_AppParameters_t)p_params;
   int32_t cardIndex = p_tdr_params->cardIndex;
   int32_t tdrid;
   bool_t bQuit = FALSE;
   nai_status_t status;

#if defined (WIN32)
   UNREFERENCED_PARAMETER(paramCount);
#endif

   bQuit = QueryEthTDRid(&tdrid);
   if (!bQuit)
   {
      status = check_status(naibrd_Ether_StartTDR(cardIndex, (uint16_t)tdrid));
      if (status == NAI_SUCCESS)
      {
         printf("TDR ID = %d Started\n", tdrid);
      }

      terminateThread = FALSE;
#if defined (__VXWORKS__)
      taskSpawn("uprHandler", 100, 0, 10000, (FUNCPTR)UPR_Handler, NULL, 0, 0, 0, 0, 0, 0, 0, 0, 0 );
#elif defined (LINUX)
      pthread_create(&interruptThread, NULL, (void*)UPR_Handler, NULL);
#else
      CreateThread( NULL, 0, UPR_Handler, NULL, 0, NULL );
#endif
   }
   return (bQuit) ? NAI_ERROR_UNKNOWN : NAI_SUCCESS;
}

/**************************************************************************************************************/
static nai_status_t HaltEthTDR(int32_t paramCount, int32_t* p_params)
{
   p_naiapp_AppParameters_t p_tdr_params = (p_naiapp_AppParameters_t)p_params;
   int32_t cardIndex = p_tdr_params->cardIndex;
   int32_t tdrid;
   bool_t bQuit = FALSE;
   nai_status_t status;

#if defined (WIN32)
   UNREFERENCED_PARAMETER(paramCount);
#endif

   bQuit = QueryEthTDRid(&tdrid);
   if (!bQuit)
   {
      status = check_status(naibrd_Ether_StopTDR(cardIndex, (uint16_t)tdrid));
      if (status == NAI_SUCCESS)
      {
         printf("TDR ID = %d Stopped\n", tdrid);
         terminateThread = TRUE;
      }
   }
   return (bQuit) ? NAI_ERROR_UNKNOWN : NAI_SUCCESS;
}

Help Bot

X