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.

TM4C1294NCPDT: run time static ip is not changing on ti-rtos

Part Number: TM4C1294NCPDT

Hello ,

I am working on a project using Tiva, TM4C1294NCPDT MCU ON TIRTOS environment and uses NDK module for TCP client application. My application use static ip connection and I am enter this address in to .cfg file. tcp-echo application is works fine with any ip address entered on .cfg files.

But I want to change ip to be enter in run time. I am already done with following which was posted on one of your portal and tried but it is not connected with new ip. .

  1. use the NDK hook "Network open hook" instead of "Stack begin hook" for 'readIPAddr()'
  2. find and remove the static IP address that's initially added (unbind it from the interface)
  3. add the new IP address (bind a new one)

Here's the updated code I used to do this (covers steps 2 + 3 above).  You can change it to read and use the IP address in ROM:


    CI_IPNET NA;
    HANDLE      hCfgIpAddr;

    /* Setup manual IP address */
    bzero(&NA, sizeof(NA));
    NA.IPAddr  = inet_addr("172.16.10.2");
    NA.IPMask  = inet_addr("255.255.255.0");
    strcpy(NA.Domain, "demo.net");
    NA.NetType = 0;

    /* get the current static IP entry */
    CfgGetEntry(0, CFGTAG_IPNET, 1, 1, &hCfgIpAddr);

    /* remove the current static IP entry */
    CfgRemoveEntry(0, hCfgIpAddr);

    /* add a new static IP entry */
    CfgAddEntry(0, CFGTAG_IPNET, 1, 0,
            sizeof(CI_IPNET), (UINT8 *)&NA, 0);

I have added above routine on netOpenHook function(tcp-eco sample code) which is already Network open hook function.

On console following is displayed where 172.16.10.1 is .cfg ip address and 172.16.10.2 is new ip.

Network Added: If-1:172.16.10.1

Network Removed: If-1:172.16.10.1

Network Added: If-1:172.16.10.2

