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.

MSP-EXP432E401Y: DNSGetHostByName fails with error 19 (cannot open socket)

Part Number: MSP-EXP432E401Y

When calling DNSGetHostByName, the request always fails with error 19 NDK_DNS_ENODNSREPLY. However, when debugging it turns out the socket cannot be opened.

As the network interface is working fine and other socket calls before the DNS request pass without any problems, I exclude a general problem in the network configuration. However, normally I am using
fdOpenSession(TaskSelf()) and fdCloseSession(TaskSelf()) before socket operations.

I have tried to do the same with the DNS request, but this does not work either:

char hn[64], b[512];
sprintf (hn, "cloud.coqon.de");
fdOpenSession(TaskSelf());
int status = DNSGetHostByName(hn, b, sizeof(b));
fdCloseSession(TaskSelf());

I did not have a .cfg file in my project, only .syscfg. So i added a blank cfg file with contents:

var Global = xdc.useModule ('ti.ndk.config.Global');
Global.autoOpenCloseFD = true;

This does not work either and when removing the fd.. functions from the other socket functions, they stop working as well. So the setting is apparently not being applied.

Is there a way to process DNS requests by manually opening and closing the fd or how can I get the autoOpenCloseFD=true working?

Thank you and regards
Peter

  • Hi,

      Did you have the below line to enable the DNS module from the NDK?

    var Dns = xdc.useModule('ti.ndk.config.Dns');

  • Hi Charles,

    I did not have that line but adding it does not have any effect as I think the whole .cfg file is just ignored at all. The reason is that, if Global.autoOpenCloseFD = true; had any effect, I would not need the fdOpen/Close calls for the other socket calls anymore but as I do need them, it seems the setting is not being applied. This is why I have asked what else to do than just adding it to the project with the above contents as I did not have it before in the project (only the .syscfg).

    What happens is that DNSGetHostByName calls DNSResolveExternal which calls socket resolving to NDK_socket:

    /* Create the Socket */
        s = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
        if( s == INVALID_SOCKET )
            goto dnsleave;

    Without fdOpenSession being called before and without Global.autoOpenCloseFD active, the function will report INVALID_SOCKET which DNSGetHostByName  transforms into error 19 NDK_DNS_ENODNSREPLY.

    1. Is there a way to set Global.autoOpenCloseFD within the code or using syscfg?
    2. Alternatively, how do I get the .cfg being applied in a CCS project which did not have that file before?
    3. Why does that not work?
      fdOpenSession(TaskSelf());
      int status = DNSGetHostByName(hn, b, sizeof(b));
      fdCloseSession(TaskSelf());

    Regards
    Peter

  • Hi,

    The reason is that, if Global.autoOpenCloseFD = true; had any effect, I would not need the fdOpen/Close calls for the other socket calls anymore but as I do need them, it seems the setting is not being applied.
    • Is there a way to set Global.autoOpenCloseFD within the code or using syscfg?

    I'm not a TI-RTOS expert but after some searching, I find the below conditions for using autoOpenCloseFD. It says that autoOpenCloseFD is only supported for dynamically-created Tasks created from within a Task context (that is, from within another running Task function). Tasks created statically in the configuration or dynamically in main() or a Hwi or Swi thread do not support this feature. 

    • Alternatively, how do I get the .cfg being applied in a CCS project which did not have that file before?

    If you refer to a MSP432E example project like tcpecho_MSP_EXP432E401Y_tirtos_ccs, you will find that it has a dependency on another project called tirtos_builds_MSP_EXP432E401Y_release_ccs. The tirtos_builds_MSP_EXP432E401Y_release_ccs has the .cfg file. 

  • Great idea, that project does have a cfg file indeed. Only issue now is that it does not find module ti.ndk.config.Global.

    'C:/ti/simplelink_msp432e4_sdk_4_20_00_12/source;C:/ti/simplelink_msp432e4_sdk_4_20_00_12/kernel/tirtos/packages;C:/ti/ccs1230/xdctools_3_62_01_16_core/packages;..;'. Ensure that the package path is set correctly.
        "./package/cfg/release_pem4f.cfg", line 189
    xdctools_3_62_01_16_core\gmake.exe: *** [package.mak:202: package/cfg/release_pem4f.xdl] Error 1
    js: "C:/ti/ccs1230/xdctools_3_62_01_16_core/packages/xdc/tools/Cmdr.xs", line 52: Error: xdc.tools.configuro: configuration failed due to earlier errors (status = 2); 'linker.cmd' deleted.

    In the application project, I have the ndk references under Properties - CCS Build - Arm Linker - File Search Path - Inlcude libraries but the tirots_builds_MSP_EXP432E401Y_release_ccs project does not offer such option. Which is the best way to get that packet supported in that project as well?

  • Hi,

      I'm not an expert in MSP432E SDK. It seems that MSP432E SDK does not have module ti.ndk.config.Global. When I search 'Global' in the Available Products, I do not see the Global module. 

    Unlike TI-RTOS for TM4C129 MCU, I could search for Global and it is there. I'm not sure if you had used TM4C129 in the past and was trying to find the equivalent module for MSP432E. 

    I think the NDK is configured in the syscfg for MSP432E SDK.  If I bring up a MSP432E Ethernet example, I could see NDK and services being selected to support tcpecho application. 

  • Hi Charles,

    NDK is perfectly working with other services indeed and yes, I did set it up via syscfg. There is also "Global", but all that is included on an application level which is why the setting in the tirtos upper project fails as this does not include any of these components.

    My question is related specifically to the DNSGetHostByName-function and the issue described initially. Is there anyone who can provide further assistance on RTOS/NDK?

    Regards
    Peter

  • This is just my guess at the moment. I think DNS is part of the NAT package library which is not in your link library path. Can you add stk_nat.aem4f to your link library and see if that makes a difference. You might only have linked stk.aem4f right now. 

  • Hi Charles,

    I have tried but adding NAT does not help. It also would have been surprising as we are not lacking DNS support but the problem is that the socket function called by DNSGetHostByName returns an error as autoOpenCloseFD is not active and there is no fdOpenSession in the SDK's function code.

    In the documentation of the SNTP package you can find:

     *  Additionally, it is necessary to configure the automatic calling to
     *  fdOpenSession() and fdCloseSession() in an application which uses the SNTP
     *  client. This is accomplished by setting the configuration parameter
     *  "Global.autoOpenCloseFD = true;".
    I suppose it is the same for DNS and so we need autoOpenCloseFD.
    At this point, as adding the parameter to the referenced project's .cfg did not work, I managed to get XDC with .cfg support running for the actual project. The error remains the same, XDC cannot find ti.ndk.config:
    xdc.services.global.XDCException: xdc.PACKAGE_NOT_FOUND: can't locate the package 'ti.ndk.config

    At this point I have had a look at the NDK packages in simplelink_msp432e4_sdk_4_20_00_12 and actually there is no config package under ti/ndk at all! There is such package for the standalone NDK package (ndk_3_61_01_01) which however - as far as I understand - is for Linux only and not for use with TI-RTOS.

    Looking at the code in ndk_3_61_01_01/packages/ti/ndk/config, in Global.xdt you can find:

    /*
     * ======== ti_ndk_config_global_taskCreateHook ========
     * Automatically call fdOpenSession for dynamically created tasks.
     * Requires Global.enableCodeGeneration == true
     */
    Void ti_ndk_config_global_taskCreateHook(ti_sysbios_knl_Task_Handle h)
    {
    %
    % /* must use NDK config with code generation to get this feature */
    % if (this.enableCodeGeneration && Global.autoOpenCloseFD) {
    %
        /* open the file descriptor session automatically */
        if ((ti_sysbios_BIOS_getThreadType() == ti_sysbios_BIOS_ThreadType_Task)
            && (h != ti_sysbios_knl_Task_getIdleTask())) {
            /* open FD table session for the user.  Don't call if idle task */
            fdOpenSession(h);
        }
    %
    % } // end "if(enableCodeGeneration && autoOpenCloseFD) ..."
    %
    }
    
    /*
     * ======== ti_ndk_config_global_taskExitHook ========
     * Automatically call fdCloseSession for dynamically created tasks.
     * Requires Global.enableCodeGeneration == true
     */
    Void ti_ndk_config_global_taskExitHook(ti_sysbios_knl_Task_Handle h)
    {
    %
    % /* must use NDK config with code generation to get this feature */
    % if (this.enableCodeGeneration && Global.autoOpenCloseFD) {
    %
        if (h != ti_sysbios_knl_Task_getIdleTask()) {
            /* close FD table session for the user.  Don't call if idle task */
            fdCloseSession(h);
        }
    %
    % } // end "if(enableCodeGeneration && autoOpenCloseFD) ..."
    %
    }

    This code is supposed to be generated by XDK if
    Global.enableCodeGeneration == true
    and
    lobal.autoOpenCloseFD
    are set.

    As there is no trace of that at all in the simplelink_msp432e4_sdk_4_20_00_12, how is this option supposed to be activated and has anyone ever managed to get autoOpenCloseFD with that SDK???

    Can you now please really involve your RTOS or NDK team to get a solution for this? DNS lookup is a basic function and there is no point having to implement this by hand just because someone forgot to move that from XDC to syscfg.

    Regards
    Peter

  • Hi Peter,

      I believe using fdOpenSession(TaskSelf()) and fdCloseSession(TaskSelf()) before socket operations is required. What I know is that for a different platform such as TM4C129 MCU,  It does not use SimpleLink SDK, but rather TI-RTOS and NDK based on the .cfg file. In this case, you can apply the below statements to automatically call fdOpen/CloseSession for sockets Task.

    var Global    = xdc.useModule('ti.ndk.config.Global');

    /* automatically call fdOpen/CloseSession for our sockets Task */

    Global.autoOpenCloseFD = true;

    The reason that autoOpenCloseFD is offered is because too many people in the past forgot to call fdOpen/CloseSession for their sockets Task. The autoOpenCloseFD is offered to automatically insert fdOpen/CloseSession for you to help alleviate the trouble people were forgetting. The downside is that it is a overkill since it is done for tasks that don't use networking. For SL SDK, they move away from using the .cfg file. As such, all the networking examples in the SL SDKcall fpOpenSession (and all the stack initialization code that the .cfg generates for you in the TI-RTOS product). If you look at a socket example like the tcpecho for both freertos or ti-rtos versions, the fdOpenSession(TaskSelf()) is first called in the task. 

     I understand that  you have tried to call fdOpenSession/CloseSession with DNSGetHostByName and it did not work. With some searching, I find this post that may have some relevance and similarity to your question.

    https://e2e.ti.com/support/microcontrollers/arm-based-microcontrollers-group/arm-based-microcontrollers/f/arm-based-microcontrollers-forum/894296/ccs-tm4c1294ncpdt-function-dnsgethostbyname-solving-wrong-ip?tisearch=e2e-sitesearch&keymatch=dnsgethostbyname#

    In this post getaddrinfo() is suggested instead of DNSGetHostByName. Do you mind to try this as an alternative solution as I don't know why DNSGetHostByName does not work. 

    https://man7.org/linux/man-pages/man3/getaddrinfo.3.html

    I find the below snippet of code using getaddrinfo that is based on TI-RTOS/NDK for TM4C129 MCU. 

    /*
     *  ======== dnsWorker ========
     *  Task to request DNS service
     */
    Void dnsWorker(UArg arg0, UArg arg1)
    {
        struct addrinfo *server_data = NULL;
        int result;
        int i;
    
        for (i=0;i<NUM_HOST;i++)
        {
            System_printf("!!!!!!!!!!\n", result);
            System_flush();
    
            /*
             * Given the host name, which identify a Internet host, getaddrinfo
             * returns one or more addrinfo structure, each of which contains
             * an Internet address that can be specified in a call to bind or
             * connect
             */
            result = getaddrinfo(hostname[i], "0", NULL, &server_data);
    
            if (result == 0 && server_data != NULL)
            {
                struct sockaddr addr = *(server_data->ai_addr);
                /*
                 * convert IP address structure to string format
                 */
                inet_ntop(AF_INET, &((struct sockaddr_in *)&addr)->sin_addr, strIp, INET_ADDRSTRLEN);
                System_printf("HOSTNAME: %s\tResolved address:%s\n", hostname[i],strIp);
                System_flush();
    
                freeaddrinfo(server_data);
                server_data = NULL;
            }
    
            Task_sleep(1000); // Sleep for 1 seconds
        }
    }

  • Hi Charles,

    getaddrinfo resolves to SlNetUtil_getAddrInfo. I can confirm that it works perfectly well as well as also SlNetUtil_getHostByName. Apparently the solution is focusing on SLNET instead of NDK.

    It could save a lot of time updating you guides accordingly discouraging the use of NDK and removing functions which are actually not supported anymore at all (at least by the MSP432 SDK) such as autoOpenCloseFD.

    Thank you and regards
    Peter