Quantcast
Channel: Microcontrollers
Viewing all articles
Browse latest Browse all 229876

Forum Post: LWIP Segmentation Problem

$
0
0

Hi All,

New to LWIP and I am at lost as to what caused the data segmentation problem I am experiencing. I am running TI's Demo LWIP in TMDXRM48HDK with FREERTOS. Basically the problem is, I am sending an 11 byte MODBUS/TCP Reply ADU to a remote client but during transmission for an unknown reason the 11 byte data is being segmented. Please see below the Wireshark trace:

Transmission Control Protocol, Src Port: asa-appl-proto (502), Dst Port: 51719 (51719), Seq: 45, Ack: 61, Len: 11

  Source port: asa-appl-proto (502)

  Destination port: 51719 (51719)

  [Stream index: 0]

  Sequence number: 45 (relative sequence number)

  [Next sequence number: 56 (relative sequence number)]

  Acknowledgment number: 61 (relative ack number)

  Header length: 20 bytes

  Flags: 0x018 (PSH, ACK)

  Window size value: 4036

  [Calculated window size: 4036]

  [Window size scaling factor: -1 (unknown)]

  Checksum: 0xa6a3 [validation disabled]

  [Good Checksum: False]

  [Bad Checksum: False]

  [SEQ/ACK analysis]

    [This is an ACK to the segment in frame: 76]

    [The RTT to ACK the segment was: 0.024228000 seconds]    

    [Bytes in flight: 11]

  [PDU Size: 10] (Why 10?)

  TCP segment data (1 byte)  (<--Problem: Segment data)

Modbus/TCP

  Transaction Identifier: 5

  Protocol Identifier: 0

  Length: 4

  Unit Identifier: 1

Modbus

   Function Code: Read Holding Registers (3)

   Byte Count: 2

   Data: 00

Please see below our code:

void vTask1(void *pvParameters) {     err_t err;      EMAC_LwIP_Main (emacAddress);      modbus_socket  = tcp_new();      err = tcp_bind(modbus_socket, IP_ADDR_ANY, 502);     if (err != ERR_OK)     {         return;     }      modbus_socket = tcp_listen(modbus_socket);     tcp_accept(modbus_socket, socket_accept);     while(1)     {         vTaskDelay(100);     } } err_t socket_accept(void *arg, struct tcp_pcb *newpcb, err_t err) {     tcp_recv(newpcb, socket_receive);     tcp_sent(newpcb, socket_sent);     return ERR_OK; } err_t socket_receive(void *arg, struct tcp_pcb *tpcb, struct pbuf *p, err_t err) {     uint16 quantity;     ReadHoldingRegs_st *readHoldingRegs;     ModbusTCP_st *modbusTcp;      if (p != NULL)     {         tcp_recved(tpcb, p->tot_len);     }     if(err != ERR_OK || p == NULL)     {         tcp_close(tpcb);         if(p != NULL)         {             pbuf_free(p);         }         return ERR_OK;     }     modbusTcp = p->payload;      if(modbusTcp->data[0] == 0x03) //READ HOLDING REGISTERS     {         readHoldingRegs = (ReadHoldingRegs_st *)modbusTcp->data;         quantity = readHoldingRegs->quantity[0] << 8;         quantity |= readHoldingRegs->quantity[1];          //check for quantity         if(quantity < 1 || quantity > 0x7DU)         {             //invalid quantity             ReplyError(tpcb, modbusTcp, 0x03);         }         //create fake register content         ReplyFakeData(tpcb, modbusTcp, quantity);         //echo         //tcp_write(tpcb, p->payload, p->len, TCP_WRITE_FLAG_COPY);      }     else     {         //unsupported function         ReplyError(tpcb, modbusTcp, 0x01);     }     //process data     pbuf_free(p);      return ERR_OK; } void ReplyFakeData(struct tcp_pcb *tpcb, ModbusTCP_st *originalRqst, uint16 count) {     uint32 index = 0;      ModbusTCP_st *replyModbusTcp;     uint32 pduSize = 7 + 2 + (count * 2); //MODBUS/TCP ADU + MODBUS PDU + REGISTERS VALUE      replyModbusTcp = pvPortMalloc(pduSize);      //adu modbus     replyModbusTcp->uintId        = originalRqst->uintId;     replyModbusTcp->transactionId = originalRqst->transactionId;     replyModbusTcp->protocolId    = originalRqst->protocolId;     replyModbusTcp->length = swap16(2 +  (count * 2));     //pdu modbus     replyModbusTcp->data[0] = 0x03;     replyModbusTcp->data[1] = count * 2;      for(index=0; index < (count*2); index++)     {         replyModbusTcp->data[2+index] = index;     }     //check current send buffer if enough     if(tcp_sndbuf(tpcb) >= pduSize)     {         tcp_write(tpcb, replyModbusTcp, pduSize, TCP_WRITE_FLAG_COPY);     }      vPortFree(replyModbusTcp); }


Thanks in advance for the suport.


Regards,

Chris


Viewing all articles
Browse latest Browse all 229876

Latest Images

Trending Articles



Latest Images

<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>