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.

AM3359: NIMU_ICSS issue

Part Number: AM3359

Hello,

because of an unknown issue with the "NIMU_BasicExample" (see ) I tried the same code (Source and Header Files) with the "NIMU_ICSS_BasicExample".

Here the situation is a bit different. Interestingly , the mentioned exception doesn't appear when I call connect().
But, now I get (6) as return value which says this is Error ENXIO. Referring to the Guide it says that I have to declare a special SocketOption, but I use StreamSocket Communication where this option should not be necessary. This is the result, when I create the respective task with a priority of "5".
Another very interesting thing is, that when I create the task with priority "4", then I don't get this return value. Additionally, I can't see any console information (system_printf is not activ?!).
However, the communication works with priority "4" and for me it would be interesting why?!

If I call the "TcpEchoServer" I get again this strange exception (as in the above mentioned post), when I come to the accept() in line 105.
This is also a bit confusing for me.

I will add the current source and main file for investigation.

main_a8.c
/*
 * Copyright (C) 2012 Texas Instruments Incorporated - http://www.ti.com/
 * 
 * 
 *  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.
 *
*/

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <debug.h>

#include <xdc/std.h>
#include <xdc/runtime/Error.h>
#include <xdc/runtime/System.h>
#include <xdc/runtime/knl/Cache.h>
#include <xdc/runtime/Types.h>
#include <xdc/runtime/Timestamp.h>

#include <ti/sysbios/BIOS.h>
#include <ti/sysbios/knl/Task.h>
#include <ti/sysbios/hal/Hwi.h>
#include <ti/sysbios/hal/Core.h>

#include <ti/ndk/inc/netmain.h>
#include <ti/ndk/inc/stkmain.h>

#include <ti/drv/pruss/soc/pruicss_v1.h>

#include <ti/drv/icss_emac/icss_emacDrv.h>

#include <ti/drv/uart/UART.h>
#include <ti/drv/uart/UART_stdio.h>
#include <ti/drv/icss_emac/test/src/tiemac_pruss_intc_mapping.h>

#include <ti/drv/icss_emac/firmware/am335x/icss_emac_pru0_bin.h>
#include <ti/drv/icss_emac/firmware/am335x/icss_emac_pru1_bin.h>

#include <ti/transport/ndk/nimu_icss/nimu_icssEth.h>
#include <ti/transport/ndk/nimu_icss/example/src/osdrv_ndkdeviceconfig.h>

#include <ti/board/board.h>
#include <ti/starterware/include/board.h>
#include <ti/starterware/include/am335x/chipdb_defs.h>
#include <ti/starterware/include/hw/soc_am335x.h>

// Includes for socket communication
#include "Socket.h"

#define PRU0_FIRMWARE_NAME  PRU0_FIRMWARE        // name of the C struct in PRU header file
#define PRU1_FIRMWARE_NAME    PRU1_FIRMWARE        // name of the C struct in PRU header file

PRUICSS_Handle pruIcssHandle;
ICSS_EmacHandle emachandle;
ICSS_EmacHandle emachandle1;

ICSS_EmacInitConfig* switchEmacCfg;
ICSS_EmacInitConfig* switchEmacCfg1;

uint8_t lclMac[6];
uint8_t lclMac1[6];

/************************************************************************/
/* 						constructors									*/
/************************************************************************/
void SOCCtrlGetPortMacAddr(uint32_t portNum, uint8_t *pMacAddr);
uint8_t ICSSEmacDRVInit(ICSS_EmacHandle handle, uint8_t instance);
extern ICSS_EmacBaseAddrCfgParams icss_EmacBaseAddrCfgParams[3];
void TaskSocketServer (UArg a0, UArg a1);
void TaskSocketClient (UArg a0, UArg a1);
/************************************************************************/
/* function definitions													*/
/************************************************************************/

/*
 * ======== stackInitHook ========
 * hook called from ti_nkd_config_Global_stackThread() to run user setup code
 */
