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.

CC1310: My plan to add router functionality to the TI 15.4 stack

Part Number: CC1310

Hi,

I am using the TI 15.4 stack on a CC1310 in LRM. Whilst the RF range in this mode is impressive, I need to ensure coverage by using routers to allow end devices to be placed in noisy environments. This is my plan:

1) I want the end device (Sensor application) to join using the normal 802.15.4 beacon/beacon response mechanism which as standard would be with the pan-coordinator (Collector). However I also want the end device to be able to join the network through the router. 

2) To satisfy router joins, the router needs also to be able to send out beacons in response to an end device's beacon request. I cannot see how the TI 15.4 stack allows me to configure the MAC level beacon response of the coordinator (e.g. PAN Coordinator = 0, FFD = 1) to turn it into a router, so I am stuck with using the beacon format as sent out by the pan-coordinator.

3) My plan is to use the Collector application as a basis for a router and allow end devices (or other routers) to join as though it were a pan-coordinator. However, once the end device has joined locally, it will send all the join information to the actual pan-coordinator for it to populate its association tables. The router then deletes the newly joined end device from its own association tables.

4) Now that the end device is joined on the network with the router as its parent, any messages received by the router will be forwarded to the pan-coordinator. 

I have not thought too much at this stage what complications may arise if the end device loses its parent router and needs to join another. There isn't any need for routing tables in my application as messages are addressed only from an end device to the pan-coordinator and vice-versa. The return route mechanism will be based on the MTORR used in ZigBee 3.0 applications. This means the task of the router should be only to forward messages to either its parent node or one of its child nodes (routers and end devices).

At this stage I would be grateful for any feedback as to whether or not the above plan is feasible. I would be happy to report back my success to help others.

Many thanks,

