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.

PROCESSOR-SDK-AM335X: Creating raw sockets

Part Number: PROCESSOR-SDK-AM335X


Goodmorning,

I'm working to create a system to communicate with raw sockets. I've built all the sample projects with pdkProjectCrate.bat and I've taken the NIMU_BasicExample_bbbAM335x_armExampleproject as starting point. Reading the document NDK_API_Reference.html, the file C:\ti\ndk_3_61_01_01\packages\ti\ndk\inc\serrno.h and some TI threads,  below you can see thread used to initialize the sockets.

I'm getting the following response:

Jumping to StarterWare Application...

SetPhyMode:000021e1 Auto:1, FD10:64, HD10:32, FD100:256, HD100:128, FD1000:8192 LPBK:0
Starting app to test raw sockets!
SetPhyMode:000021e1 Auto:1, FD10:64, HD10:32, FD100:256, HD100:128, FD1000:8192 LPBK:0
error in rx device setsockopt: 22
ENETPHY_FindingState: PhyNum: 0
ENETPHY_FindingState: PhyNum: 0
ENETPHY_DisablePhy(0)
Enable Phy to negotiate external connection
NWAY Advertising: FullDuplex-1000 FullDuplex-100 HalfDuplex-100 FullDuplex-10 HalfDuplex-10
ENETPHY_DisablePhy(0)
Enable Phy to negotiate external connection
NWAY Advertising: FullDuplex-1000 FullDuplex-100 HalfDuplex-100 FullDuplex-10 HalfDuplex-10
Phy: 0, NegMode 01e1, NWAYadvertise 01e1, NWAYREadvertise 45e1
Negotiated connection: FullDuplex 100 Mbs

void test()
{
    UART_printf("Starting app to test raw sockets!\n");

    while(1)
    {
        int r, val;
        static MACHINE_STATES machineStates = INIT_MACHINE;

        switch(machineStates)
        {
            case INIT_MACHINE:

                fdOpenSession(TaskSelf());

                prxsock = socket(AF_RAWETH, SOCK_RAWETH, 0x400);
                if (prxsock == INVALID_SOCKET) {
                    UART_printf("\nFailed to create RX RAW socket: %d\n", fdError());
                    fdCloseSession(TaskSelf());
                    machineStates = ERROR_DATA;
                    break;
                }

                // configure the receive device
                val = 1;
                r = setsockopt(prxsock, SOL_SOCKET, SO_IFDEVICE, &val, sizeof(val));
                if(r < 0) {
                    UART_printf("error in rx device setsockopt: %d\n", fdError());
                    fdCloseSession(TaskSelf());
                    machineStates = ERROR_DATA;
                    break;
                }

                // Configure the EMAC channel number
                val = 3;
                r = setsockopt(prxsock, SOL_SOCKET, SO_PRIORITY, &val, sizeof(val));
                if(r < 0) {
                    UART_printf("error in rx emac setsockopt: %d\n", fdError());
                    fdCloseSession(TaskSelf());
                    machineStates = ERROR_DATA;
                    break;
                }

                // Configure the Receive buffer size
                val = 1000;
                r = setsockopt(prxsock, SOL_SOCKET, SO_RCVBUF, &val, sizeof(val));
                if(r < 0) {
                    UART_printf("error in rx setsockopt: %d\n", fdError());
                    fdCloseSession(TaskSelf());
                    machineStates = ERROR_DATA;
                    break;
                }

                // we use RAW packet socket, with packet type ETH_P_ECAT
                ptxsock = socket(AF_RAWETH, SOCK_RAWETH, 0x400);
                if (ptxsock == INVALID_SOCKET) {
                    UART_printf("\nFailed to create TX RAW socket: %d\n", fdError());
                    fdCloseSession(TaskSelf());
                    machineStates = ERROR_DATA;
                    break;
                }

                // configure the transmit device
                val = 1;
                r = setsockopt(ptxsock, SOL_SOCKET, SO_IFDEVICE, &val, sizeof(val));
                if(r < 0) {
                    UART_printf("error in tx device setsockopt: %d\n", fdError());
                    fdCloseSession(TaskSelf());
                    machineStates = ERROR_DATA;
                    break;
                }

                // Configure the EMAC channel number
                val = 3;
                r = setsockopt(ptxsock, SOL_SOCKET, SO_PRIORITY, &val, sizeof(val));
                if(r < 0) {
                    UART_printf("error in tx emac setsockopt: %d\n", fdError());
                    fdCloseSession(TaskSelf());
                    machineStates = ERROR_DATA;
                    break;
                }

                // Configure the Transmitter buffer size
                val = 1000;
                r = getsendncbuff(ptxsock, val, (void **) &pBuffer, &hPkt);
                if(r < 0) {
                    UART_printf("error in tx setsendbuf: %d\n", fdError());
                    fdCloseSession(TaskSelf());
                    machineStates = ERROR_DATA;
                    break;
                }

                UART_printf("\nSockets Initialized!\n");
                fdCloseSession(TaskSelf());
                machineStates = SEND_DATA;
                break;

            case SEND_DATA:
                composePacket();
                osal_usleep(100);
                break;

            case RECEIVE_DATA:
                //decodePacket();
                break;

            case ERROR_DATA:
                osal_usleep(1000);
                break;

            default:
                break;
        }
    }
}