void stackInitHook(HANDLE hCfg)
{
    CI_IPNET NA;
    CI_ROUTE RT;

    /* Static IP Address settings for interface 1 */
    char *ipAddr      = "192.168.2.3";
    char *ipMask      = "255.255.255.0";
    char *ipGateway   = "192.168.2.1";

    /* Add IP address for interface 1 */
    NA.IPAddr = inet_addr(ipAddr);
    NA.IPMask = inet_addr(ipMask);
    CfgAddEntry(hCfg, CFGTAG_IPNET, 1, 0, sizeof(CI_IPNET),
            (UINT8 *)&NA, 0 );

    /*
     * Add gateway for interface 1
     * --> I *think* the below should work but you may need different values ...
     */
    bzero(&RT, sizeof(RT));
    RT.IPDestAddr = 0;
    RT.IPDestMask = 0;
    RT.IPGateAddr = inet_addr(ipGateway);

    CfgAddEntry(hCfg, CFGTAG_ROUTE, 0, 0,
            sizeof(CI_ROUTE), (UINT8 *)&RT, 0);

}

/* PRUICSS objects */
PRUICSS_V1_Object prussObjects[2];

/*
 *	---task to initialize PRU---
 */
Void taskPruss(UArg a0, UArg a1)
{
	Uint8 firmwareLoad_done = FALSE;
    Uint8 count = 0;
    static Uint8 pktReceived = 0;
	while(GetNdkStatus(0)== NIMU_STAT_PROGRESS || GetNdkStatus(0)==NIMU_STAT_UNKNOWN)
	{
		Task_sleep(100);
	}


	PRUICSS_pruDisable(pruIcssHandle, ICSS_EMAC_PORT_1-1);
	PRUICSS_pruDisable(pruIcssHandle, ICSS_EMAC_PORT_2-1);
	if(PRUICSS_pruWriteMemory(pruIcssHandle,PRU_ICSS_IRAM(0) ,0,
						  (uint32_t *) PRU0_FIRMWARE_NAME,
						  sizeof(PRU0_FIRMWARE_NAME)))
	{
		if(PRUICSS_pruWriteMemory(pruIcssHandle,PRU_ICSS_IRAM(1) ,0,
							  (uint32_t *) PRU1_FIRMWARE_NAME,
							  sizeof(PRU1_FIRMWARE_NAME)))
		{
            firmwareLoad_done = TRUE;
		}
	}

    if( firmwareLoad_done)
    {
        PRUICSS_pruEnable(pruIcssHandle, ICSS_EMAC_PORT_1-1);
        PRUICSS_pruEnable(pruIcssHandle, ICSS_EMAC_PORT_2-1);
    }
}

/*
 *  ======== main ========
 */
