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.

Unlinking/Relinking End Devices in SimpliciTi

Other Parts Discussed in Thread: SIMPLICITI

I've seen this topic on this forum several times. I know SimpliciTi won't support this capability until v1.1.0 (unknown release date?). I suspect that plenty of people know how to do this and have done it, but besides Markus's guidelines, I haven't seen any other useful tips here. I'm making this post for two reasons: so people can learn from what I've done, and so the more knowledgeable may be able to warn me if I'm doing something "unsafe." Personally, I need to be able to unlink/relink devices because my network will evntually contain more end devices than the AP will be able to support at one time. I'll want to disconnect end devices from time to time, so that other end devices can link to the access point.

I was able to implement unlinking/relinking successfully with a v1.0.5 protocol that I ported to CCE. (v1.0.5? Yeah, I had trouble with the port of v1.0.6, but that's another topic) Anyways, I suspect that my methods will work with v1.0.6, but I have not tested that version. For my test setup, I had an AP acting as a data hub and one polling end device.

For the AP, The disconnection occurs in two basic steps.

1) nwk_freeConnection() is executed when you make a call to the api function SMPL_Ioctl(IOCTL_OBJ_CONNOBJ, IOCTL_ACT_DELETE, &lid);

2) nwk_freeConnection calls nwk_disconnect and nwk_QdiscardFrames

For the polling ED, I have it calling SMPL_Receive on a periodic basis. If the poll returns anything besides SMPL_SUCCESS or SMPL_NO_FRAME (as it will after the AP performs its disconnection routine), I know something is wrong with the connection.  I have the end device attempt to reconnect by calling SMPL_Init to join and then SMPL_Link to link. Importantly, I make a call to the api function SMPL_Ioctl(IOCTL_OBJ_CONNOBJ, IOCTL_ACT_DELETE, &lid) to free the resources of the faulty connection before I attempt to reconnect.

In summary, the AP disconnects the end device at will, and then the end device can detect this and recover by forming a new connection. In the future, I will be disconnecting an end device to allow a different end device to connect to the access point.

If I had any one question for the more knowledgeable, it would be, is my function nwk_QdiscardFrames safe? I discard the store and forward frames for the removed end device in my AP's output queue by looping through the output queue and changing the fi_usage of the frames to FI_AVAILABLE. It seems to work...

Of course, if you see me doing something else that isn't particularly wise, I'd like to know.

And here's the important bits of my code:

Changes in nwk_join.c:
- Added nwk_disconnect function that removes an end device from sJoinedED and sSandFClients tables.

/******************************************************************************
 * @fn          nwk_disconnect
 *
 * @brief       Disconnect ED by removing it from store and forward table and
 *                 joined end devices table.
 *
 * input parameters
 * @param   address  -  address of device to remove
 *
 * output parameters
 *
 * @return   void
 */
void nwk_disconnect(addr_t *addr)
{
    uint8_t i, j;
   
    /* Find address in sJoinedED, then shift remaining addresses down over the top of it. */
    for (i = 0; i < NUM_CONNECTIONS; i++)
    {
        if (!memcmp(&sJoinedED[i].addr, addr, NET_ADDR_SIZE))
        {
            for (j = i; j < NUM_CONNECTIONS - 1; j++)
            {
                memcpy(&sJoinedED[j], &sJoinedED[j + 1], NET_ADDR_SIZE);
            }
            memcpy(&sJoinedED[j], 0, NET_ADDR_SIZE);
            sNumJoined--;
        }
    }
   
    /* Find address in sSandFClients, then shift remaining addresses down over the top of it. */
    for (i = 0; i < NUM_STORE_AND_FWD_CLIENTS; i++)
    {
        if (!memcmp(&sSandFClients[i].addr, addr, NET_ADDR_SIZE))
        {
            for (j = i; j < NUM_STORE_AND_FWD_CLIENTS - 1; j++)
            {
                memcpy(&sSandFClients[j], &sSandFClients[j + 1], NET_ADDR_SIZE);
            }
            memcpy(&sSandFClients[j], 0, NET_ADDR_SIZE);
            sCurNumSandFClients--;
        }
    }
}

Changes to nwk_QMgmt.c:
- Added nwk_QdiscardFrames to remove all store and forward frames from output queue destined for the removed end device.

/******************************************************************************
 * @fn          nwk_QdiscardFrames
 *
 * @brief       Discard all the frames in the output queue corresponding to
 *                 particular device address
 *
 * input parameters
 * @param   lid   - dispose all frames destined for this device address
 */
void nwk_QdiscardFrames(addr_t *addr)
{
    uint8_t i;
    frameInfo_t *fiPtr = sOutFrameQ;
   
    /* Loop through output queue and mark output frames being sent to particular device
     * as available space in buffer */
    for (i=0; i<SIZE_OUTFRAME_Q; ++i, fiPtr++)
    {
        if (FI_INUSE_UNTIL_FWD == fiPtr->fi_usage)
        {
            if (memcmp(MRFI_P_DST_ADDR(&fiPtr->mrfiPkt), addr, NET_ADDR_SIZE))
            {
                fiPtr->fi_usage = FI_AVAILABLE;
            }
        }
    }       
}