/* ========================================================================== */
/*                              Main Function                                 */
/* ========================================================================== */


int main()
{
    /* Call board init functions */
    Board_initCfg boardCfg;
    EMAC_HwAttrs_V4 cfg;

    boardCfg = BOARD_INIT_PINMUX_CONFIG |
        BOARD_INIT_MODULE_CLOCK | BOARD_INIT_UART_STDIO;
    Board_init(boardCfg);

    /* Chip configuration MII/RMII selection */
    SOCCtrlCpswPortMacModeSelect(1, ETHERNET_MAC_TYPE_MII);
    SOCCtrlCpswPortMacModeSelect(2, ETHERNET_MAC_TYPE_MII);

    EMAC_socGetInitCfg(0, &cfg);
    cfg.port[0].phy_addr = EMAC_CPSW_PORT0_PHY_ADDR_EVM;
    cfg.port[1].phy_addr = EMAC_CPSW_PORT0_PHY_ADDR_EVM;
    cfg.macModeFlags = EMAC_CPSW_CONFIG_MODEFLG_FULLDUPLEX;
    EMAC_socSetInitCfg(0, &cfg);

    NIMUDeviceTable[nimu_device_index++].init =  &CpswEmacInit ;
    NIMUDeviceTable[nimu_device_index].init =  NULL ;

    osal_thread_create(&test, 0);

    BIOS_start();

    return -1;
}

My questions are:

  1. Is the NIMU_basic example the more suitable project to start with raw sockets? If not, can you provide an up-to-date example?
  2. Is there an application (.exe) that can be used to test the sockets?
  3. Is it possible to connect sockets in loop (I read what I write)?
  4. Why do I get error 22 (NDK_EINVAL  /* Invalid argument */) when crating raw_socket?
  5. Once that I created the read and write sockets can I call the method sendncfree() and recvncfree() only when closing the sockets ? It's not necessary to allocate space and deallocate every time that I call methods sendnc and recvnc, right?

Thank you.

Best Regards,

Davide Brunelli

Best Regards,