int main()
{ 
    Error_Block eb;
    Task_Params taskParams;
    int32_t ret;
    PRUICSS_Config  *pruIcssCfg;
    Error_init(&eb);
    
    Board_initCfg cfg = BOARD_INIT_PLL| BOARD_INIT_MODULE_CLOCK |  BOARD_INIT_DDR | BOARD_INIT_ICSS_PINMUX | BOARD_INIT_UART_STDIO | BOARD_INIT_ICSS_ETH_PHY;
    ret = Board_init(cfg);
    if (ret != BOARD_SOK)
    {
        UART_printf("main: Board_init returned error code: %d\n", ret);
        return -2;
    }
    ret  = PRUICSS_socGetInitCfg(&pruIcssCfg);
    if (ret  != PRUICSS_RETURN_SUCCESS)
        return (ret);
    pruIcssHandle = PRUICSS_create((PRUICSS_Config*) pruIcssCfg,PRUICCSS_INSTANCE_ONE);

    Task_Params_init(&taskParams);
    taskParams.priority = 15;
    taskParams.instance->name = "SwitchTask";
    Task_create(taskPruss, &taskParams, &eb);

	/*Port I initializations*/
	emachandle = (ICSS_EmacHandle)malloc(sizeof(ICSS_EmacConfig));

	switchEmacCfg = (ICSS_EmacInitConfig*)malloc(sizeof(ICSS_EmacInitConfig));

    if ((emachandle == NULL) || (switchEmacCfg == NULL))
    {
        UART_printf("main: malloc returned null\n");
    }
    switchEmacCfg->phyAddr[0]=BOARD_ICSS_EMAC_PORT0_PHY_ADDR;
    switchEmacCfg->portMask = ICSS_EMAC_MODE_MAC1;
	switchEmacCfg->ethPrioQueue = ICSS_EMAC_QUEUE1;



    switchEmacCfg->halfDuplexEnable = 1;
	switchEmacCfg->enableIntrPacing = ICSS_EMAC_ENABLE_PACING;
	switchEmacCfg->ICSS_EmacIntrPacingMode = ICSS_EMAC_INTR_PACING_MODE1;
	switchEmacCfg->pacingThreshold = 100;
	switchEmacCfg->learningEn = 0;
    switchEmacCfg->rxIntNum = 20;
    switchEmacCfg->linkIntNum=26;
	SOCCtrlGetPortMacAddr(1,lclMac);
	switchEmacCfg->macId = lclMac;

	ICSSEmacDRVInit(emachandle, 0); 	// ICSS_M instance 0




	((ICSS_EmacObject*)emachandle->object)->pruIcssHandle = pruIcssHandle;
	((ICSS_EmacObject*)emachandle->object)->emacInitcfg = switchEmacCfg;


    /*PORT2 Initializations*/
	emachandle1 = (ICSS_EmacHandle)malloc(sizeof(ICSS_EmacConfig));

    switchEmacCfg1 = (ICSS_EmacInitConfig*)malloc(sizeof(ICSS_EmacInitConfig));

    if ((emachandle1 == NULL) || (switchEmacCfg1 == NULL))
    {
        UART_printf("main: malloc returned null\n");
    }

    switchEmacCfg1->phyAddr[0]= BOARD_ICSS_EMAC_PORT1_PHY_ADDR;
    switchEmacCfg1->portMask = ICSS_EMAC_MODE_MAC2;
    switchEmacCfg1->ethPrioQueue = ICSS_EMAC_QUEUE3;
    switchEmacCfg1->halfDuplexEnable = 1;
    switchEmacCfg1->enableIntrPacing = ICSS_EMAC_DISABLE_PACING;
    switchEmacCfg1->pacingThreshold = 100;

    switchEmacCfg1->learningEn = 0;
    switchEmacCfg1->rxIntNum = 21;
    switchEmacCfg1->linkIntNum=27;


	SOCCtrlGetPortMacAddr(2,lclMac1);
	switchEmacCfg1->macId = lclMac1;

	ICSSEmacDRVInit(emachandle1,0); 	// ICSS_M instance 0

	((ICSS_EmacObject*)emachandle1->object)->pruIcssHandle = pruIcssHandle;
	((ICSS_EmacObject*)emachandle1->object)->emacInitcfg = switchEmacCfg1;

	PRUICSS_IntcInitData pruss_intc_initdata = PRUSS_INTC_INITDATA;
	ICSS_EmacInit(emachandle,&pruss_intc_initdata,ICSS_EMAC_MODE_MAC1|ICSS_EMAC_MODE_DUALMAC);
	ICSS_EmacInit(emachandle1,&pruss_intc_initdata,ICSS_EMAC_MODE_MAC2|ICSS_EMAC_MODE_DUALMAC);




    	Task_Params_init(&taskParams);
    	taskParams.priority = 10;
    	taskParams.instance->name = (char*)"port0_rxTaskFnc";
    	taskParams.stackSize = 0x1000;
    	taskParams.arg0 = (UArg)emachandle;

    	((ICSS_EmacObject*)emachandle->object)->rxTaskHandle = Task_create(ICSS_EMacOsRxTaskFnc, &taskParams, NULL);


    if(((ICSS_EmacObject*)emachandle->object)->rxTaskHandle==NULL)
    {
        UART_printf("main: Task_create rturned NULL handle\n");
        return -2;
    }

    Task_Params_init(&taskParams);
    taskParams.priority = 10;
    taskParams.instance->name = (char*)"port0_linkTaskFnc";
    taskParams.stackSize = 0x1000;
    taskParams.arg0 = (UArg)emachandle;
    ((ICSS_EmacObject*)emachandle->object)->linkTaskHandle = Task_create((ti_sysbios_knl_Task_FuncPtr)ICSS_EMacOsLinkTaskFnc, &taskParams, NULL);
    if(((ICSS_EmacObject*)emachandle->object)->linkTaskHandle==NULL)
    {
        UART_printf("main: Task_create rturned NULL handle\n");
        return -2;
    }

    Task_Params_init(&taskParams);
    taskParams.priority = 10;
    taskParams.instance->name = (char*)"port1_rxTaskFnc";
    taskParams.stackSize = 0x1000;
    taskParams.arg0 = (UArg)emachandle1;
    ((ICSS_EmacObject*)emachandle1->object)->rxTaskHandle = Task_create(ICSS_EMacOsRxTaskFnc, &taskParams, NULL);
    if(((ICSS_EmacObject*)emachandle1->object)->rxTaskHandle==NULL)
    {
        UART_printf("main: Task_create rturned NULL handle\n");
        return -2;
    }

    Task_Params_init(&taskParams);
    taskParams.priority = 10;
    taskParams.instance->name = (char*)"port1_linkTaskFnc";
    taskParams.stackSize = 0x1000;
    taskParams.arg0 = (UArg)emachandle1;
    ((ICSS_EmacObject*)emachandle1->object)->linkTaskHandle = Task_create((ti_sysbios_knl_Task_FuncPtr)ICSS_EMacOsLinkTaskFnc, &taskParams, NULL);
    if(((ICSS_EmacObject*)emachandle1->object)->linkTaskHandle==NULL)
    {
        UART_printf("main: Task_create rturned NULL handle\n");
        return -2;
    }

    if(OSDRV_addNetifEntry((NIMUInitFn)&EmacInit,emachandle) == 0)
        BIOS_exit(0);
    if(OSDRV_addNetifEntry((NIMUInitFn)&EmacInit,emachandle1) == 0)
            BIOS_exit(0);
/*
    // TaskSocketServer
    // Create a Task with priority 5;
    // Task priority must be within the configured range of NDK priorities
    // and lower priority than kernel priority NDK tasks
    //
    Task_Handle hMyTaskServer;
    Error_init(&eb);


    Task_Params_init(&taskParams);
    taskParams.priority = 5;
    taskParams.instance->name = (char*)"TCP_Socket_Server";
    taskParams.stackSize = 4096;

    hMyTaskServer = Task_create (TaskSocketServer , &taskParams, &eb);
    if (hMyTaskServer == NULL) {
    	UART_printf("main: Task_create TaskSocketServer failed\n");
    }
*/

    // TaskSockerClient
    // Create a Task with priority 5;
    // Task priority must be within the configured range of NDK priorities
    // and lower priority than kernel priority NDK tasks
    //
    Task_Handle hMyTaskClient;
    Error_init(&eb);

    Task_Params_init(&taskParams);
	taskParams.priority = 4;
    taskParams.stackSize = 4096;
    taskParams.instance->name = (char*)"TCP_Socket_Client";
    hMyTaskClient = Task_create (TaskSocketClient , &taskParams, &eb);

    if (hMyTaskClient == NULL) {
    	UART_printf("main: Task_create TaskSocketClient failed\n");
    }

    System_printf("\n<<< Starting BIOS >>>\n");
    BIOS_start();
    return(0);
}


