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.

CCS/CC1310: Collector mixes up short addresses during association

Part Number: CC1310
Other Parts Discussed in Thread: SIMPLELINK-CC13X0-SDK

Tool/software: Code Composer Studio

Hey guys,

I just noticed something really strange. I use sensor collectorTi15.4 stack example in non-beacon mode. I made a network for testing purpose consisting of 6 sensors and one collector although I limited the network to only 5 sensors. In my code I have two features.

  1. The collector disconnects a sensor if it is not answering to tracking messages
  2. I print a list of all connected sensors once in a while including short and extended address, directly from the NV memory

Here the code for disconnection and sensor list printing:

void Csf_deviceNotActiveUpdate(ApiMac_deviceDescriptor_t *pDevInfo,
bool timeout)
{
//______________________MY CHANGE START___________________________
    LCD_WRITE_STRING_VALUE("!Resp: 0x", pDevInfo->shortAddress, 16, 5);

#ifdef TRACKING_DELAY_DISC
    /* Remove device from NV */
    Llc_deviceListItem_t item;
    ApiMac_sAddr_t devAddr;
    devAddr.addrMode = ApiMac_addrType_short;
    devAddr.addr.shortAddr = pDevInfo->shortAddress;

    Csf_getDevice(&devAddr, &item);
    Cllc_removeDevice(&item.devInfo.extAddress);
    System_printf("ReS: 0x%02x | ", pDevInfo->shortAddress);
    print_extAddress(item.devInfo.extAddress);
#endif
//_____________________MY CHANGE END______________________________
#if defined(MT_CSF)
    MTCSF_deviceNotActiveIndCB(pDevInfo, timeout);
#endif
}
void Csf_printSensorList(void)
{
    /* Sli = Sensor list */
    System_printf("Sli\r\n");
    int x;
    Llc_deviceListItem_t item;
    ApiMac_sAddr_t devAddr;
    devAddr.addrMode = ApiMac_addrType_short;

    for(x = 0; x < CONFIG_MAX_DEVICES; x++)
    {
        if(Cllc_associatedDevList[x].shortAddr != CSF_INVALID_SHORT_ADDR)
        {
            devAddr.addr.shortAddr = Cllc_associatedDevList[x].shortAddr;
            if(Csf_getDevice(&devAddr, &item))
            {
                System_printf("0x%02x | ", devAddr.addr.shortAddr);
                print_extAddress(item.devInfo.extAddress);
            }
        }
    }
    System_printf("NumS: %d\r\n", Csf_getNumDeviceListEntries());
}
#endif

Now look at the UART print what happened. Note, Sli indicates the start of the list, !Resp: 0x05 indicates the kick of the sensor, PJ-ON means the network is open again for another sensor (the 6th sensor now joining). STr means "send tracking request to sensor 06". The next two lines are one sensor data message being processed by the collector: MAC address, and then one line with info. newD means new device is joining, PJ-OFF means the network is closed again. PTr means the collector received a tracking response and is processing it.

So, a sensor gets kicked (I removed the battery so it could not answer tracking requests), but before a new sensor can join, a message is received by the collector, afteerwards the new sensor joins. The new sensor gets an already in use short address and is stored incorrectly with another extended address which corresponds to the wrong short address.

Sli
0x01 | 27:49:76:19:00:4b:12:00
0x02 | 67:49:76:19:00:4b:12:00
0x04 | 1d:44:76:19:00:4b:12:00
0x05 | 7c:49:76:19:00:4b:12:00
0x06 | 7d:49:76:19:00:4b:12:00
NumS: 5
!Resp: 0x5
PJ-ON
ReS: 0x05 | 7c:49:76:19:00:4b:12:00
STr 06
MAC: 7d:49:76:19:00:4b:12:00
AMA 9:1;0;0;0;0;0;0;0;0;
newD
joinD: 0x06 | 5a:49:76:19:00:4b:12:00
PJ-OFF
PTr 06
MAC: 5a:49:76:19:00:4b:12:00
AMA 26:0;0;0;0;0;0;0;5;2;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;
Sli
0x01 | 27:49:76:19:00:4b:12:00
0x02 | 67:49:76:19:00:4b:12:00
0x04 | 1d:44:76:19:00:4b:12:00
0x06 | 7d:49:76:19:00:4b:12:00
0x06 | 7d:49:76:19:00:4b:12:00
NumS: 5
ConfigRsp: 0x6

Here the code for the "joinD... line"

