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/DK-TM4C129X: Get access to DHCP Client information

Part Number: DK-TM4C129X

Tool/software: TI-RTOS

I'm working on an application where I need to obtain the IP address, host name, and name server information provided from the network's DHCP server.

Is there a way I can access the information that the DHCP client is working with?  Some way I can get a pointer to the DHCPLEASE structure it is handling?

Later-

  • Hello David,

    Just to be sure, you are looking for TI-RTOS solution for this right? Not just using the base TivaWare?
  • Yes, this is using tirtos_tivac_2_16_01_14.

    Not sure if this is the only supported platform, Does TivaWare or SysBios support multi-threaded applications?

    My application has about a half-dozen simultaneous threads normally (working on Linux and Windows already).

    Later-

  • Hello David,

    I was more asking to route your question to the correct engineers for support, I don't work on TI-RTOS myself so I have pinged the TI-RTOS experts who can help you.
  • Hi David,

    Unfortunately, there's now way to get a pointer to the DHCPLEASE itself.

    You should be able to access the info you're looking for via the Cfg* APIs. I'll have to get back to you on finding the name server, but you can start with this code in the mean time:

    1) IP address


    char IPString[50];
    CI_IPNET    NA;

    CfgGetImmediate( 0, CFGTAG_IPNET, if_req.index, 1, sizeof(NA), (UINT8 *)&NA);

    NtIPN2Str (NA.IPAddr, IPString);
    DbgPrintf(DBG_INFO, "IP Address    : %s\n", IPString);

    // NA.Domain = the domain name string

    2) host name


    You should have set this in your app, however you can get it like this:

    char hostName[HOSTNAME_LENGTH]; // HOSTNAME_LENGTH == 256

    CfgGetImmediate(0, CFGTAG_SYSINFO, CFGITEM_DHCP_HOSTNAME, 1, HOSTNAME_LENGTH - 1, (uint8_t *)hostName);

    // hostName[] now has the host name string

    Steve

  • The network configuration is set by the DHCP server on the network.  I don't supply a hostname, I'm provided the hostname I'm supposed to use.

    Same with the other items.  I'm provided an IP address and domain name, I don't provide them.

    I'm not exactly sure why the DNS servers, or gateway are required, but for some reason, it's part of the protocol I'm supporting.

    Later-

    David

  • Well, I'm getting closer to getting things down where I can load and test something (not that it's going to work...).

    First, there is a major collision between the functions in bsd/sys/socket.h and nettools/inc/netcfg.h  I've worked it out by adding a bunch of conditional blocks, but that shouldn't be something for me to be doing.

    Basically, my version of 17.9.0.STS is not factory anymore.  Main problem is the definition of a couple of structures.

    Now, to the code you supplied me:

    in section 1), where do I get if_req.index?  I don't see this defined anywhere.

    On to the next item.  I cannot for the life of me, figure how to link in EMACSnow_NIMUInit.  Where is it defined, and how do I include it?

    Later-

    David

  • David,

    David Dudley said:
    there is a major collision between the functions in bsd/sys/socket.h and nettools/inc/netcfg.h

    Are you including both sys/socket.h and (netmain.h or stkmain.h) in the same source file?

    If so, this is probably the reason you're seeing collisions. The BSD support layer in the version of the NDK that you're using has the limitation that BSD sockets API code must be in a separate compilation unit from your "standard NDK API" code.

    (Typically, if you need to include either netmain.h or stkmain.h in order to get at a particular API, then that would be a "standard NDK API").

    I would recommend to refactor your code so that one file (let's say "file A") includes sys/socket.h and has your BSD calls, and another file ("file B") includes netmain.h and stkmain.h, and calls "NDK standard functions".

    For example, you might have something like this:

    file A:

    #include <sys/socket.h>
    
    extern void findIpInfo();
    
    myFxn()
    
    {
    
        findIpInfo(); // this function will call Cfg* APIs, and other non-BSD NDK functions
    
        int s = socket(...);
    
        send(s, ...);
    
        recv(s, ...);
    
        close(s);
    
    }
    

    file B:

    #include <netmain.h>
    
    #include <stkmain.h>
    
    void findIpInfo()
    
    {
    
        char IPString[50];
        CI_IPNET    NA;
    
        CfgGetImmediate( 0, CFGTAG_IPNET, if_req.index, 1, sizeof(NA), (UINT8 *)&NA);
    
        NtIPN2Str (NA.IPAddr, IPString);
        DbgPrintf(DBG_INFO, "IP Address    : %s\n", IPString);
    
        // etc.
    
    }

    Please refer to the NDK User's Guide for more info

    c:\tirtos_tivac_2_16_01_14\products\ndk_2_25_00_09\docs\spru524j.pdf

    section 3.3.1.1 Things to Remember About BSD Compatibility
    -> File separation

    David Dudley said:
    I've worked it out by adding a bunch of conditional blocks, but that shouldn't be something for me to be doing.

    With the above changes, you should be able to undo this.

    David Dudley said:
    where do I get if_req.index?  I don't see this defined anywhere.

    My bad, what I gave you prior was incomplete. You can get it like this:

    NIMU_IF_REQ if_req;

    memset(&if_req, 0, sizeof(NIMU_IF_REQ));

    NIMUIoctl (NIMU_GET_DEVICE_INDEX, &if_req, &dev_index, sizeof(dev_index);

    See the NDK Telnet console code for more examples of what you're trying to do:

    c:\tirtos_tivac_2_16_01_14\products\ndk_2_25_00_09/ti/ndk/tools/console/conipaddr.c

    David Dudley said:
    I cannot for the life of me, figure how to link in EMACSnow_NIMUInit.  Where is it defined, and how do I include it?

    This function comes from the driver library. Can you add the following code to your project's *.cfg file? Then rebuild all.

    /* ================ TI-RTOS drivers' configuration ================ */
    var driversConfig = xdc.useModule('ti.drivers.Config');
    /*
     * Include TI-RTOS drivers
     *
     * Pick one:
     *  - driversConfig.LibType_NonInstrumented (default)
     *      Use TI-RTOS drivers library optimized for footprint and performance
     *      without asserts or logs.
     *  - driversConfig.LibType_Instrumented
     *      Use TI-RTOS drivers library for debugging with asserts and logs enabled.
     */
    driversConfig.libType = driversConfig.LibType_NonInstrumented;
    //driversConfig.libType = driversConfig.LibType_Instrumented;
    

    Steve

  • Moving down the path....

    I know I've seen this somewhere....  How do I prevent my main program from starting until the DHCP client has received an IP address?

    As I remember, there's a reporting function that you use to tell when it's safe to go?

    Later-

    David

  • Next question....

    Does the CFGImmediate routine support getting CFGITEM_DHCP_DOMAINNAMESERVER in order to get the DNS records that were provided by the DHCP server?

  • David Dudley said:

    I know I've seen this somewhere....  How do I prevent my main program from starting until the DHCP client has received an IP address?

    As I remember, there's a reporting function that you use to tell when it's safe to go?

    Yes, exactly, there's an IP address callback function. It gets called whenever an IP address is added or removed from the system. So that's where you should add code to do what you want, I just want to note the importance of the underlined part. The function takes a parameter, "fAdd" which is a boolean that's true if an IP address was added, false if it is being removed. So, just check that fAdd parameter to know which case is happening.

    Anyway, you can add this to your app by updating your *.cfg file with the following setting:

    Global.networkOpenHook = "&ipAddressHook";

    Then, in C source code (for example, see example file tcpEchoHooks.c in the tcpEcho example app), add a function with the name specified above. From within that function, you can post a globally shared semaphore:

    void ipAddressHook(uint32_t IPAddr, uint32_t IfIdx, uint32_t fAdd)

    {

        if (fAdd) {

            // e.g.

            Semaphore_post(ipAddrSem);

        }

    }

    Then, in your network thread, the first thing to do is to block on the ipAddrSem semaphore. This way, your code won't run until the semaphore is posted from within the IP address hook function:

    void networkAppThread()

    {

        // e.g.

        Semaphore_pend(ipAddrSem);

        // followed by the rest of your networking code

    }

    Steve

  • Is the IPAddr that is passed to this routine the IP address that was issued? It seems to be entirely different from the one that the dhcp client shows was received.
  • So... just can't leave well enough alone.

    I need to implement a SNTP client on this machine, in order to get the correct time.

    Is there any way I can get the IP of the SNTP server that was provided by DHCP?

    It's provided as entry #4, but not sure how to retrieve it, or if I can.

    Later-

    David

    PS: Somehow, the headings on this page got set to only show Chinese.  How do I change them back, or can I?

  • Hi David,

    Yes, the IP address is received from (and issued by) the DHCP server, gets set as the IP address for the embedded device, and then this callback function is called passing the same IP address as an arg.

    I'm guessing you're missing code to handle the byte ordering. See below.

    Steve

    void ipAddressHook(uint32_t IPAddr, uint32_t IfIdx, uint32_t fAdd)
    {
        uint32_t IPTmp;
    
    ...
        /* print the IP address that was added/removed */
        IPTmp = ntohl(IPAddr); // might be NDK_ntohl() if you have newer NDK
        DbgPrintf(DBG_INFO, "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);
    ...
    }
    

  • David Dudley said:

    I need to implement a SNTP client on this machine, in order to get the correct time.

    Is there any way I can get the IP of the SNTP server that was provided by DHCP?

    Can you please open a new thread for this issue?

    Thanks,

    Steve