#define CONTROL_MAC_ID_LO(n)   (0x630 + (n * 8))
#define CONTROL_MAC_ID_HI(n)   (0x634 + (n * 8))
void SOCCtrlGetPortMacAddr(uint32_t portNum, uint8_t *pMacAddr)
{
    uint32_t slavePortNum = portNum - 1U;

    pMacAddr[5U] =  (HW_RD_REG32(SOC_CONTROL_REGS + CONTROL_MAC_ID_LO(slavePortNum))
                   >> 8U) & 0xFFU;
    pMacAddr[4U] =  (HW_RD_REG32(SOC_CONTROL_REGS + CONTROL_MAC_ID_LO(slavePortNum)))
                  & 0xFF;
    pMacAddr[3U] =  (HW_RD_REG32(SOC_CONTROL_REGS + CONTROL_MAC_ID_HI(slavePortNum))
                   >> 24U) & 0xFFU;
    pMacAddr[2U] =  (HW_RD_REG32(SOC_CONTROL_REGS + CONTROL_MAC_ID_HI(slavePortNum))
                   >> 16U) & 0xFFU;
    pMacAddr[1U] =  (HW_RD_REG32(SOC_CONTROL_REGS + CONTROL_MAC_ID_HI(slavePortNum))
                   >> 8U) & 0xFFU;
    pMacAddr[0U] =  (HW_RD_REG32(SOC_CONTROL_REGS + CONTROL_MAC_ID_HI(slavePortNum)))
                  & 0xFFU;
}



