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.

MSP432E401Y: NDK in simplelink_msp432e4_sdk_4_20_00_12 can't send fragmented UDP packets, but can receive them

Part Number: MSP432E401Y

In the related thread found that when attempted to use the NDK from simplelink_msp432e4_sdk_4_20_00_12 to send a UDP packet which was greater than the MSS that the sendto() function returned -1, rather than sending fragmented UDP packets.

The test was done with a modified udpEcho example in which the recvfrom() could receive a UDP packet which was larger than the MSS and had therefore been fragmented. The issue was that trying to use sendto() to echo the received UDP packet failed.

The issue appears to be the structure of the UdpOutput() function in simplelink_msp432e4_sdk_4_20_00_12\source\ti\ndk\stack\udp\udp.c:

/*-------------------------------------------------------------------- */
/* UdpOutput() */
/* Called when UDP packet should be sent */
/*-------------------------------------------------------------------- */
int UdpOutput( void *hSock, unsigned char *buf, int32_t size, int32_t *pRetSize )
{
    <snip>
    mss -= SockGetIpHdrSize(hSock) + UDPHDR_SIZE;   /* Sub off IpHdr & UdpHdr */

    if( size > mss )
    {
        error = NDK_EMSGSIZE;
        goto UDP_EXIT;
    }

    <snip>
    /* Send the packet */
    error=(int)IPTxPacket(pPkt,SockGetOptionFlags(hSock)&FLG_IPTX_SOSUPPORTED);

UDP_EXIT:
    if( !error )
        *pRetSize = size;
    else
        *pRetSize = 0;

    return( error );
}

The issue that UdpOutput() returns the error NDK_EMSGSIZE if the packet size is larger than the MSS, rather than attempting to send a fragmented packet. The IPTxPacket() function does appear to be able to send a fragmented UDP packet as has a /* Send out a bunch of fragmented packets */ loop.

If it a bug that sendto() can't send a fragmented UDP packet?

Note that the original thread is marked as resolved since the original poster changed their program to avoid sending UDP packets greater than the MSS to avoid the issue. I created this thread to query if it is a bug which should be fixed in the NDK.

I have attached the UDP echo programs used, one for TI-RTOS and one for FreeRTOS, both of which show the issue. The changes made to the examples were:

  • Increase the UDPPACKETSIZE macro to allow to handle packets larger than the MSS.
  • Increase the stack size for echoFxn task due to the increase in UDPPACKETSIZE
  • Add a Display_printf() call to report an error from sendto()

udpecho_MSP_EXP432E401Y_tirtos_ccs.zip

