EtherTDRCommands
Edit this on GitLab
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.
-
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. -
Query the user for a card index with
naiapp_query_CardIndex(). -
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:
|
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:
-
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. -
Enter a loop that queries for card index.
-
Call
Run_EtherTDRCommands()to enter the interactive command loop. -
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) orETHER_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 to192.168.1.100. -
port— the TCP or UDP port on the host. The sample defaults to52801. -
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 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
|
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:
-
Create a socket and bind it to the configured response port.
-
Listen for incoming data (TCP: accept a connection then recv; UDP: recvfrom).
-
Pass received data to
DecodeUPRTDRMessages()for parsing. -
Continue receiving until the
terminateThreadflag 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 |
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 |
TDR period too fast, responses overlapping |
Period shorter than combined command execution time |
Increase the period value in |
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 |
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, ðcmdlen);
msgIndex += ethcmdlen;
tdrcmdlen += ethcmdlen;
tdrcmdcnt++;
MakeWriteRegsCommand(bGen4TDRCommands, msgIndex, commands, ðcmdlen);
msgIndex += ethcmdlen;
tdrcmdlen += ethcmdlen;
tdrcmdcnt++;
MakeReadBlockCommand(bGen4TDRCommands, msgIndex, commands, ðcmdlen);
msgIndex += ethcmdlen;
tdrcmdlen += ethcmdlen;
tdrcmdcnt++;
MakeWriteBlockCommand(bGen4TDRCommands, msgIndex, commands, ðcmdlen);
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;
}