uint8_t ICSSEmacDRVInit(ICSS_EmacHandle handle, uint8_t instance) {
	/* LLD attributes mallocs */
	handle->object = (ICSS_EmacObject*)malloc(sizeof(ICSS_EmacObject));
	handle->hwAttrs= (ICSS_EmacHwAttrs*)malloc(sizeof(ICSS_EmacHwAttrs));

	/* Callback mallocs */
	ICSS_EmacCallBackObject* callBackObj = (ICSS_EmacCallBackObject*)malloc(sizeof(ICSS_EmacCallBackObject));

	callBackObj->learningExCallBack=(ICSS_EmacCallBackConfig*)malloc(sizeof(ICSS_EmacCallBackConfig));
	callBackObj->rxRTCallBack=(ICSS_EmacCallBackConfig*)malloc(sizeof(ICSS_EmacCallBackConfig));
    callBackObj->rxCallBack=(ICSS_EmacCallBackConfig*)malloc(sizeof(ICSS_EmacCallBackConfig));
    callBackObj->txCallBack=(ICSS_EmacCallBackConfig*)malloc(sizeof(ICSS_EmacCallBackConfig));
	((ICSS_EmacObject*)handle->object)->callBackHandle = callBackObj;

	/*Allocate memory for learning*/
	((ICSS_EmacObject*)handle->object)->macTablePtr = (HashTable_t*)malloc(NUM_PORTS * sizeof(HashTable_t));

	/*Allocate memory for PRU Statistics*/
	((ICSS_EmacObject*)handle->object)->pruStat = (ICSS_EmacPruStatistics_t*)malloc(NUM_PORTS * sizeof(ICSS_EmacPruStatistics_t));

	/*Allocate memory for Host Statistics*/
	((ICSS_EmacObject*)handle->object)->hostStat = (ICSS_EmacHostStatistics_t*)malloc(NUM_PORTS * sizeof(ICSS_EmacHostStatistics_t));

	/*Allocate memory for Storm Prevention*/
	((ICSS_EmacObject*)handle->object)->stormPrevPtr = (stormPrevention_t*)malloc(NUM_PORTS * sizeof(stormPrevention_t));

	/* Base address initialization */
	if(NULL == ((ICSS_EmacHwAttrs*)handle->hwAttrs)->emacBaseAddrCfg) {
		((ICSS_EmacHwAttrs*)handle->hwAttrs)->emacBaseAddrCfg =
						(ICSS_EmacBaseAddressHandle_T)malloc(sizeof(ICSS_EmacBaseAddrCfgParams));
	}
	ICSS_EmacBaseAddressHandle_T emacBaseAddr = ((ICSS_EmacHwAttrs*)handle->hwAttrs)->emacBaseAddrCfg;

        emacBaseAddr->dataRam0BaseAddr = icss_EmacBaseAddrCfgParams[instance].dataRam0BaseAddr;
        emacBaseAddr->dataRam1BaseAddr = icss_EmacBaseAddrCfgParams[instance].dataRam1BaseAddr;

        /*      Restricting l3OcmcBaseAddr to 0x40xxxx00.
         *  This is done because L3 OCMC Base Address must be 256 byte aligned and to support OCMC memory usage for Linux Power Management.
         */
        emacBaseAddr->l3OcmcBaseAddr =  (((icss_EmacBaseAddrCfgParams[instance].l3OcmcBaseAddr)&0xFFFF00)|0x40000000);
        emacBaseAddr->prussCfgRegs =  icss_EmacBaseAddrCfgParams[instance].prussCfgRegs;
        emacBaseAddr->prussIepRegs =  icss_EmacBaseAddrCfgParams[instance].prussIepRegs;
        emacBaseAddr->prussIntcRegs = icss_EmacBaseAddrCfgParams[instance].prussIntcRegs;
        emacBaseAddr->prussMiiMdioRegs = icss_EmacBaseAddrCfgParams[instance].prussMiiMdioRegs;
        emacBaseAddr->prussMiiRtCfgRegsBaseAddr = icss_EmacBaseAddrCfgParams[instance].prussMiiRtCfgRegsBaseAddr;
        emacBaseAddr->prussPru0CtrlRegs = icss_EmacBaseAddrCfgParams[instance].prussPru0CtrlRegs;
        emacBaseAddr->prussPru1CtrlRegs = icss_EmacBaseAddrCfgParams[instance].prussPru1CtrlRegs;
        emacBaseAddr->sharedDataRamBaseAddr = icss_EmacBaseAddrCfgParams[instance].sharedDataRamBaseAddr;
        return 0;
}