Davide Brunelli

  • Hi Davide,

    >>Is the NIMU_basic example the more suitable project to start with raw sockets? If not, can you provide an up-to-date example?

    [MW] the NIMU_basic example is used to test the "ping" command for NDK/NIMU. It is not a good start for your test. Maybe the ftpApp example in C:\ti_am3_610\pdk_am335x_1_0_16\packages\ti\transport\ndk\nimu\example\ftpApp will help.

    >>Is there an application (.exe) that can be used to test the sockets?

    [MW] no such windows application exist. You may want check out C:\ti_am3_610\ndk_3_61_01_01\packages\ti\ndk\winapps

    >>Is it possible to connect sockets in loop (I read what I write)?

    [MW] I am not aware of any example in PDK. You may want to check the NDK 5.4.2 Server Daemon Example in http://www.ti.com/lit/ug/spru524k/spru524k.pdf

    >>Why do I get error 22 (NDK_EINVAL  /* Invalid argument */) when crating raw_socket?

    [MW] are you sure 0x400 in socket(AF_RAWETH, SOCK_RAWETH, 0x400) is a legal protocol?

    >>Once that I created the read and write sockets can I call the method sendncfree() and recvncfree() only when closing the sockets ? It's not necessary to allocate >>space and deallocate every time that I call methods sendnc and recvnc, right?

    [MW] that is correct.

    Ming

  • Hello Ming,

    thank you for your answer and valuable information. Using the ftpApp as starting point I could succesfully create TCP client and server sockets.

    But when I try to create raw sockets in the very same project, I still have the same problem. I changed the code as follow:

        // we use RAW packet socket, with packet type PROFINET
        ptxsock = socket(AF_RAWETH, SOCK_RAWETH, 0x8892);                 // NDK_htons(0x8892)
        if (ptxsock == INVALID_SOCKET) {
            UART_printf("\nFailed to create TX RAW socket: %d\n", fdError());
            goto leave;
        }
    
        // configure the transmit device
        val = 1;
        r = setsockopt(ptxsock, SOL_SOCKET, SO_IFDEVICE, &val, sizeof(val));
        if(r < 0) {
            UART_printf("error in tx device setsockopt: %d\n", fdError());
            goto leave;
        }

    When I set the SO_IFDEVICE property I still get "error in tx device setsockopt: 22".

    Here some questions:

    1. I tried to create the socket both setting the protocol as 0x8892 and NDK_htons(0x8892), what is the correct form?
    2. Concerning the SO_IFDEVICE, which is mandatory for raw sockets, where does the value to assign come from? Looking in other threads, I saw that anyone set it to 1 but I don't know why..

    For information the Code composer version is 9.3.0.00012 , the PROCESSOR_SDK is processor_sdk_rtos_am335x_6_01_00_08, the demo board is Beaglebone black.

    Thank you.

    Best Regards,

    Davide

  • Hi Davide,,

    1. I tried to create the socket both setting the protocol as 0x8892 and NDK_htons(0x8892), what is the correct form?

    [MW] NDK_htons(port_num) is using port number, while socket(0x8892) is using the protocol 

    2. Concerning the SO_IFDEVICE, which is mandatory for raw sockets, where does the value to assign come from? Looking in other threads, I saw that anyone set it to 1 but I don't know why..

    [MW] According to pp66 in spru524k.pdf (NDK API Reference),  socket() --> NDK_socket(AF_RAWETH, SOCK_RAWETH, 0x8892); is illegal. The 0x8892 is not one of the following

    #define     ETHERTYPE_IP            0x800
    #define     ETHERTYPE_IPv6          0x86DD
    #define     ETHERTYPE_VLAN          0x8100
    #define     ETHERTYPE_PPPOECTL      0x8863
    #define     ETHERTYPE_PPPOEDATA     0x8864

    According to pp69 of spru524k, setsockopt(ptxsock, SOL_SOCKET, SO_IFDEVICE, &val, sizeof(val)); return 22 is "EINVAL Buffer arguments are invalid". It means either the &val is NULL or sizeof(val) is not sizeof(uint32_t) (check RawEthSockSet()in ndk_3_61_01_01\packages\ti\ndk\stack\rawethsock\rawethsock.c).

    Ming

  • Hello Ming,

    thank you

    I'll read and write you back.

    Regards,

    Davide Brunelli

  • Hello Ming,

    when I wrote the code to create a raw socket, I did it looking at other threads like:

    e2e.ti.com/.../530697

    Where they create a raw socket with something like:

    sraw = socket(AF_RAWETH, SOCK_RAWETH, 0x4A58); (0x4A58 is the custom protocol to be implemented)

    Besides if I read spru524k.pdf on page 66, it states concerning raw socket:

    Socket protocol(canbe set to any custom value other than the well-known types:IP (0x800), IPv6(0x86DD), VLAN(0x8100), PPPoEControl(0x8863), PPPoEData(0x8864) is acceptable)

    As per my understanding, the socket protocol can be any custom value different than the ones that you listed (IP (0x800), IPv6(0x86DD), VLAN(0x8100), PPPoEControl(0x8863), PPPoEData(0x8864)).

    However please ignore this introduction of mine. My job consists of moving code that it's working under Linux to TIRTOS. I have the following expression in Linux:

    socket(AF_PACKET, SOCK_RAW, htons(0x8892));

    How do I implement it in RTOS?

    Thank you.

    Regards,

    Davide

  • Hi Davide,

    Please refer to the function Nimu_testSendRawEth() in pdk_am335x_1_0_16\packages\ti\transport\ndk\nimu\example\client\src\client.c for how to send a raw packet.

    According to ndk_3_61_01_01\packages\ti\ndk\inc\socketndk.h, "#define SO_IFDEVICE     0x100a".

    Ming

  • Hello Ming,

    thank you for your link. Actually now I can succesfully send raw frames. The changes that I have done are:

    1. Insert a delay before creating the socket (as in the link that you passed me).
    2. Change the variable of val as uint32_t (looking the source code rawethsock.c I saw that it check that the sizeof(var) must be coherent with the one of uint32_t)
    uint32_t val = 1;
    int size = (int) sizeof(val);
    r = setsockopt(ptxsock, SOL_SOCKET, SO_IFDEVICE, &val, size);

    For testing the receiving socket, unfortunately I've look at the winapps folder executables but all the programs ask for an IP and a port, which don't exist in raw sockets.

    I'll try to use the same socket to send and receive in two different threads, I guess I'll use fdShare() instead of fdOpen() for this purpose. In case of problems, I'll write again on the forum.

    Thank you.

    Regards,

    Davide

  • Hi Davide,

    Glad to see it works for you now.

    Ming