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.

Statically define IP address of PC in code

Hello,

I am going off the TI-RTOS for TivaC example udpEcho_DK_TM4C129X_GNU_TivaTM4C129XNCZAD

Instead of using recvfrom() to workout what ip address to echo back to, I would like to modify this function so that I only send out information, instead of waiting for a message to echo back.

Therefore, how would I go about defining an IP address within code so that the tiva sends a message to a PC console?

udpEcho.c

/*
 *    ======== udpEcho.c ========
 *    Contains BSD sockets code.
 */

#include <string.h>

#include <xdc/std.h>
#include <xdc/cfg/global.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 UDPPACKETSIZE 256

/*
 *  ======== echoFxn ========
 *  Echoes UDP messages.
 *
 */
Void echoFxn(UArg arg0, UArg arg1)
{
    int                bytesRcvd;
    int                bytesSent;
    int                status;
    int                server;
    fd_set             readSet;
    struct sockaddr_in localAddr;
    struct sockaddr_in clientAddr;
    socklen_t          addrlen;
    char               buffer[UDPPACKETSIZE];

    server = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
    if (server == -1) {
        System_printf("Error: socket not created.\n");
        goto shutdown;
    }

    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");
        goto shutdown;
    }

    do {
        /*
         *  readSet and addrlen are value-result arguments, which must be reset
         *  in between each select() and recvfrom() call
         */
        FD_ZERO(&readSet);
        FD_SET(server, &readSet);
        addrlen = sizeof(clientAddr);

        /* Wait forever for the reply */
        status = select(server + 1, &readSet, NULL, NULL, NULL);
        if (status > 0) {
            if (FD_ISSET(server, &readSet)) {
                bytesRcvd = recvfrom(server, buffer, UDPPACKETSIZE, 0,
                        (struct sockaddr *)&clientAddr, &addrlen);

                if (bytesRcvd > 0) {
                    bytesSent = sendto(server, buffer, bytesRcvd, 0,
                            (struct sockaddr *)&clientAddr, addrlen);
                    if (bytesSent < 0 || bytesSent != bytesRcvd) {
                        System_printf("Error: sendto failed.\n");
                        goto shutdown;
                    }
                }
            }
        }
    } while (status > 0);

shutdown:
    if (server > 0) {
        close(server);
    }
}

/*
 *  ======== main ========
 */
int main(void)
{
    /* Call board init functions */
    Board_initGeneral();
    Board_initGPIO();
    Board_initEMAC();

    /* Turn on user LED */
    GPIO_write(Board_LED0, Board_LED_ON);

    System_printf("Starting the UDP 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);
}

udpEchoHooks.c

/*
 *    ======== udpEchoHooks.c ========
 *    Contains non-BSD sockets code (NDK Network Open Hook)
 */

/* XDCtools Header files */
#include <xdc/std.h>
#include <xdc/cfg/global.h>
#include <xdc/runtime/Error.h>
#include <xdc/runtime/System.h>

/* BIOS Header files */
#include <ti/sysbios/BIOS.h>
#include <ti/sysbios/knl/Task.h>

#define UDPPORT 1000

/* Prototypes */
Void echoFxn(UArg arg0, UArg arg1);

/*
 *  ======== netOpenHook ========
 *  NDK network open hook used to initialize IPv6
 */
void netOpenHook()
{
    Task_Handle taskHandle;
    Task_Params taskParams;
    Error_Block eb;

    /* Make sure Error_Block is initialized */
    Error_init(&eb);

    /*
     *  Create the Task that handles UDP "connections."
     *  arg0 will be the port that this task listens to.
     */
    Task_Params_init(&taskParams);
    taskParams.stackSize = 1024;
    taskParams.priority = 1;
    taskParams.arg0 = UDPPORT;
    taskHandle = Task_create((Task_FuncPtr)echoFxn, &taskParams, &eb);
    if (taskHandle == NULL) {
        System_printf("main: Failed to create udpHandler Task\n");
    }
}

 

  • Hi Terry,

    If you have the IP address of the PC, it should be straight forward. You can create a "struct sockaddr_in" object and initialize it with the IP address and port number of the server running on your PC and then pass the object to the sendto() API.

    struct sockaddr_in serverAddr;
    
    memset(&serverAddr, 0, sizeof(serverAddr));
    serverAddr.sin_family = AF_INET;
    serverAddr.sin_port = htons(PORT_NUMBER);
    inet_pton(AF_INET, "<IP Address in dotted decimal notation>", &(serverAddr.sin_addr));

    ...
    bytesSent = sendto(socketFd, buffer, bufferSize, flags, (struct sockaddr*)&serverAddr, sizeof(serverAddr));
    ...

    Best,

    Ashish

  • Hello Ashish,

    Thank you for the input, an important concept i was missing  is how to define an IP address e.g: 192.168.0.02; I have made the realisation that htonl () takes a hexidecimal form of that ip address where by octets grouping of 2 resemble the decimal form of the ip coordinates. eg. 192 = c0, 168 = A8, 0 = 00,  2 = 02. Therefore using the htonl() function we have:

    localAddr.sin_addr.s_addr = htonl(0xc0a80002);

    this assigns 192.168.0.2 to the localAddr.