/**
 *  \name TaskSocketServer
 *  \Task to call the socket function in SocketServer.c
 *  \param a0
 *  \param a1
 *  \return none
 *
 */
void TaskSocketServer (UArg a0, UArg a1)
{
    System_printf("<< enter TaskSocketServer() >>\n");

	// define IP-Addr.
    IPN IPAddrExt;
    IPN IPAddrLocal;
    IPAddrExt = inet_addr("192.168.1.10"); 		//PC
    IPAddrLocal = inet_addr("192.168.1.4"); 	//ICEV2 board

    // call function
    EchoTcpServer(IPAddrLocal, IPAddrExt);

    System_printf("<< closing TaskSocketServer() >>\n");
    Task_exit();
}

/**
 *  \name TaskSocketClient
 *  \Task to call the socket function in SocketClient.c
 *  \param a0
 *  \param a1
 *  \return none
 *
 */
void TaskSocketClient (UArg a0, UArg a1)
{
    System_printf("<< enter TaskSocketClient() >>\n");

	// define IP-Addr.
    IPN IPAddrExt;
    IPN IPAddrLocal;
    IPAddrExt = inet_addr("192.168.1.10"); 		//PC
    IPAddrLocal = inet_addr("192.168.1.4"); 	//ICEV2 board

    // call function
    EchoTcpClient(IPAddrLocal, IPAddrExt);

    System_printf("<< closing TaskSocketClient() >>\n");
    Task_exit();
}







SocketClient.c
/*
 * Socket.c
 *
 *  Created on: 17. Mai 2017
 *      Author: PirklbauerMa
 */

/* ========================================================================== */
/*                            Includes		                                  */
/* ========================================================================== */
#include <xdc/std.h>
#include <xdc/runtime/System.h>
#include <ti/sysbios/knl/Task.h>
#include <ti/ndk/inc/bsd/sys/socket.h>
#include "ti/ndk/inc/bsd/socketndk.h"


// The following header should not be included referring to the NDK Reference Guide
// No header of the ti/ndk/inc should be included
/*
#include "ti/ndk/inc/socketndk.h"
#include "ti/ndk//inc/os/osif.h"
#include "ti/ndk/inc/usertype.h"
*/


/* ========================================================================== */
/*                            Constructors	                                  */
/* ========================================================================== */

