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.

Zigbee Fragmentation on z-stack 2.5.0 using ZNP + ZAP model

Other Parts Discussed in Thread: Z-STACK

5518.ExampleBigPacketSendFail.psd

I have turned on ZIGBEE_FRAGMENTATION and every time I send out a large set of data, I get afStatus_MEM_FAIL (x10)  from AF_DataRequest() via the SPI/ZNP and the packet sniffer shows a large pink "Error!! Parse data too long Data Length: 1551". The data length value goes a bit up or down but is always around 1500 regardless of the fact I am only trying to send 500 bytes. Once I lower the packet size to a single packet size (< 100 bytes) I am fine.

 

I am using the ZNP-pro.hex on the ZNP and I despite the fact that   ZIGBEE_FRAGMENTATION should be enabled  I went ahead and explicitly defined it again. I also tried adapting the generic app from here (http://e2e.ti.com/support/low_power_rf/f/158/p/119683/427588.aspx#427588) for this processor model and received the same results.

It appears that  is a problem in the ZNP side.  Shouldn't this work if we are using the Pro-stack?

 

I have attached a packet capture here.

As you can see, the request is in packet 94.

Bad “max size” packets are in 102, 108,114,120, and 126. The final truncated packet is ok in packet 132.

  • I don't know about the ZNP side, but I might be able to help with the packet sniffer "Parse data too long" error. I was having the same issue with the sniffer, was able to correct it by editing the file

    C:\Program Files\Texas Instruments\SmartRF Tools\Packet Sniffer\bin\general\plugin\zigbee\zigbee.plt

    in a text editor. Find the value "Packet_length_parsed_data" and increase this value; I believe the default is 1500, I increased it to 1600 and that fixed the problems I was having with the sniffer.

    Hope this helps!

  • Hello,

       I'm not using the ZAP (I prefer starting with the examples) and I've been able to send/receive messages of 600 Bytes without any errors. This is using the stock ZNP hex files. The fragmentation feature is cool but not really well documented. Below is the code I used to send the message. It's a wrapper method for AF_DATA_REQUEST_EXT. The API is a bit wanky, because if the message is long you don't include any data in the first AF_DATA_REQUEST_EXT message but instead only use AF_DATA_STORE messages as needed to get the whole message loaded. Both functions are included.

     

    --Derek

     

     


    #define AF_DATA_REQUEST_EXT_PAYLOAD_LEN  20
    #define AF_DATA_REQUEST_EXT_SRSP_STATUS_FIELD   SRSP_PAYLOAD_START
    /** Sends a message using extended messaging. This is more flexible and allows for long addressing.
    @param destinationLongAddress If using short addressing then the first two bytes are the short address,
    LSB first. Remaining 6 bytes are don't care. If using long addressing then this is the 8 byte MAC, and LSB first.
    @param destinationAddressMode Either DESTINATION_ADDRESS_MODE_LONG or DESTINATION_ADDRESS_MODE_SHORT
    @see afSendData for description of remaining fields.
    @note a znpResult of 0xE9 (233d) means ZMacNoACK error
    @return the transactionId used for this message, or NULL if znp error.
    This can be used by higher levels for matching AF_DATA_CONFIRM messages received.
    If znpResult != 0 then return value must not be used.

    TODO since sendMessage() is called in a few different places here (including in afDataStore)
    return a negative value to indicate where the error occurred.
    */
    unsigned char afSendDataExtended(unsigned char destinationEndpoint, unsigned char sourceEndpoint,
                            unsigned char* destinationAddress, unsigned char destinationAddressMode,
                            unsigned int clusterId, unsigned char* data, unsigned int dataLength)
    {
        if ((dataLength > AF_DATA_REQUEST_EXT_MAX_TOTAL_PAYLOAD_LENGTH) || (dataLength == 0))
        {
            znpResult = AF_ERROR_MESSAGE_EXCEEDS_MAX_LENGTH;
            return NULL;
        }
        if (clusterId == 0)
        {
            znpResult = -2000;
            return NULL;
        }
    #ifdef AF_ZDO_VERBOSE    
        printf("Sending EXT %u bytes to endpoint %u from endpoint %u with cluster %u (%04X) at LONG Address ",
               dataLength, destinationEndpoint, sourceEndpoint, clusterId, clusterId);
        printHexBytes(destinationAddress, 8);
    #endif 
        unsigned char transId = transactionSequenceNumber++;  //this value will get returned for use by higher level
        znpBuf[0] = AF_DATA_REQUEST_EXT_PAYLOAD_LEN + dataLength;
        znpBuf[1] = MSB(AF_DATA_REQUEST_EXT);
        znpBuf[2] = LSB(AF_DATA_REQUEST_EXT);     
        znpBuf[3] = destinationAddressMode;
        if (destinationAddressMode == DESTINATION_ADDRESS_MODE_LONG)
        {
            memcpy(znpBuf+4, destinationAddress, 8);
        } else if (destinationAddressMode == DESTINATION_ADDRESS_MODE_SHORT) {
            memcpy(znpBuf+4, destinationAddress, 2);  //remaining bytes are don't care
        } else {        //error - unsupported addressing mode
            znpResult = -3;
            return NULL;
        }
        znpBuf[12] = destinationEndpoint;
        znpBuf[13] = LSB(INTRA_PAN);
        znpBuf[14] = MSB(INTRA_PAN);
        znpBuf[15] = sourceEndpoint;
        znpBuf[16] = LSB(clusterId);
        znpBuf[17] = MSB(clusterId);
        znpBuf[18] = transId;
        znpBuf[19] = 0; //MAC_ACK; //Could also use AF_APS_ACK;
        znpBuf[20] = DEFAULT_RADIUS;
        znpBuf[21] = LSB(dataLength);
        znpBuf[22] = MSB(dataLength);

        if (dataLength <= AF_DATA_REQUEST_EXT_MAX_PAYLOAD_LENGTH)                       //if payload short enough, then include it in this message
        {
            memcpy(znpBuf+AF_DATA_REQUEST_EXT_PAYLOAD_LEN+3, data, dataLength);
           
            //printZnpBuf();
           
            znpResult = sendMessage();                                                  //...and send the message
            if (znpResult != 0)
                return NULL; //if error then return immediately; don't wait for AF_DATA_CONFIRM
    #ifdef AF_DATA_CONFIRM_HANDLED_BY_APPLICATION
        znpResult = 0;
    #else
        znpResult = waitForMessage(AF_DATA_CONFIRM, AF_DATA_CONFIRM_TIMEOUT);
        if (znpResult != 0)
            return NULL;
        znpResult = znpBuf[AF_DATA_REQUEST_EXT_SRSP_STATUS_FIELD];      // verify status is success, pass error to calling method
    #endif
        return transId;  //all done!
        }
       
        //NOW, message was larger than could fit into one message, so send the AF_DATA_REQUEST_EXT and then store the data...
        znpResult = sendMessage();
        if (znpResult != 0)
            return NULL;
       
        unsigned int totalMessageIndex = 0;  //index in the ZNP data buffer
       
        while (dataLength > 0)              //while there is still more data to be stored...
        {
            unsigned char bytesToSend = 0;
            if (dataLength > MAXIMUM_DATA_STORE_PAYLOAD_LENGTH)
                bytesToSend = MAXIMUM_DATA_STORE_PAYLOAD_LENGTH;
            else
                bytesToSend = dataLength;
           
            afDataStore(totalMessageIndex, data, bytesToSend);  //store each chunk of the total message
            if (znpResult != 0)
                return NULL;
           
            dataLength -= bytesToSend;
            totalMessageIndex += bytesToSend;      
    #ifdef AF_ZDO_VERBOSE 
            printf("Sent %u Bytes, %u remaining\r\n", bytesToSend, dataLength);
    #endif
        }

        afDataStore(0, data, 0);    //all data has been stored, now send the message
        if (znpResult != 0)
            return NULL;
    #ifdef AF_DATA_CONFIRM_HANDLED_BY_APPLICATION
        znpResult = 0;
    #else
        znpResult = waitForMessage(AF_DATA_CONFIRM, AF_DATA_CONFIRM_TIMEOUT);
    #endif
        return transId;  //all done!
    }

     

     


     

    #define MAXIMUM_DATA_STORE_PAYLOAD_LENGTH 247
    #define AF_DATA_STORE_PAYLOAD_LEN           3
    void afDataStore(unsigned int index, unsigned char* data, unsigned char dataLength)
    {
        if (dataLength > MAXIMUM_DATA_STORE_PAYLOAD_LENGTH)
        {
            znpResult = AF_ERROR_MESSAGE_EXCEEDS_MAX_LENGTH;
            return;
        }   
    #ifdef AF_ZDO_VERBOSE    
        printf("Storing %u bytes starting at index %u\r\n", dataLength, index);
    #endif
        // AF_DATA_STORE
        znpBuf[0] = AF_DATA_STORE_PAYLOAD_LEN + dataLength;
        znpBuf[1] = MSB(AF_DATA_STORE);
        znpBuf[2] = LSB(AF_DATA_STORE); 
       
        znpBuf[3] = LSB(index);
        znpBuf[4] = MSB(index);
        znpBuf[5] = dataLength;
        memcpy(znpBuf+AF_DATA_STORE_PAYLOAD_LEN+3, data, dataLength);
        znpResult = sendMessage();
        if (znpResult != 0)
            return;   
    }

  • Hi I am using the IF_DATA_REQUEST_EXT to send messages between 112 and 200 bytes from my end device and my coordinator. It works fine, but if I turn down my coordinator the end device keeps sending messages and the value of the SRSP is Success, is this normal?.

    I mean, is there any way to know that the coordinator  received the message from the END DEVICE side?

  • Yes - look at the result in the AF_DATA_CONFIRM_CMD that will come as an AREQ sometime after sending all of the chunks.

    Even when running a sample application directly on the Z-Stack, the immediate (i.e. SRSP) return from calling AF_DataRequest() is almost always SUCCESS - it simply means that the request was accepted by the stack library and will be attempted to be sent. The asynchronous AF_DATA_CONFIRM_CMD is the result of said attempt.

  • Thank you, I know it is not a really complicated question but I am new.

    Jaime.

  • Hi , I am using the AF_DATA_STORE to send a message of 249 bytes and all seems to work fine but I don´t receive the AF_DATA_CONFIRM and the message never arrive to the coordinator. I don´t know if I must do something that is not here in the post . If I send a message using only AF_DATA_REQUEST_EXT it works fine so maybe I am missing something.

  • Please download Z-Stack ZAP

    http://www.ti.com/tool/z-stack

    swrc173.zip (11MB) - contains ZStack-ZAP-MSP430-1.0.4.exe

    You can use the afStore(uint8 *buf, uint16 len) function as your example of how to do it.

  • Hi Harry thank you for your fast reply.

    I have downloaded the the file and I have seen the function you say. But I am not using the ZAP I am with the examples as Dereck. And I wonder If i can use the function he uses, but for me is not working. Another issue I have now is that I send the message with afSendDataExtended function in my end device side, but in my coordinator side I receive AF_INCOMING_MSG as AREQ instead of AF_INCOMING_MSG_EXT. I really can´t understand why.