udpecho_MSP_EXP432E401Y_freertos_ccs.zip

  • Hi Chester,

    Based on the SDK documentation at http://software-dl.ti.com/simplelink/esd/simplelink_msp432e4_sdk/4.20.00.12/docs/ndk/NDK_API_Reference.html, 
    it is not clear whether this feature is intended to be supported. 

    Srinivas

  • Chester Gillon said:
    If it a bug that sendto() can't send a fragmented UDP packet?

    I tried commenting out the following in the UdpOutput function in the simplelink_msp432e4_sdk_4_20_00_12\source\ti\ndk\stack\udp\udp.c source file:

        /*if( size > mss )
        {
            error = NDK_EMSGSIZE;
            goto UDP_EXIT;
        }*/
    

    With that modification the sendto() function no longer fails with an error when attempted to send a packet greater than the MSS of 1472 bytes. However, the udpSendReceive test program running on a Linux PC failed to receive any reply when the MSP432E target was attempting to echo UDP packets of size 1473 bytes (one byte larger that the MSS of one packet). A wireshark capture showed that the MSP432E target was generating a UDP checksum error:

    I have turned off the tx and rx offload on the PC running the wireshark capture, and wireshark is only reporting an incorrect UDP checksum on the fragmented UDP  packets sent from the MSP432E device, so believe this is a real problem.

    For the above 192.168.0.118 is the Linux PC running the udpSendReceive program and 192.168.0.5 is the MSP432E device running the udpEcho test.

  • Chester Gillon said:
    have turned off the tx and rx offload on the PC running the wireshark capture, and wireshark is only reporting an incorrect UDP checksum on the fragmented UDP  packets sent from the MSP432E device, so believe this is a real problem.

    The simplelink_msp432e4_sdk_4_20_00_12/source/ti/drivers/emac/EMACMSP432E4.c driver is configuring the hardware to be responsible for computing all checksums in that:

    1. The EMACMSP432E4_NIMUInit function sets the device flags as:

        /* Inform upper layers that this driver enables Checksum Offloading */
        device->flags = NIMU_DEVICE_ENABLE_HW_CHKSM_TX_ALL |
                        NIMU_DEVICE_ENABLE_HW_CHKSM_RX_ALL;
    

    2. The EMACMSP432E4_processPendingTx function sets:

            pDesc->Desc.ui32CtrlStatus |=
                    (DES0_TX_CTRL_IP_ALL_CKHSUMS | DES0_TX_CTRL_CHAINED);
    

    3. The EMACMSP432E4_emacStart function sets:

        /* Set MAC configuration options. */
        EMACConfigSet(EMAC0_BASE, (EMAC_CONFIG_FULL_DUPLEX |
                                   EMAC_CONFIG_7BYTE_PREAMBLE |
                                   EMAC_CONFIG_IF_GAP_96BITS |
                                   EMAC_CONFIG_USE_MACADDR0 |
                                   EMAC_CONFIG_SA_FROM_DESCRIPTOR |
                                   /* Enable RX Checksum Offload: */
                                   EMAC_CONFIG_CHECKSUM_OFFLOAD |
                                   EMAC_CONFIG_BO_LIMIT_1024),
                      (EMAC_MODE_RX_STORE_FORWARD |
                       EMAC_MODE_TX_STORE_FORWARD |
                       EMAC_MODE_TX_THRESHOLD_64_BYTES |
                       EMAC_MODE_RX_THRESHOLD_64_BYTES), 0);
    

    The problem enabling hardware generation of UDP checksums is that for the UDP checksum to be calculated the UDP payload across all fragmented frames must be known. While the NDK software fragments UDP packets into multiple Ethernet frames, the MSP432E Ethernet Controller transmit UDP checksum transmit offload only processes one frame at a time. Therefore, when a UDP packet is fragmented into multiple Ethernet frames the UDP checksum inserted by the hardware offload into the first frame (which contains the UDP header) is only calculated on the payload in the first frame, and is therefore incorrect.

  • Chester Gillon said:
    Therefore, when a UDP packet is fragmented into multiple Ethernet frames the UDP checksum inserted by the hardware offload into the first frame (which contains the UDP header) is only calculated on the payload in the first frame, and is therefore incorrect.

    The same problem can occur with ICMP packets.

    E.g a ping with a size of 1400 bytes, using one frame, works.

    Whereas a ping of size 1500 bytes, which requires fragmenting into two Ethernet frames, causes the device to transmit an incorrect ICMP checksum.

  • Srinivas Lingam said:
    Based on the SDK documentation at http://software-dl.ti.com/simplelink/esd/simplelink_msp432e4_sdk/4.20.00.12/docs/ndk/NDK_API_Reference.html, 
    it is not clear whether this feature is intended to be supported. 

    The 2.5.1 Troubleshooting Common Problems section of the NDK Users Guide has advice for how to resolve the following issues; both of which require the NDK to handle fragmented IP packets:

    • Pings to NDK target Fails Beyond 3012 Size
    • Sending and Receiving UDP Datagrams over MTU Size

    Which would suggest the NDK was intended to allow support for fragmented IP packets and UDP datagrams.

    I was able to make NDK modifications to allow the udpEcho example to work with UDP datagrams of 4000 bytes (i.e. fragmented into 3 Ethernet frames). The example is in https://github.com/Chester-Gillon/E2E_example_projects/tree/master/udpecho_fragmented_packets_MSP_EXP432E401Y_tirtos_ccs. There is a notes.txt file in that directory which lists the changes which were required. Some were just syscfg configuration changes, but there were also 3 modified simplelink sources which were added to the project.

    Perhaps TI could look at the list of the changes and determine if any are bug-fixes / enhancements which could be made to simplelink.

**Attention** This is a public forum