void EchoTcpClient( IPN IPAddrLocal, IPN IPAddrExt )
{
	SOCKET s = INVALID_SOCKET;
	struct sockaddr_in sinExt;
	struct sockaddr_in sinLocal;
	int i, received, sent, error, val, buffersize ,ret = 0;
	char *pBuf = 0;
	char *pBufTest = 0;
	struct timeval timeout;

	buffersize = 2048;

	System_printf("\n== Start TCP Echo Client Test ==\n");

	// Allocate the file descriptor environment for this Task
	ret = fdOpenSession( (HANDLE)Task_self() );
	if (ret = 0){
		System_printf("failed to create file descriptor session!");
		goto leave;
	}
	else if (ret = 1) { System_printf("= File Descriptor session opened successfully =\n");}
	// Create test socket
	s = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);	// returns a file descriptor representing the socket
	if( s == INVALID_SOCKET ){ // INVALID_SOCKET stands for -1
		System_printf("failed socket create (%d)\n",fdError());
		goto leave;
	}
	else{ System_printf("= Socket created successfully =\n");}
	// Prepare address for connect
	bzero( &sinExt, sizeof(struct sockaddr_in) );
	sinExt.sin_family = AF_INET;
	sinExt.sin_addr.s_addr = IPAddrExt;	// Var.2 to set IP Addr. PC
	sinExt.sin_port = htons(54216); // Port PC
	//inet_aton("192.168.1.10", &sinExt.sin_addr.s_addr); // Var.1 to set IP Addr. PC

	// Configure our Tx and Rx timeout to be 5 seconds
	timeout.tv_sec = 5;
	timeout.tv_usec = 0;
	// Set send timeout
	ret = setsockopt( s, SOL_SOCKET, SO_SNDTIMEO, &timeout, sizeof( timeout ) );
	if (ret < 0 ){
		System_printf("failed set socket option (%d)\n",fdError());
		goto leave;
	}
	else if (ret = 0) { System_printf("= Socket Option set successfully =\n");}
	// Set receive timeout
	ret = setsockopt( s, SOL_SOCKET, SO_RCVTIMEO, &timeout, sizeof( timeout ) );
	if (ret < 0 ){
		System_printf("failed set socket option (%d)\n",fdError());
		goto leave;
	}
	else if (ret = 0) { System_printf("= Socket Option set successfully =\n");}
	// Connect socket - &sinExt is the pointer to the serv_addr
	ret = connect( s , (PSA) &sinExt, sizeof(sinExt));
	if( ret < 0 ){
		error = fdError();
		System_printf("\nfailed connect (%d)\n", error);
		goto leave;
	}
	else if (ret = 0) { System_printf("= Socket connected successfully =\n");}
	// Allocate a working buffer and testing buffer
	if( !(pBuf = malloc( buffersize )) )
	{
		System_printf("failed buffer allocation\n");
		goto leave;
	}
	if( !(pBufTest = malloc( buffersize )) )
	{
		System_printf("failed test buffer allocation\n");
		goto leave;
	}
	// Fill buffer with a test pattern
	for(i=0; i<buffersize; i++)
	{
		*(pBuf+i) = (char)i;
	}
	//
	// Send the buffer - return is the amount of successfully sent bytes
	sent = send( s, pBuf, buffersize, 0 );
	if( ret < 0 )
	{
		System_printf("send failed (%d)\n",fdError());
		goto leave;
	}
	// Try and receive the test pattern back - returns the number of bytes received .. data is in Buffer in pBufTest
	received = recv( s, pBufTest, buffersize, MSG_WAITALL );
	if( received < 0 )
	{
		System_printf("recv failed (%d)\n",fdError());
		goto leave;
	}
	// Verify reception size and pattern
	if( sent != received )
	{
		System_printf("received %d (not %d) bytes\n",received, sent);
		goto leave;
	}
	for(i=0; i<buffersize; i++)
		if( *(pBufTest+i) != (char)i )
		{
			System_printf("verify failed at byte %d\n",i);
			break;
		}
	// If here, the test passed
	if( received==sent )
		System_printf("passed\n");

leave:
	if( pBuf )
		free( pBuf );
	if( pBufTest )
		free( pBufTest );
	if( s != INVALID_SOCKET )
		fdClose( s );
	System_printf("== End TCP Echo Client Test ==\n\n");

	// Free the file descriptor environment for this Task
	fdCloseSession( (HANDLE)Task_self() );

}


SocketServer.c
/*
 * Socket.c
 *
 *  Created on: 17. Mai 2017
 *      Author: PirklbauerMa
 */