Strange behavior is this new ip is getting ping on cmd prompt but when is connected to hyper terminal is it not connected. The accept function is not return the connection. Why is it so? When this above routin is comment form netOpenHook function , it is connected to .cfg ip address(i.e 172.16.10.1)

  • Hi Anushka,

    I want to clarify some things. Your target device has an IP that you manually assign in the .cfg file. You want to assign a different static IP address at run-time.

    1. What do you mean by "when is connected to hyper terminal it is not connected"? Are you using hyper terminal to run the tcpSendReceive application?
    2. Which accept call is failing? Is it the call inside tcpHandler in tcpEcho.c?
      1. If so, when using the *.cfg static IP address, are you saying that your tcpHandler accept call succeeds and you can successfully echo messages back and forth between your PC and the target?

    Best,
    Brandon

  • 1) What do you mean by "when is connected to hyper terminal it is not connected"? Are you using hyper terminal to run the tcpSendReceive application?

    yes we are using hyper terminal as tcpsendreceiver application. the connection is not establish between client and server when ip is changed at run time. 

    2) Which accept call is failing? Is it the call inside tcpHandler in tcpEcho.c

    yes tcpHandler in tcpecho.c. 

    whenever try to connect with new ip this accept function is accept the connection and return the connection id as clientfd . this will not return anything whenever ip is changed in run time. 

    i have attached tcpEcho.c and tcpechohooks.c files. i just want to change ip at run time. my application is used static client base application where as pc is server.(as we are connected to hyper terminal). 

    /*
     * Copyright (c) 2014-2015, Texas Instruments Incorporated
     * All rights reserved.
     *
     * Redistribution and use in source and binary forms, with or without
     * modification, are permitted provided that the following conditions
     * are met:
     *
     * *  Redistributions of source code must retain the above copyright
     *    notice, this list of conditions and the following disclaimer.
     *
     * *  Redistributions in binary form must reproduce the above copyright
     *    notice, this list of conditions and the following disclaimer in the
     *    documentation and/or other materials provided with the distribution.
     *
     * *  Neither the name of Texas Instruments Incorporated nor the names of
     *    its contributors may be used to endorse or promote products derived
     *    from this software without specific prior written permission.
     *
     * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
     * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
     * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
     * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
     * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
     * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
     * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
     * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
     * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
     * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
     * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     */
    
    /*
     *    ======== tcpEcho.c ========
     *    Contains BSD sockets code.
     */
    
    #include <string.h>
    
    #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/drivers/GPIO.h>
    
    /* NDK BSD support */
    #include <sys/socket.h>
    
    /* Example/Board Header file */
    #include "Board.h"
    
    #define TCPPACKETSIZE 256
    #define NUMTCPWORKERS 3
    
    /*
     *  ======== tcpWorker ========
     *  Task to handle TCP connection. Can be multiple Tasks running
     *  this function.
     */
    Void tcpWorker(UArg arg0, UArg arg1)
    {
        int  clientfd = (int)arg0;
        int  bytesRcvd;
        int  bytesSent;
        char buffer[TCPPACKETSIZE];
    
        System_printf("tcpWorker: start clientfd = 0x%x\n", clientfd);
        System_flush();
        while ((bytesRcvd = recv(clientfd, buffer, TCPPACKETSIZE, 0)) > 0) {
            bytesSent = send(clientfd, buffer, bytesRcvd, 0);
            if (bytesSent < 0 || bytesSent != bytesRcvd) {
                System_printf("Error: send failed.\n");
                break;
            }
        }
        System_printf("tcpWorker stop clientfd = 0x%x\n", clientfd);
        System_flush();
        close(clientfd);
    }
    
    /*
     *  ======== tcpHandler ========
     *  Creates new Task to handle new TCP connections.
     */
    Void tcpHandler(UArg arg0, UArg arg1)
    {
        int                status;
        int                clientfd;
        int                server;
        struct sockaddr_in localAddr;
        struct sockaddr_in clientAddr;
        int                optval;
        int                optlen = sizeof(optval);
        socklen_t          addrlen = sizeof(clientAddr);
        Task_Handle        taskHandle;
        Task_Params        taskParams;
        Error_Block        eb;
    
        server = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
        if (server == -1) {
            System_printf("Error: socket not created.\n");
            System_flush();
            goto shutdown;
        }
    
    #if 0
        memset(&localAddr, 0, sizeof(localAddr));
        localAddr.sin_family = AF_INET;
        localAddr.sin_addr.s_addr = htonl(INADDR_ANY)
        localAddr.sin_port = htons(arg0);
    #endif
        memset(&localAddr, 0, sizeof(localAddr));
        localAddr.sin_family = AF_INET;
        localAddr.sin_addr.s_addr = htonl(INADDR_ANY);
        localAddr.sin_port = htons(arg0);
    
    
        status = bind(server, (struct sockaddr *)&localAddr, sizeof(localAddr));
        if (status == -1) {
            System_printf("Error: bind failed.\n");
            System_flush();
            goto shutdown;
        }
    
        status = listen(server, NUMTCPWORKERS);
        if (status == -1) {
            System_printf("Error: listen failed.\n");
            System_flush();
            goto shutdown;
        }
    
        optval = 1;
        if (setsockopt(server, SOL_SOCKET, SO_KEEPALIVE, &optval, optlen) < 0) {
            System_printf("Error: setsockopt failed\n");
            System_flush();
            goto shutdown;
        }
    
        while ((clientfd = accept(server, (struct sockaddr *)&clientAddr, &addrlen)) != -1)// this will not return anything when ip is going to change in run time
        {
    
            System_printf("tcpHandler: Creating thread clientfd = %d\n", clientfd);
            System_flush();
            /* Init the Error_Block */
            Error_init(&eb);
    
            /* Initialize the defaults and set the parameters. */
            Task_Params_init(&taskParams);
            taskParams.arg0 = (UArg)clientfd;
            taskParams.stackSize = 1280;
            taskHandle = Task_create((Task_FuncPtr)tcpWorker, &taskParams, &eb);
            if (taskHandle == NULL) {
                System_printf("Error: Failed to create new Task\n");
                System_flush();
                close(clientfd);
            }
    
            /* addrlen is a value-result param, must reset for next accept call */
            addrlen = sizeof(clientAddr);
            goto a;
        }
    
        System_printf("Error: accept failed.\n");
        System_flush();
    
    shutdown:
        if (server > 0)
        {
            close(server);
        }
    }
    
    /*
     *  ======== main ========
     */
    int main(void)
    {
        /* Call board init functions */
        Board_initGeneral();
        Board_initGPIO();
        Board_initEMAC();
    
        System_printf("Starting the TCP Echo example\nSystem provider is set to "
                      "SysMin. Halt the target to view any SysMin contents in"
                      " ROV.\n");
        /* SysMin will only print to the console when you call flush or exit */
        System_flush();
    
        /* Start BIOS */
        BIOS_start();
    
        return (0);
    }
    

    /*
     * Copyright (c) 2015, Texas Instruments Incorporated
     * All rights reserved.
     *
     * Redistribution and use in source and binary forms, with or without
     * modification, are permitted provided that the following conditions
     * are met:
     *
     * *  Redistributions of source code must retain the above copyright
     *    notice, this list of conditions and the following disclaimer.
     *
     * *  Redistributions in binary form must reproduce the above copyright
     *    notice, this list of conditions and the following disclaimer in the
     *    documentation and/or other materials provided with the distribution.
     *
     * *  Neither the name of Texas Instruments Incorporated nor the names of
     *    its contributors may be used to endorse or promote products derived
     *    from this software without specific prior written permission.
     *
     * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
     * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
     * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
     * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
     * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
     * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
     * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
     * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
     * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
     * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
     * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     */
    
    /*
     *    ======== tcpEchoHooks.c ========
     *    Contains non-BSD sockets code (NDK Network Open Hook)
     */
    
    /* XDCtools Header files */
    #include <xdc/std.h>
    #include <xdc/runtime/Error.h>
    #include <xdc/runtime/System.h>
    
    #include <netmain.h>
    #include <stacksys.h>
    #include <_netctrl.h>
    #include <_nettool.h>
    #include <_oskern.h>
    #include <_stack.h>
    #include <serrno.h>
    #include <socket.h>
    #include <stkmain.h>
    #include <usertype.h>
    /* BIOS Header files */
    #include <ti/sysbios/BIOS.h>
    #include <ti/sysbios/knl/Task.h>
    
    #define TCPPORT 502
    
    #define TCPHANDLERSTACK 1024
    
    /* Prototypes */
    Void tcpHandler(UArg arg0, UArg arg1);
    
    /*
     *  ======== netOpenHook ========
     *  NDK network open hook used to initialize IPv6
     */
    extern char *LocalIPAddr;
    extern char *LocalIPMask;
    extern char *GatewayIP;
    
    void netOpenHook()
    {
    #if 1
        Task_Handle taskHandle;
        Task_Params taskParams;
        Error_Block eb;
    
        /* Make sure Error_Block is initialized */
        Error_init(&eb);
    #endif
    
    #if 0 //when comment this part the .cfg ip(  i.e 172.16.10.1) is connected properly  but when try to change ip the
        CI_IPNET NA;
    
        HANDLE      hCfgIpAddr;
    
        /* Setup manual IP address */
        bzero(&NA, sizeof(NA));
        NA.IPAddr  = inet_addr("172.16.10.2");
        NA.IPMask  = inet_addr("255.255.255.0");
        strcpy(NA.Domain, "demo.net");
        NA.NetType = 0;
    
        /* get the current static IP entry */
        CfgGetEntry(0, CFGTAG_IPNET, 1, 1, &hCfgIpAddr);
    
        /* remove the current static IP entry */
        CfgRemoveEntry(0, hCfgIpAddr);
    
        /* add a new static IP entry */
        CfgAddEntry(0, CFGTAG_IPNET, 1, 0,
                sizeof(CI_IPNET), (UINT8 *)&NA, 0);
    #endif
    
        /*
         *  Create the Task that farms out incoming TCP connections.
         *  arg0 will be the port that this task listens to.
         */
    #if 1
        Task_Params_init(&taskParams);
        taskParams.stackSize = TCPHANDLERSTACK;
        taskParams.priority = 1;
        taskParams.arg0 = TCPPORT;
        taskHandle = Task_create((Task_FuncPtr)tcpHandler, &taskParams, &eb);
        if (taskHandle == NULL)
        {
            System_printf("netOpenHook: Failed to create tcpHandler Task\n");
        }
    
        System_flush();
    #endif
    
    }
    
    #if 0
    void FnStackThreadHook(void)
    {
        LocalIPAddr = "172.16.10.1";
        LocalIPMask = "255.255.255.0";
        GatewayIP = "192.168.0.1";
    }
    #endif
    

  • Hi Anushka,

    Thanks for providing your code. Have you tried using other IP addresses at run-time?

    I do not run into any issues as long as I choose an IP that is within my network. i.e. 192.x.x.x works for me, while 172.x.x.x does not.
    You may want to check your network configuration to see what IP addresses fall within your network.

    What is odd is that you said you can ping the IP after assigning it to the device at run-time, but you cannot echo messages back and forth. The next step would be to start debugging from the accept call to see precisely where the program is failing.

    Brandon