Changes to nwk.c:
- call nwk_disconnect and nwk_QdiscardFrames in nwk_freeConnection to remove connection from access point

/******************************************************************************
 * @fn          nwk_freeConnection
 *
 * @brief       Return the connection structure to the free pool. Currently
 *              this routine is only called when a link freame is sent and
 *              no reply is received so the freeing steps are pretty simple.
 *              But eventually this will be more complex so this place-holder
 *              is introduced.
 *
 * input parameters
 * @param   pCInfo    - pointer to entry to be freed
 *
 * output parameters
 *
 * @return   None.
 */
void nwk_freeConnection(connInfo_t *pCInfo)
{
#if NUM_CONNECTIONS > 0
  pCInfo->isValid = 0;

#ifdef ACCESS_POINT 
  /* Remove device from sSandFClients and sJoinedED in nwk_join.c */
  nwk_disconnect((addr_t *)pCInfo->peerAddr);
 
  /* Remove all frames from output queue for device. */
  nwk_QdiscardFrames((addr_t *)pCInfo->peerAddr);
#endif

#endif
}

 

  • Hello.

    Your approach is bascially sound. I have a few comments.

    1. The new 1.1.0 mechanism implements somthing similar to you method and amends it by sending a message to the peer. It is possible, as in your case, that the peer is not listening. In that case a solution such as yours will still be necessary. The device could miss the disconnect frame and therefore not participate in the session. In that case the device is on its own.
    2. The processing of the output queue on the AP to purge S&F frames is also OK. There is no cast-out (aging) scheme for the output like there is for the input queue. The cast-out occurs in nwk_QMgmt.c::nwk_QfindSlot().
    3. In your discard frames method just changing the state variable in the frame object will work to make resource available. The queues are not linked lists and operations on them are accomplished by exhaustively walking the queue.
    4. If you port 1.1.0 you will not need the nwk_disconnect() routine. First, the 'sJoinedED' object is no longer there. The scheme for tracking joined devices was changed because the 'sJoinedED' array was redundant and caused extra processing if the peer unlinked (as you found out).  The second half of the routine, purging the S&F client list also had to be done anyway once Unlink was implemented. There are still some open issues for the unlink case when one of the peers is a polling devce and the AP is not the peer. These will be called out in release notes. But it doesn't sound as if this will affect your scenario.

    Hope this helps.

    lfriedman

     

  • I had time to fiddle with the 1.0.6 port, and I got it working with the above unlinking/relinking scheme for ONE polling end device. I noticed that v1.0.6 had many of the unlinking functions already in place, and some even implemented or partially implemented. I didn't attempt to use any of those functions however; I just kept with the above scheme.

    Although things seem to work with one end device, there are definitely some issues with multiple end devices. Devices aren't always capable of relinking once I "delete" them from the access point. This indicates to me that I'm not cleaning up the resources properly. I know when a device is linked, it gets placed in the connection table in nwk.c as well as the join tables in nwk_join.c. I believe I took care of removing a device from those places adequately. Something I'm not too sure about is how the application ports are defined or if I need to take them into account when deleting a connection.

    The relinking problems seem to correlate with how quickly I delete the devices and/or which device gets deleted first. If I delete the end device that has the highest link ID, then the access point seems capable of relinking that device repeatedly. But if I delete a device with a lower link ID, or try to delete many devices in quick succession, relinking problems occur. But please take these observations with a grain of salt. I haven't been able to nail down any definite patterns (or I would have likely already fixed the issue).

  • Hi Sir, I am currently using simpliciTI 1.0.6 and I need to implement disconnect since I place two AP either side of my room whenever I corners of my room one should dissconnect and other should connect and when I disconnect it should clear the linkID from RAM.And I didnt see the disconnect supporting in 1.0.6 version do you have any patch support for it. Where could I get the latest version simpliciTI 1.1.0 version is this portable to CCE.When I want to implement disconnect feature, should I implement in AP or End Device.Waiting for your support and guidance

    Thanks & Regards

    Umamahesh Y V

  • chipcon RF transceivers range said:

    Hi Sir, I am currently using simpliciTI 1.0.6 and I need to implement disconnect since I place two AP either side of my room whenever I corners of my room one should dissconnect and other should connect and when I disconnect it should clear the linkID from RAM.

    I think you'll have to make the join token for the end device variable. And each of the access points will need a different join token.

    chipcon RF transceivers range said:

    And I didnt see the disconnect supporting in 1.0.6 version do you have any patch support for it.

    Unfortunately, I do not have a patch. You'll notice that I never got things completely working from the above posting. I had to divert my efforts elsewhere, but now I may have some time to start looking at the disconnect functionality again. The good news is that I think my troubles were caused by how I was attempting to re-link the end devices and not by how I was deleting the connections.

    chipcon RF transceivers range said:

    Where could I get the latest version simpliciTI 1.1.0 version is this portable to CCE.

    I'm not aware of any release date for SimpliciTI 1.1.0, and every time I kind-of asked, the question always got side-stepped. I'm going to assume that if support for CCE isn't made available by TI when v1.1.0 comes out, someone in the community will post a port like they did for v1.0.6. Of course, you could always port it yourself. It's really not much more complicated than going through all the protocol's files and ensuring that static variables are explicitly initialized to zero, because CCE doesn't do this. I personally think it's rather poor programming practice to depend on a compiler to initialize your variables for you, but maybe the TI guys have good reason for it. They're no doubt better programmers than me.

    chipcon RF transceivers range said:

    When I want to implement disconnect feature, should I implement in AP or End Device.

    The three disconnect functions are added to the protocol as detailed above, so they're compiled into the object code for both the access point and end device. The nwk_freeConnection function contains a compiler directive #ifdef ACCESS_POINT, which control's what code is included for the particular kind of network device (AP or ED).

     

  • Hello.

    A couple of comments:

    1. Unlinking wil be supported in a formal manner in Release 1.1.0. Using separate Join tokens is a good suggestion. Though SimpliciTI was not specifically designed to support such scenarios (multiple APs) it can do so with some thought toward the design of the applications. But the scenario may be more complex depending on the specific requirements of the topology. More specific information might lead to a better solution in this dsicussion.
    2. Release 1.1.0 is scheduled for release at the end of March. CCE will be fully supported.

    Hope this helps.

    lfriedman

     

  • Hi!.

    I'm working with SimpliciTI v1.1.0 and my project is based on "AP_as_Data_Hub". By now I only have one End Device and two Access Points. These are their networks parameters:

    • AP1
      • Address: 0x78,0x56,0x34,0x01
      • Join Token: 0x05060708
      • Link Token: 0x01020304
      • Max connections: 9
    • AP2
      • Address: 0x78,0x56,0x34,0x01
      • Join Token: 0x05060709
      • Link Token: 0x01020305
      • Max connections: 9
    • ED
      • Address: 0x78,0x56,0x34,0x02
      • Join Token: Depends on the network is joined in
      • Link Token: Depends on the network is linked in

    The End Device is switching between the two AP, so it has to perform a link and unlink action. The steps done by the ED are:

    1. Set the Join and Link token values of the network he wants to join. (AP1 or AP2)
    2. SMPL_Init (..);
    3. SMPL_Link(...);
    4. Send to and Receive data from AP (1 or 2)
    5. SMPL_Unlink(..);
    6. Go to step 1.

    Each time the End Device joins and links into an AP network, the AP decreases in one the total available connections. The problem is that when the End Device joins again over the same AP network, the AP decreases again the total available connections. After 9 iterations (max connections), all the available AP connections are used and the End Device cannot perform any link or join connection to either AP1 or AP2. Sorry if the explanation if a bit confusing or not very clear.

    Does anybody know why the AP don't empty their connecion table when it receives an unlink request from an End Device? As I read in this post, the new SimpliciTI release 1.1.0 has the unlink and link process solved and implemented.

    Is there necessary to implement any special call in the AP side to empty the connecion tables?

    Thank you very much in advance and sorry for my bad english.

    Best regards,

    David.

  • Hi David,

    I meet the exactly same problem as you. Did you solve it? Could you tell me how to fix it ?

    Many thanks,

    Sun Li

  • Hi Sun Li,

     

    I didn't solve the problem and I decided to change the philosophy of how my network had to work. Now there is not AP and all the devices send and receive data using the Link ID “SMPL_LINKID_USER_UUD”. This link ID allows me to send and receive data without needing to perform a link or unlink action.

    Hope this helps you.

    Best regards,

    David.

  • HI David,

    Thanks for your reply. But my case is different form yours. Part of my project is sending data from Sd card to computer with rf block. As the sd card and rf block share the same connections, the infinite swtch between sd card and rf block is requested. So initial network, link and unlink must be a loop. Do you have any suggestions?

    Thanks,

    Sun Li

  • Hi lfriedman,

    I am using SimpliciTi, peer to peer two EDs. The LinkTo(ED1) device has to break the link after a particular response from the LinkListener(ED2).  ED1 sends unlink request then ED2 sent unlink_reply as a response.

    When ED1 receives unlink_reply from ED2, it does not call IRQ handler function. But for all other transaction the same IRQ handler has been called and serviced.

     

    I checked RFIF, S1CON, TCON registers during debug, all relevant bits are asserted but the IRQ handler function was not called.

    Can you please help me to solve the issue.

     

    Thanks

    Sat