/* ========================================================================== */
/*                            Includes		                                  */
/* ========================================================================== */
#include <xdc/std.h>
#include <xdc/runtime/System.h>
#include <ti/sysbios/knl/Task.h>
#include <ti/ndk/inc/bsd/sys/socket.h>
#include "ti/ndk/inc/bsd/socketndk.h"


// The following header should not be included referring to the NDK Reference Guide
// No header of the ti/ndk/inc should be included
/*
#include "ti/ndk/inc/socketndk.h"
#include "ti/ndk//inc/os/osif.h"
#include "ti/ndk/inc/usertype.h"
*/


/* ========================================================================== */
/*                            Constructors	                                  */
/* ========================================================================== */


void EchoTcpServer( IPN IPAddrLocal, IPN IPAddrExt )
{
	SOCKET s = INVALID_SOCKET;
	struct sockaddr sinExt;
	struct sockaddr_in sinLocal;
	int i, error, val, ret = 0;
	char *pBuf = 0;
	struct timeval timeout;
	char test[4096];

	// Allocate the file descriptor environment for this Task
	ret = fdOpenSession( (HANDLE)Task_self() );
	if (ret = 0)
	{
		System_printf("failed to create file descriptor session!");
		goto leave;
	}

	System_printf("\n== Start TCP Echo Server Test ==\n");
	// Create test socket
	s = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);	// returns a file descriptor representing the socket
	if( s == INVALID_SOCKET ) // INVALID_SOCKET stands for -1
	{
		System_printf("failed socket create (%d)\n",fdError());
		goto leave;
	}
	// Prepare address for connect
	//bzero( &sinExt, sizeof(struct sockaddr_in) );
	//sinExt.sin_family = AF_INET;
	//inet_aton("192.168.1.10", &sinExt.sin_addr.s_addr); // Var.1 to set IP Addr. PC
	//sinExt.sin_addr.s_addr = IPAddrExt;	// Var.2 to set IP Addr. PC
	//sinExt.sin_port = htons(54216); // Port PC
	// Prepare address for listening
	bzero( &sinLocal, sizeof(struct sockaddr_in) );
	sinLocal.sin_family = AF_INET;
	//inet_aton("192.168.1.4", &sinLocal.sin_addr.s_addr); // Var.1 to set IP Addr. ICEV2
	sinLocal.sin_addr.s_addr = IPAddrLocal; // Var.2 to set IP Addr. ICEV2
	sinLocal.sin_port = htons(23); // Port ICEV2
	//sinExt.sin_port = htons(7); // Port ICEV2

	// Configure our Tx and Rx timeout to be 5 seconds
	timeout.tv_sec = 5;
	timeout.tv_usec = 0;
	// Set send timeout
	ret = setsockopt( s, SOL_SOCKET, SO_SNDTIMEO, &timeout, sizeof( timeout ) );
	if (ret < 0 )
	{
		System_printf("failed set socket option (%d)\n",fdError());
		goto leave;
	}
	// Set receive timeout
	ret = setsockopt( s, SOL_SOCKET, SO_RCVTIMEO, &timeout, sizeof( timeout ) );
	if (ret < 0 )
	{
		System_printf("failed set socket option (%d)\n",fdError());
		goto leave;
	}

	// [PIM 20170522] Test bind() function for a port
	ret = bind( s, (PSA) &sinLocal, sizeof(sinLocal));
	if( ret < 0 )
	{
		System_printf("failed to bind port (%d)\n",fdError());
		goto leave;
	}
	// [PIM 20170522] Test listen() function for a port
	ret = listen( s, 10);
	if( ret < 0 )
	{
		System_printf("failed to listen (%d)\n",fdError());
		goto leave;
	}
	// [PIM 20170522] Test accept() function for a port
	ret = accept( s , &sinExt, sizeof(sinExt));	// writes address from connecting entity in sinExt
	if( ret < 0 )
	{
		System_printf("failed to accept (%d)\n",fdError());
		goto leave;
	}
	goto leave;

leave:
	if( pBuf )
		free( pBuf );
	if( s != INVALID_SOCKET )
		fdClose( s );
	System_printf("== End TCP Echo Server Test ==\n\n");

	// Free the file descriptor environment for this Task
	fdCloseSession( (HANDLE)Task_self() );

}