static ApiMac_assocStatus_t cllcDeviceJoiningCB(
                ApiMac_deviceDescriptor_t *pDevInfo,
                ApiMac_capabilityInfo_t *pCapInfo)
{
    //_____________MY CHANGE START_________________
#ifdef STATUS_MSG
    System_printf("joinD: ");
    System_printf("0x%02x | ",(uint16_t) pDevInfo->shortAddress);
    print_extAddress(pDevInfo->extAddress);
#endif
    //_____________MY CHANGE END___________________

The interesting thing is, that disconnecting and rejoining usually works fine like here (including timestamps):

24.11.2019 22:37:20    0x01 | 27:49:76:19:00:4b:12:00
24.11.2019 22:37:20    0x02 | 67:49:76:19:00:4b:12:00
24.11.2019 22:37:20    0x04 | 1d:44:76:19:00:4b:12:00
24.11.2019 22:37:20    0x07 | 7d:49:76:19:00:4b:12:00
24.11.2019 22:37:20    0x08 | 5a:49:76:19:00:4b:12:00
24.11.2019 22:37:21    NumS: 5
24.11.2019 22:37:39    !Resp: 0x7
24.11.2019 22:37:39    PJ-ON
24.11.2019 22:37:39    ReS: 0x07 | 7d:49:76:19:00:4b:12:00
24.11.2019 22:37:39    STr 08
24.11.2019 22:37:40    Sli
24.11.2019 22:37:40    0x01 | 27:49:76:19:00:4b:12:00
24.11.2019 22:37:40    0x02 | 67:49:76:19:00:4b:12:00
24.11.2019 22:37:40    0x04 | 1d:44:76:19:00:4b:12:00
24.11.2019 22:37:40    0x08 | 5a:49:76:19:00:4b:12:00
24.11.2019 22:37:41    NumS: 4
24.11.2019 22:37:41    newD
24.11.2019 22:37:42    joinD: 0x09 | 7c:49:76:19:00:4b:12:00
24.11.2019 22:37:42    PJ-OFF
24.11.2019 22:37:55    ConfigRsp: 0x9
24.11.2019 22:37:56    PTr 08
24.11.2019 22:37:59    Sli
24.11.2019 22:37:59    0x01 | 27:49:76:19:00:4b:12:00
24.11.2019 22:37:59    0x02 | 67:49:76:19:00:4b:12:00
24.11.2019 22:38:00    0x04 | 1d:44:76:19:00:4b:12:00
24.11.2019 22:38:00    0x09 | 7c:49:76:19:00:4b:12:00
24.11.2019 22:38:00    0x08 | 5a:49:76:19:00:4b:12:00
24.11.2019 22:38:00    NumS: 5

I know this is a long message but sometimes (really rare) I see wrong assignment of already in use short addresses also in the sniffer in crowdy networks with much disconnects and rejoins. I dont know if the error originates from my changes or if there is some bug in the Ti software. The difference between the two UART prints I shared is that once a message is received between disconnection of the old and connection of the new sensor.

Any ideas are welcome, because I am stuck so far and got no idea where this is coming from.

kind regards

Slev1n

  • Hey Slev1n,

    Which SDK are you experiencing this on?

  • Hey ammar,

    we use SIMPLELINK-CC13X0-SDK_3.20.00.23. If I can help you with anything just let me know.

  • Hey Slev1n,

    Can you try out your setup using the 3.10 SDK (http://www.ti.com/tool/download/SIMPLELINK-CC13X0-SDK/3.10.00.11)?

    Let me know what you see, as I think you may not see the issue on this SDK. If so, I can walk you through some code changes I think may remedy this issue for now.

  • Hey Ammar,

    I tried the old sdk and the issue didnt occur. However, I am not sure if I just wasnt able to reproduce the error, because I havent noticed the error at the new SDK anymore, too.

    If it is not too much effort you could still guide me through some changes. Otherwise, a factory reset would be the only action coming into my mind to solve this issue if occurring.

  • Hey Slev1n,

    I'm sorry, the solution I thought of is unrelated to the problem you described.

    Are you still having this same issue? If so, I'll try and look into it further.

  • Hey Ammar,

    I still do have this issue. I was able to reproduce it (check https://e2e.ti.com/support/wireless-connectivity/sub-1-ghz/f/156/t/863511) and it strikes me, that this only happens if a collector reset is performed and a sensor is being kicked.

    This is what I do:

    1. Trigger kick of sensor and remove it

                    if(Csf_getDevice(&devAddr, &item))
                    {
                        Cllc_sendDisassociationRequest(devAddr.addr.shortAddr, false);
                        Cllc_removeDevice(&item.devInfo.extAddress);
                    }

    2. I do now reset the collector

    3. Collector restarts, sensors polls, collector enteres PollIndCb() and sends disassociation request (note that the function Cllc_sendDiss... has to be called again to trigger the disassociation message by the collector)

    static void pollIndCB(ApiMac_mlmePollInd_t *pPollInd)
    {
        ApiMac_sAddr_t addr;
    
        addr.addrMode = ApiMac_addrType_short;
        if (pPollInd->srcAddr.addrMode == ApiMac_addrType_short)
        {
            addr.addr.shortAddr = pPollInd->srcAddr.addr.shortAddr;
        }
        else
        {
            addr.addr.shortAddr = Csf_getDeviceShort(
                            &pPollInd->srcAddr.addr.extAddr);
        }
    //__________MY CHANGE START____________
    #ifdef SMART_DIS
        if (findDevice(&pPollInd->srcAddr) == NULL &&
           pPollInd->srcAddr.addrMode == ApiMac_addrType_short)
        {
            Cllc_sendDisassociationRequest(addr.addr.shortAddr, false);
            System_printf("disD 0x%02x\r\n", addr.addr.shortAddr);
        }
    #endif
    //__________MY CHANGE END______________
        processDataRetry(&addr);
    }

    4. Sensor leaves network and joins after a few seconds again and receives an already in use short address. (maintainAssocTable and assocIndCb are not altered)

    Hope you can reproduce the error

  • Hey Slev1n,

    I'm having trouble reproducing the issue.

    Slev1n said:
    Trigger kick of sensor and remove it

    How are you triggering the kick of the sensor? I am "kicking" the first sensor joined by defining TEST_REMOVE_DEVICE (and modifying the api to NOT add the removed sensor to the blacklist). This enables me to kick the sensor by pressing the left button.

    Slev1n said:
    2. I do now reset the collector

    Do you wait for the sensor state to be 0 before resetting? I tried both situations and the device disassociated as intended.

    Slev1n said:
    Sensor leaves network and joins after a few seconds again and receives an already in use short address.

    When the sensor leaves, do you have to hit the right button to restart the sensor? On the collector side, is permit-Join on?

    Lastly, does this only happen with 5 or 6 sensors connected? Can I reproduce this issue with 1 or 2 sensors?

  • Ammar N said:
    How are you triggering the kick of the sensor?

    I send a UART cmd indicating which short address shall be kicked. Than the following code is executed.

        Llc_deviceListItem_t item;
        ApiMac_sAddr_t devAddr;
        devAddr.addrMode = ApiMac_addrType_short;
        devAddr.addr.shortAddr = shortAddr;
        /* If short address exists, kick and remove sensor */
        if(Csf_getDevice(&devAddr, &item))
        {
            Cllc_sendDisassociationRequest(devAddr.addr.shortAddr, false);
            Cllc_removeDevice(&item.devInfo.extAddress);
        }

    Before the sleepy sensor polls the next time, I reset the collector board. Note, that if you now want the collector to not just remove this sensor but actually send the disassociation message, you have to call Cllc_sendDisassociationRequest() within pollIndCb() again for this sensor. Seems like the collector "forgets" to send this request if being reset.

    Ammar N said:
    Do you wait for the sensor state to be 0 before resetting? I tried both situations and the device disassociated as intended.

    I dont know the states of the sensor since I have TIDA 00489 modules which are not connected to any pc. But I think I answered this questions before. The collector is reset before the sensor node has been notified.

    Ammar N said:
    When the sensor leaves, do you have to hit the right button to restart the sensor? On the collector side, is permit-Join on?

    Permit Join is always on in my system as long as the network is not full.

    Ammar N said:
    Lastly, does this only happen with 5 or 6 sensors connected?

    You need at least two sensor nodes for that test, because if only one is present, you cannot see if an already in use short address is assigned. Make sure, that you kick the sensor which is stored in the NV at an index BEFORE the second sensor. But this should be accomplished by kicking the "first" sensor in the NV.

    I tested with one sensor and after being kicked and joining again, the sensor should have short_address 0x02 but it still has 0x01. (I tested without reset of the collector and the sensor indeed is assigned to short address 0x02 after being kicked)

    kind regards

    Slev1n

  • Hey Slev1n,

    I apologize for the delay as we are out for the holidays here in the US. I am still looking into this.

  • Hey Slev1n,

    After looking into this, I think I may have some information you might find useful. To start, what we're seeing is actually the intended behavior of our examples, although they certainly can be improved (and you've done a great job so far implementing ways to improve).

    The shortAddresses are assigned in the assocIndCb(), and are a function of a variable not stored in NV. Because of this, when the collector is reset, we see the new sensor get assigned the short address of 0x1 when we intend for it to be assigned 0x2. The variable that tracks the number of devices is Cllc_numOfDevices.

    I recommend storing this variable in NV to maintain a correct count when the collector device is reset.