This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

RTOS/TM4C1294NCPDT: getaddrinfo works only if the task is started from networkIPAddrHook

Expert 2730 points
Part Number: TM4C1294NCPDT

Tool/software: TI-RTOS

I'm trying to get the DNS to work, but it seems to be not so easy. The function DNSGetHostByName fails always to resolve IP-address and that is why I have to use getaddrinfo. The only problem is that it only works if I create a task dynamically from networkIPAddrHook. If I create a task statically (means adding it to .cfg file) it fails to get address. Below all the code and output.

TI-RTOS: 2.16.1.14

XDCTools: 3.32.0.06

NDK: 2.25.00.09

.cfg

 /* ================ NDK configuration ================ */
var Ndk		= xdc.loadPackage('ti.ndk.config');
var Global	= xdc.useModule('ti.ndk.config.Global');
var Ip		= xdc.useModule('ti.ndk.config.Ip');
var Udp		= xdc.useModule('ti.ndk.config.Udp');
var Tcp		= xdc.useModule('ti.ndk.config.Tcp');
var Dns 	= xdc.useModule('ti.ndk.config.Dns');

Global.IPv6 = false;
Global.stackLibType = Global.MIN;
Global.networkOpenHook = "&TcpHooks_vNetOpenHook";
Global.networkIPAddrHook = "&TcpHooks_vIPAddrHook";

(This fails to resolve the ip-address)
var task11Params = new Task.Params();
task11Params.instance.name = "hDnsTest";
task11Params.priority = 1;
Program.global.hDnsTest = Task.create("&testTaskFxn", task11Params);

/* automatically call fdOpen/CloseSession for our sockets Task */
Global.autoOpenCloseFD = true;

Global.pktNumFrameBufs = 10;
Global.memRawPageCount = 6;
Global.ndkThreadStackSize = 1536;
Global.lowTaskStackSize = 1024;
Global.normTaskStackSize = 1024;
Global.highTaskStackSize = 1024;
//Global.stackBeginHook = "&TcpHooks_vReadIPAddress";

Tcp.transmitBufSize = 1024;
Tcp.receiveBufSize = 1024;

Ip.autoIp = true;

tcphooks.c

Task to resolve ip-address for to test

#define HOSTNAME          "www.google.de"
static char strIp[INET_ADDRSTRLEN];

void testTaskFxn(UArg arg0, UArg arg1)
{
    struct addrinfo *server_data = NULL;
    int result;

    Task_sleep(5000);

    while(1)
    {
        System_printf("!!!!!!!!!!\n", result);

        result = getaddrinfo(HOSTNAME, "0", NULL, &server_data);

        System_printf("getaddrinfo result: %d\n", result);

        if (result == 0 && server_data != NULL)
        {
            struct sockaddr addr = *(server_data->ai_addr);
            inet_ntop(AF_INET, &((struct sockaddr_in *)&addr)->sin_addr, strIp, INET_ADDRSTRLEN);
            System_printf("Resolved address:%s\n", strIp);

            freeaddrinfo(server_data);
            server_data = NULL;
        }

        Task_sleep(5000);
    }
}
networkIPAddrHook:

void TcpHooks_vIPAddrHook(IPN IPAddr, uint IfIdx, uint fAdd)
{
    IPN IPTmp;
    CI_IPNET NA;
    HANDLE hCfg;
    int rc = 0;
    char IPString[16];

    hCfg = CfgGetDefault();

    /* Initialize the IP Address block. */
    bzero(&NA, sizeof(CI_IPNET));

    if (fAdd)
    {
        System_printf("networkIPAddrHook: Network Added\n");
    }
    else
    {
        System_printf("networkIPAddrHook: Network Removed\n");
    }

    IPTmp = ntohl(IPAddr);
    System_printf("networkIPAddrHook:\tIf-%d:%d.%d.%d.%d\n", IfIdx,
                  (UINT8)(IPTmp>>24)&0xFF, (UINT8)(IPTmp>>16)&0xFF,
                  (UINT8)(IPTmp>>8)&0xFF, (UINT8)IPTmp&0xFF);

    /* Print the IP address information only if one is present. */
    if (CfgGetImmediate(hCfg, CFGTAG_IPNET, 1, 1, sizeof(NA), (UINT8 *)&NA) == sizeof(NA))
    {
        /* Yes the device was configured and we got the IP address/Mask */
        NtIPN2Str (NA.IPAddr, IPString);
        System_printf("IP Address: %s\n", IPString);
        NtIPN2Str (NA.IPMask, IPString);
        System_printf("IP Subnet Mask: %s\n", IPString);
    }
    else
    {
        System_printf("IP Address & SUBNET MASK NOT AVAILABLE\n");
    }

    rc = CfgGetImmediate(hCfg, CFGTAG_SYSINFO, CFGITEM_DHCP_DOMAINNAMESERVER,
                         1, 4, (UINT8 *)&IPTmp );
    if (rc == 4)
    {
        IPTmp = ntohl(IPTmp);
        System_printf("networkIPAddrHook:\tIf-%d: DNS = %d.%d.%d.%d\n", IfIdx,
                      (UINT8)(IPTmp>>24)&0xFF, (UINT8)(IPTmp>>16)&0xFF,
                      (UINT8)(IPTmp>>8)&0xFF, (UINT8)IPTmp&0xFF);
    }
    else
    {
        System_printf("networkIPAddrHook: DNS IP Fetch Failed!!\n");
    }

    // This will be created if the task is not defined in .cfg file
    Task_Params taskParams;
    Error_Block eb;
    static bool init = false;
    static Task_Handle taskHandle;

    /* Create a HTTP task when the IP address is added */

    if (fAdd && !init)
    {
        init = true;
        Error_init(&eb);

        Task_Params_init(&taskParams);
        taskParams.stackSize = 4096;
        taskParams.priority = 1;
        taskHandle = Task_create((Task_FuncPtr)testTaskFxn, &taskParams, &eb);
        if (taskHandle == NULL) {
            System_printf("Failed to create  Task\n");
        }
        else
        {
            System_printf("created a Task at prioirty 1\r\n");
        }
    }
}

Results:

When the task is created in ipaddhook:

,!!!!!!!!!!
,getaddrinfo result: 0
,Resolved address:216.58.213.195

When the task is created in .cfg

,!!!!!!!!!!
,00005.005 getaddrinfo: Error: couldn't resolve host name "www.google.de"
,
,getaddrinfo result: -2

,!!!!!!!!!!
,00010.005 getaddrinfo: Error: couldn't resolve host name "www.google.de"
,
,getaddrinfo result: -2

So the question is, why can I call the getaddrinfo successfully only from the task created dynamically from the ipaddrhook? And why the DNSGetHostByName doesn't work at all?

JHi

  • Hi JHi,

    NDK sockets APIs must be called from within a thread (you're doing that correctly) but must also be called after a file descriptor session has been opened for that thread.  This is done with code like the following:

    void myTaskThread() // statically created Task thread
    {
        fdOpenSession(TaskSelf()); // open the NDK file descriptor session for this thread
    
        // call some sockets APIs here e.g. sock(), or getaddrinfo().
    
        fdCloseSession(TaskSelf()); // close the NDK file descriptor session for this thread
    }

    The following setting of your configuration file is automatically opening the file descriptor setting for you, for the case of your dynamically created Task thread:

    JHi said:
    /* automatically call fdOpen/CloseSession for our sockets Task */ Global.autoOpenCloseFD = true;

    This configuration setting causes "fdOpenSession()" and "fdCloseSession()" to be called automatically for dynamically created Task threads only.  This is why getaddrinfo() is working for your dynamically created Task thread.

    For your statically created Task thread, you'll have to add the calls explicitly in the code, as shown in the example above.


    Steve

  • Thanks for the explanation!

    JHi