Andy

  • TI 15.4 only supports star networks so there is no easy way of creating a router that other devices can use to join the network. Regardless of this, creating a router with 15.4 stack should still be possible.

    In order to achieve this you will have to combine some code from collector and sensor. Basically you need a Collector which is started with startReq.panCoordinator = false;(I believe this should set up your device as PAN Coordinator = 0, FFD = 1) when ApiMac_mlmeStartReq. On top of that you will need some of the code in jdllc.c to do active scans and join a network.

    Please note that I haven't had time to test this so there is a chance that I missed something
  • Also, I recommend using the Collector project as a base for the router but if you decide to go with the sensor project then make sure to define

    #define FEATURE_FULL_FUNCTION_DEVICE
  • A quick update on this, I ran a couple of tests and here are some more pointers to be able to implement a Router like device with 15.4 Stack.

    In the file osaltask.c, make sure that you call both "MAC_InitDevice" and "MAC_InitCoord". If you define "FEATURE_FULL_FUNCTION_DEVICE", by default only "MAC_InitCoord" is called but you need to call both to ensure that the device message support is also enabled and initialized.

    When it comes to joining a network with this router device you should follow the same way a sensor joins a network with the exception that after you successfully join the network(i.e. assocCnfCb call back is triggered) you then call "ApiMac_mlmeStartReq" with the parameter "panCoordinator = false"

    After this your device should be able to respond to Beacon requests and allow devices to join the network through this router device

  • Hi Hector,

    Thank you for looking into this, your replies have been most useful. I now have my environment set up and can confirm that setting startReq.panCoordinator = false; works as expected. That is, the router issues a beacon response with Pan Coordinator = false. I have created a new 'router' project which cleanly compiles and have included both cllc.c and jdllc.c. There is now a module called router.c which will have elements of both sensor.c and collector.c.

    My next task is to work though the joining process as you suggest, and add this functionality to router.c (as it was based on collector.c). I have yet to investigate if the functionality of the router-sensor code and the router-collector code need to be ran as two RTOS tasks or if they can be combined into one, and how they will work with ICall.

    I'll let you know when I have my router joined on a network.

    Many thanks,

    Andy
  • Hi Hector,

    Can you tell me if the fact that these NV ID's are the same in ssf.c is an error?

    #define SSF_NV_BLACKLIST_ENTRIES_ID 0x0002

    #define SSF_NV_CONFIG_INFO_ID  0x0002

    I have my router able to join a parent now. The plan is to allow the router-collector code use the information created during the router-sensor join, and because the NV ID for the network information (Llc_netInfo_t) are the same for both collector and sensor I shouldn't have to manipulate the NV directly myself.

    #define CSF_NV_NETWORK_INFO_ID 0x0001

    #define SSF_NV_NETWORK_INFO_ID 0x0001

    I will also manually confgire the coordInformation_t data.

    Regards,

    Andy

  • Hi,
    Yes, it is an error that the two of them are assigned the same NV ID. Thanks for pointing this out, I will submit a ticket for this to be fixed.

    Regardless, this should not cause any problems unless you are planning on using the black list feature. If this is the case then you should be able to set SSF_NV_CONFIG_INFO_ID to 0x0008 since that ID is not being use and this should take care of any conflicts between the 2 NV IDs. 

  • Hi Hector,

    I have now written a new logical link controller specifically for the router. It combines the functionality I need from the coordinator LLC and the joining-device LLC. Essentially, when the router is associated to a parent using the JDLLC code, it automatically starts the CLLC code with the network information obtained when joining as a child. All the coordinator scanning is skipped and it is simply started with the following function called from assocCnfCb(); and Rllc_rejoin();

    void Rllc_start_coordinator_with_network_info(Llc_netInfo_t *pParentInfo)
    {
        coordInfoBlock.panID = pParentInfo->devInfo.panID;
        coordInfoBlock.channel = pParentInfo->channel;
        ApiMac_mlmeGetReqUint16(ApiMac_attribute_shortAddress, &coordInfoBlock.shortAddr);
        sendStartReq(CONFIG_FH_ENABLE);
        switchState(COORD_DEVICE, Cllc_coordStates_startCnf);
    }

    In the router LLC I have the following code in the data indication callback. It will check to see if the network level destination address matches the current device (I have not written this part yet so it is fixed to 0x0002 which is the saddr of the router's child). There is an overhead in that I have to copy the incoming message indication struct ApiMac_mcpsDataInd_t to the outgoing message request struct ApiMac_mcpsDataReq_t. This works well but I wonder if there's a quicker way to reduce overhead on the router. I think this would require a function in the stack library to do this at a lower level.

    static void dataIndCb(ApiMac_mcpsDataInd_t *pData)
    {
        Rsf_updateFrameCounter(&pData->srcAddr, pData->frameCntr);
    
        /* check if msg should be routed or passed up to this app */      
        if(pData->srcAddr.addr.shortAddr == 0x0002)
        {
            ApiMac_mcpsDataReq_t dataReq;
            
            memset(&dataReq, 0, sizeof(ApiMac_mcpsDataReq_t));
    
            dataReq.dstAddr.addr.shortAddr = devInfoBlock.coordShortAddr;   
            dataReq.dstAddr.addrMode = ApiMac_addrType_short;
            dataReq.dstPanId = pData->dstPanId;
            dataReq.srcAddrMode = ApiMac_addrType_short;
            dataReq.msduHandle = 0;
            dataReq.txOptions.ack = true;
            dataReq.txOptions.indirect = false;
            
            dataReq.msdu.len = pData->msdu.len;
            dataReq.msdu.p = pData->msdu.p;
            
    #ifdef FEATURE_MAC_SECURITY
            Rllc_securityFill(&dataReq.sec);
    #endif /* FEATURE_MAC_SECURITY */
            
            /* Send the message */
            if(ApiMac_mcpsDataReq(&dataReq) == ApiMac_status_success)
            {
    
            }
        }else if(macCallbacksCopy.pDataIndCb != NULL)
        {
            macCallbacksCopy.pDataIndCb(pData);
        }
    }
  • unfortunately there is no other way of doing this with less overhead. The main reason why there are no lower level APIs to do something like this is because this is not something that is part of the IEEE 802.15.4 specification.
  • Hi,

    A quick update:

    I am making good progress with my router application development. I am implementing a ZigBee based many-to-one/source routing mechanism with many-to-one route requests transmissions from the collector (concentrator) and route record transmissions from the router devices. This way my table creation and maintenance is minimal. As well as this I need to develop address conflict resolution as the parent device randomly chooses a short-address as per ZigBee stochastic addressing scheme.

    A question:

    I am curious as how the MAC msduhandle is used by ZigBee as it only 8-bits. The TI 15.4 stack uses msduhandle as a handle count (lowest 5-bits) and as a marker to an application message (upper 1-bit) leaving only 2 bits to identify the application message type:

    /* default MSDU Handle rollover */
    #define MSDU_HANDLE_MAX 0x1F
    
    /* App marker in MSDU handle */
    #define APP_MARKER_MSDU_HANDLE 0x80
    
    /* App Message Tracking Mask */
    #define APP_MASK_MSDU_HANDLE 0x60
    
    /* App Sensor Data marker for the MSDU handle */
    #define APP_SENSOR_MSDU_HANDLE 0x40
    
    /* App tracking response marker for the MSDU handle */
    #define APP_TRACKRSP_MSDU_HANDLE 0x20
    
    /* App config response marker for the MSDU handle */
    #define APP_CONFIGRSP_MSDU_HANDLE 0x60

    This leaves only three message types available for the application. So how does ZigBee cope with this limitation? Reducing MSDU_HANDLE_MAX seems the only option. There is no other way to determine the application message type from the data confirmation callback structure:

    /*! MCPS data confirm type */
    typedef struct _apimac_mcpsdatacnf
    {
        /*! Contains the status of the data request operation */
        ApiMac_status_t status;
        /*! Application-defined handle value associated with the data request */
        uint8_t msduHandle;
        /*! The time, in backoffs, at which the frame was transmitted */
        uint32_t timestamp;
        /*!
         The time, in internal MAC timer units, at which the frame was
         transmitted
         */
        uint16_t timestamp2;
        /*! The number of retries required to transmit the data frame */
        uint8_t retries;
        /*! The link quality of the received ack frame */
        uint8_t mpduLinkQuality;
        /*! The raw correlation value of the received ack frame */
        uint8_t correlation;
        /*! The RF power of the received ack frame in units dBm */
        int8_t rssi;
        /*! Frame counter value used (if any) for the transmitted frame */
        uint32_t frameCntr;
    } ApiMac_mcpsDataCnf_t;

    Any ideas?

    update:

    Now that I have posted, the answer is quite obvious. I need use all 8-bits of msduhandle as a handle count and save it to a table which also stores alongside it, the message type. I suppose the TI 15.4 stack did it without this code as it could squeeze everything into an octet. So my only question is, am I free to use all 8-bits of msduhandle?

  • Yes, you are free to use all 8bits, the MSDU handle is defined by the application and not the stack. The way that it is used in 15.4 Stack is just an example, you are free to modify how you use it. Another thing that you can use to identify application packets in the data cnf callback is by tracking the frameCntr
  • Hi,

    I have my network set up now so that a sensor can join the network via a router. Here is a packet capture showing one sensor joining the network. To simplify the address allocation the central coordinator records the short address of all nodes on the network and randomly creates a new address upon mac association, checking to make sure it doesn't match any previously allocated short addresses. To do this, when a sensor is joining via a router and issues an association request, the router sends a message to the coordinator which then responds with an association response type message back to the router. The parent router then sends out a mac association response allowing the joining device to fully associate. It is a requirement of my network that any joining device needs the would-be parent router to have communication back to the coordinator and as well as simplifying the address allocation, this mechanism also ensures this. I have implemented zigbee style route records and source routing here so that the coordinator can send a response back immediately along the same route that it received the association request.

    Question:

    In order for the sensor (joining device) to receive the association response, it issues a Data Request. As seen here, the time between issuing an Association Request and a follow-up Data Request is 0.941575s (macResponseWaitTime). Can you tell me where this time is defined? I might need to change it to allow for a large multi-hop association delay.

    Many thanks,

    Andy  

  • Hi,

    You can modify this value by calling the following API:
    ApiMac_mlmeSetReqUint8(ApiMac_attribute_responseWaitTime, YourValue)

    I believe the default value of this attribute is 48 if you are using 50kbps or 5kbps data rate. Also you can always do a ApiMac_mlmeGetReqUint8 to get the original value of the attribute and modify it based on that value.