Part Number:BEAGLEBK
Tool/software: TI-RTOS
Hi,
I wish to know when does the NDK calls the NetworkIPAddr callback function? In the NDK User's guide document, it says that it is called when an IP address is added or removed. What does that mean? I am using Configuration Manager APIs to configure my application. In my config handle (hCfg), I setup the manual address and add the route (please refer to source code). Using this hCfg, I call the NC_NetStart function. Doesn't it mean that I am adding an IP? My application doesn't call the NetworkIPAddr hook function. However, my app does call the NetworkOpen hook function. Here is my source code. I am using my own network driver here instead of EMAC driver from TI-RTOS.
#include <ti/ndk/inc/netmain.h>
#include <stdio.h>
#include <ti/ndk/inc/stkmain.h>
/*
* ======== main.c ========
*/
#include <xdc/std.h>
#include <xdc/runtime/Error.h>
#include <xdc/runtime/System.h>
#include <ti/sysbios/BIOS.h>
#include <ti/sysbios/knl/Task.h>
#include <ti/board/board.h>
#include <ti/drv/uart/UART.h>
#include <ti/drv/uart/UART_stdio.h>
/*
* ======== taskFxn ========
*/
#define MAX_TABLE_ENTRIES 3
#define UDPHANDLERSTACK 1024
// Our NETCTRL callback functions
static void NetworkOpen();
static void NetworkClose();
static void NetworkIPAddr( uint32_t IPAddr, uint32_t IfIdx, uint32_t fAdd );
Void udpHandler(UArg arg0, UArg arg1);
// Fun reporting function
static void ServiceReport( uint32_t Item, uint32_t Status, uint32_t Report, void* hCfgEntry );
extern int CpswEmacInit (STKEVENT_Handle hEvent);
extern int WifiInit (STKEVENT_Handle hEvent);
//---------------------------------------------------------------------------
// Configuration
//
char *HostName = "EchoHost";
char *LocalIPAddr = "192.168.1.4";
char *LocalIPMask = "255.255.255.0"; // Not used when using DHCP
char *GatewayIP = "192.168.1.1"; // Not used when using DHCP
char *DomainName = "demo.net"; // Not used when using DHCP
char *DNSServer = "0.0.0.0"; // Used when set to anything but zero
/*
* ======== main ========
*/
static int nimu_device_index = 0U;
NIMU_DEVICE_TABLE_ENTRY NIMUDeviceTable[MAX_TABLE_ENTRIES];
Int main()
{
NIMUDeviceTable[nimu_device_index++].init = &WifiInit ;
NIMUDeviceTable[nimu_device_index].init = NULL ;
BIOS_start(); /* does not return */
return(0);
}
int StackTest()
{
Board_STATUS boardInitStatus =0;
Board_initCfg boardCfg;
int rc;
void* hCfg;
boardCfg = BOARD_INIT_PINMUX_CONFIG |
BOARD_INIT_MODULE_CLOCK | BOARD_INIT_UART_STDIO;
Board_init(boardCfg);
if (boardInitStatus !=0)
{
UART_printf("Board_init failure\n");
return(0);
}
UART_printf("Board_init success\n");
//
// THIS MUST BE THE ABSOLUTE FIRST THING DONE IN AN APPLICATION before
// using the stack!!
//
rc = NC_SystemOpen( NC_PRIORITY_LOW, NC_OPMODE_INTERRUPT );
if( rc )
{
UART_printf("NC_SystemOpen Failed (%d)\n",rc);
for(;;);
}
/*Create and build the system configuration from scratch without using XGCONF*/
hCfg = CfgNew();
if( !hCfg )
{
UART_printf("Unable to create configuration\n");
return 0;
}
// We better validate the length of the supplied names
if( strlen( DomainName ) >= CFG_DOMAIN_MAX ||
strlen( HostName ) >= CFG_HOSTNAME_MAX )
{
UART_printf("Names too long\n");
return 0;
}
// Add our global hostname to hCfg (to be claimed in all connected domains)
CfgAddEntry( hCfg, CFGTAG_SYSINFO, CFGITEM_DHCP_HOSTNAME, 0,
strlen(HostName), (uint8_t *)HostName, 0 );
// If the IP address is specified, manually configure IP and Gateway
//if (!platform_get_switch_state(1))
if (1)
{
CI_IPNET NA;
CI_ROUTE RT;
uint32_t IPTmp;
// Setup manual IP address
memset( &NA, 0, sizeof(NA) );
NA.IPAddr = inet_addr(LocalIPAddr);
NA.IPMask = inet_addr(LocalIPMask);
strcpy( NA.Domain, DomainName );
NA.NetType = 0;
// Add the address to interface 1
CfgAddEntry( hCfg, CFGTAG_IPNET, 1, 0,
sizeof(CI_IPNET), (uint8_t *)&NA, 0 );
// Add the default gateway. Since it is the default, the
// destination address and mask are both zero (we go ahead
// and show the assignment for clarity).
memset( &RT, 0, sizeof(RT) );
RT.IPDestAddr = 0;
RT.IPDestMask = 0;
RT.IPGateAddr = inet_addr(GatewayIP);
// Add the route
CfgAddEntry( hCfg, CFGTAG_ROUTE, 0, 0,
sizeof(CI_ROUTE), (uint8_t *)&RT, 0 );
// Manually add the DNS server when specified
IPTmp = inet_addr(DNSServer);
if( IPTmp )
CfgAddEntry( hCfg, CFGTAG_SYSINFO, CFGITEM_DHCP_DOMAINNAMESERVER,
0, sizeof(IPTmp), (uint8_t *)&IPTmp, 0 );
}
// Else we specify DHCP
else
{
CI_SERVICE_DHCPC dhcpc;
// Specify DHCP Service on IF-1
memset( &dhcpc, 0,sizeof(dhcpc) );
dhcpc.cisargs.Mode = CIS_FLG_IFIDXVALID;
dhcpc.cisargs.IfIdx = 1;
dhcpc.cisargs.pCbSrv = &ServiceReport;
CfgAddEntry( hCfg, CFGTAG_SERVICE, CFGITEM_SERVICE_DHCPCLIENT, 0,
sizeof(dhcpc), (uint8_t *)&dhcpc, 0 );
}
//
// Configure IPStack/OS Options
//
// We don't want to see debug messages less than WARNINGS
rc = DBG_WARN;
CfgAddEntry( hCfg, CFGTAG_OS, CFGITEM_OS_DBGPRINTLEVEL,
CFG_ADDMODE_UNIQUE, sizeof(uint32_t), (uint8_t *)&rc, 0 );
//
// This code sets up the TCP and UDP buffer sizes
// (Note 8192 is actually the default. This code is here to
// illustrate how the buffer and limit sizes are configured.)
//
// UDP Receive limit
rc = 8192;
CfgAddEntry( hCfg, CFGTAG_IP, CFGITEM_IP_SOCKUDPRXLIMIT,
CFG_ADDMODE_UNIQUE, sizeof(uint32_t), (uint8_t *)&rc, 0 );
//
// Boot the system using this configuration
//
// We keep booting until the function returns 0. This allows
// us to have a "reboot" command.
//
do
{
rc = NC_NetStart( hCfg, NetworkOpen, NetworkClose, NetworkIPAddr );
} while( rc > 0 );
// Delete Configuration
CfgFree( hCfg );
NC_SystemClose();
return(0);
}
//
// Service Status Reports
//
// Here's a quick example of using service status updates
//
static char *TaskName[] = { "Telnet","HTTP","NAT","DHCPS","DHCPC","DNS" };
static char *ReportStr[] = { "","Running","Updated","Complete","Fault" };
static char *StatusStr[] = { "Disabled","Waiting","IPTerm","Failed","Enabled" };
static void ServiceReport( uint32_t Item, uint32_t Status, uint32_t Report, void* h )
{
UART_printf( "Service Status: %-9s: %-9s: %-9s: %03d\n",
TaskName[Item-1], StatusStr[Status],
ReportStr[Report/256], Report&0xFF );
//
// Example of adding to the DHCP configuration space
//
// When using the DHCP client, the client has full control over access
// to the first 256 entries in the CFGTAG_SYSINFO space.
//
// Note that the DHCP client will erase all CFGTAG_SYSINFO tags except
// CFGITEM_DHCP_HOSTNAME. If the application needs to keep manual
// entries in the DHCP tag range, then the code to maintain them should
// be placed here.
//
// Here, we want to manually add a DNS server to the configuration, but
// we can only do it once DHCP has finished its programming.
//
if( Item == CFGITEM_SERVICE_DHCPCLIENT &&
Status == CIS_SRV_STATUS_ENABLED &&
(Report == (NETTOOLS_STAT_RUNNING|DHCPCODE_IPADD) ||
Report == (NETTOOLS_STAT_RUNNING|DHCPCODE_IPRENEW)) )
{
uint32_t IPTmp;
// Manually add the DNS server when specified
IPTmp = inet_addr(DNSServer);
if( IPTmp )
CfgAddEntry( 0, CFGTAG_SYSINFO, CFGITEM_DHCP_DOMAINNAMESERVER,
0, sizeof(IPTmp), (uint8_t *)&IPTmp, 0 );
}
}
//
// NetworkOpen
//
// This function is called after the configuration has booted
//
static void NetworkOpen()
{
TaskCreate(udpHandler,"NetworkTask",1, UDPHANDLERSTACK,0,0,0);
}
//
// NetworkClose
//
// This function is called when the network is shutting down,
// or when it no longer has any IP addresses assigned to it.
//
static void NetworkClose()
{
}
//
// NetworkIPAddr
//
// This function is called whenever an IP address binding is
// added or removed from the system.
//
static void NetworkIPAddr( uint32_t IPAddr, uint32_t IfIdx, uint32_t fAdd )
{
uint32_t IPTmp;
if( fAdd )
UART_printf("Network Added: ");
else
UART_printf("Network Removed: ");
// Print a message
IPTmp = NDK_ntohl( IPAddr );
UART_printf("If-%d:%d.%d.%d.%d\n", IfIdx,
(uint8_t)(IPTmp>>24)&0xFF, (uint8_t)(IPTmp>>16)&0xFF,
(uint8_t)(IPTmp>>8)&0xFF, (uint8_t)IPTmp&0xFF );
}
/*
* ======== udpHandler ========
* Creates new Task to handle new udp connections.
*/
Void udpHandler(UArg arg0, UArg arg1)
{
char data[]= "Hello";
struct sockaddr_in cli_addr;
SOCKET s = NDK_socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
if (s <0)
{
UART_printf("Socket not created: %d\n", fdError());
}
memset(&cli_addr, 0, sizeof(cli_addr));
cli_addr.sin_family = AF_INET;
cli_addr.sin_addr.s_addr = inet_addr("192.168.1.10");
cli_addr.sin_port = 17225;
int err = NDK_sendto(s,data,sizeof(data),0,(struct sockaddr *)&cli_addr, sizeof(cli_addr));
if(err<0)
{
UART_printf("Error: %x\n",fdError());
}
err = NDK_shutdown(s,0);
if(err<0)
{
UART_printf("Error: %x\n",fdError());
}
//NC_NetStop(1);
}