We have a situation where an AP needs to be aware of whether or not an ED is attempting to relink with the AP. I've been trying to figure out what is going on, but the stack seems to be automatically serving the link reply without any notice anywhere.
Process:
1) Link an ED and an AP (waiting for SMPL_SUCCESS on SMPL_LinkListen() )
2) Clear the connection from the ED, and try to relink the ED using SMPL_LinkListen()
I'm not receiving a SMPL_SUCCESS from the function (even though it is the only time that the LinkListen context is on). Is there any way to recognize this sort of situation in the SimpliciTI stack?
Hi Joshua,
Joshua Einstein 2) Clear the connection from the ED, and try to relink the ED using SMPL_LinkListen()
How do you clear the connection? Are you using SMPL_Unlink() this will generate an unlink request message to the AP, so that the AP should be able to delete the connection at his side also.
see the following functions which will be executed on the following sequence when the AP receives the unlink request:
- MRFI_RxCompleteISR() in nwk_frame.c
- dispatchFrame() in nwk_frame.c
- nwk_processLink() in nwk_link.c
- handleLinkRequest() in nwk_link.c
- smpl_send_unlink_reply() in nwk_link.c -> will call nwk_freeConnection().
Regards,
Leo Hendrawan
What I'm trying to figure out is how to recognize an ED that sends additional link messages. If the link context is only on during the LinkListen function, how does the stack handle a device that is already linked but still sends a link message? What will the SMPL_LinkListen function return?
We can't use SMPL_Unlink to clear the connection from the ED as the ED is asleep for most of its life. I'm currently using NVOBJECT to restore the ED connection on startup, and I'm "clearing" the ED connection by ignoring the saved NVOBJECT data and attempting to relink.
On the AP side, the ED is removed using a SMPL_Unlink or call, but it doesn't expect to hear a reply from the ED. This is actually working out well for us!
AFAIK, there is no way the application level will get notified when receiving messages with NWL applications (port number between 0x01 - 0x07). The callback function pointer given to SMPL_Init() function will be called only when the port belongs to application port. See the dispatchFrame() fuinction in nwk_frame.c for the details.
Joshua Einstein What I'm trying to figure out is how to recognize an ED that sends additional link messages. If the link context is only on during the LinkListen function, how does the stack handle a device that is already linked but still sends a link message? What will the SMPL_LinkListen function return? ..................... On the AP side, the ED is removed using a SMPL_Unlink or call, but it doesn't expect to hear a reply from the ED. This is actually working out well for us!
.....................
I think after the AP calls SMPL_Unlink(), you shall then try to listen again by calling SMPL_LinkListen() periodically. If the ED sends a new link request, the SMPL_LinkListe() should return success.
Lhend-
Sorry not to be as clear as I should. The problem I'm running into is slightly different. If I cause the ED to forget the AP, and then set the AP into LinkListen to relink the ED, I'm not getting a SMPL_SUCCESS, but a link reply is sent. What I need to do for my application is recognize that a link reply was sent to an already linked device to enable a change of state. I'm not sure why I'm not seeing a success though!
Joshua,
now it's clear for me what the real problem is (sorry for misunderstanding it).
How many EDs do you have actually? and how many of them will try to relink to the AP at the same time? Have you set the NUM_CONNECTIONS correctly?
Is it possible for you to debug the AP when it replies the link request for the second time? If yes, can you put a breakpoint at nwk_link.c (i am referring to the v1.2.0 code) smpl_send_link_reply() function at this code part:
----------------------------------------------------------------------------
/* The local Rx port is the one returned in the connection structure. The * caller is waiting on this to be set. The code here is running in an ISR * thread so the caller will see this change after RETI. */ if (NUM_CONNECTIONS == sNumLinkers) { /* Something is wrong -- no room to stack Link request */ nwk_freeConnection(pCInfo); /* we're done with the packet */ return SENT_REPLY; } sServiceLinkID[sNumLinkers++] = pCInfo->thisLinkID;
is the last line there executed and what is the value of sNumLinkers variable?
Leo-
I'm using SimpliciTI 1.1.1 with a project about to head out the door on CCS v5.1. Trying to link a new device, I reach that breakpoint and sNumLinkers increments to 1. Trying to link a device that is already linked, I don't even reach that breakpoint.
We have a bunch of EDs, but everything is done sequentially. Only one ED is dealt with at a time, and only one is going to be in link mode at any given time.
I noticed in the changelog for SimpliciTI that you are no longer supporting CCS with 1.2.0? Is there anything I should be aware of before I try upgrading the SimpliciTI stack?
Thanks
Josh E
I'm thinking there is something going on in the nwk_findAlreadyJoined() function
Joshua Einstein I'm using SimpliciTI 1.1.1 with a project about to head out the door on CCS v5.1. Trying to link a new device, I reach that breakpoint and sNumLinkers increments to 1. Trying to link a device that is already linked, I don't even reach that breakpoint.
That is quite strange, could check another thing please?
in the same function smpl_send_link_reply(), when trying to link a device which is already linked, do you get into this code part?
------------------------------------------------------------------------------------
/* is this a duplicate request? */ remotePort = *(MRFI_P_PAYLOAD(frame)+F_APP_PAYLOAD_OS+L_RMT_PORT_OS); if (pCInfo=nwk_isLinkDuplicate(MRFI_P_SRC_ADDR(frame), remotePort)) { /* resend reply */ msg[LB_REQ_OS] = LINK_REQ_LINK | NWK_APP_REPLY_BIT;
/* sender's TID */ msg[LB_TID_OS] = *(MRFI_P_PAYLOAD(frame)+F_APP_PAYLOAD_OS+LB_TID_OS);
/* Send reply with the local port number so the remote device knows where to * send packets. */ msg[LR_RMT_PORT_OS] = pCInfo->portRx;
If yes, that would be strange, because you basically should have erased the connection previously using SMPL_Unlink() which should call nwk_freeConnection().
Could you debug/show the sPersistInfo structure in nwk.c after you call SMPL_Unlink() (breakpoint at nwk_freeConnection()) and also at nwk_isLinkDuplicate() which should be called during the re-link?
Joshua Einstein I noticed in the changelog for SimpliciTI that you are no longer supporting CCS with 1.2.0? Is there anything I should be aware of before I try upgrading the SimpliciTI stack?
I do get into that code segment when linking an already linked device.
I noticed this in the changelog and wonder if it is related:
"Correctly Free connection table status in nwk_link function.
Failure to free connection table entry when link packet failed to betransmitted caused connection table entries to be exhausted andunusable."
Debug info:
nwk_freeconnection() breakpoint on relink shows a next linkID of 5. What information would you like from the sPersistInfo?
I can't get the new version of SimpliciTI to play nicely with my project as there look to be some significant differences to the files, types, and similar (variable and #define additions among others).
Joshua Einstein I'm thinking there is something going on in the nwk_findAlreadyJoined() function
I would actually think that in both cases (new link, or second link), both have to go through the second way. However if you said that in the second link, you never reach the line above, it means the function exits after the first way. However again, i don't think this is possible since the nwk_isLinkDuplicate() should return NULL in both cases because it looks only for connected state, but even in second link, the link should be in free state.
Hope you understand my way of thinking and can debug further. Would be nice if you can share the result with others here.
Joshua Einstein nwk_freeconnection() breakpoint on relink shows a next linkID of 5. What information would you like from the sPersistInfo?
basically if you can show the whole connStruct[] member of sPersistInfo after freeing the connection with SMPL_Unlink() and when doing the second link, it would be helpful i guess.
Joshua Einstein I do get into that code segment when linking an already linked device.
This should explain why your SMPL_LinkList() fails when relinking. The next question is why does the code get into that code segment. As i said, check every connection state (connState) of connStruct[] of sPersistInfo after freeing the connection and also in nwk_isLinkDuplicate() when trying to do the relink.
Unfortunately i got to go now, good luck for the debugging and have a nice weekend :)
Okay.
This actually makes sense now, as an already linked device would return as a duplicate device since it is already in the connection table. That's reasonable. I guess the next question then becomes, does the new version of SimpliciTI better handle this, or would I need to build in custom semaphores to test this? The logic makes sense in case there is bad transmission, so I just need some way of handling this myself.
Thanks for the clarification. I guess I can call this "expected behavior"
now i'm online from home :)
Joshua Einstein This actually makes sense now, as an already linked device would return as a duplicate device since it is already in the connection table.
This actually makes sense now, as an already linked device would return as a duplicate device since it is already in the connection table.
No, actually it doesn't make sense to me. Indeed the data from the previous connection is still available in the table, but the table itself has been marked as invalid/free as soon as it is passed to the nwk_freeConnection() when you call the SMPL_Unlink().
So i think we still need to find out why this happen.
Leo,
The duplicate message is occurring if I try to relink a device BEFORE calling SMPL_Unlink. What I've been trying to do is find a way for my application to recognize when a duplicate link message is sent back to a device. Your information about the linking process definitely helped me track down what was going on, and it looks like this is the expected behavior in the stack, for example if a device sends 2+ link messages before finalizing its link.
The problem with this is that some sort of a timeout would be nice so that if another link message is received after, say, 5 minutes, then the smpl_linklisten function would return a SMPL_DUPLICATE_LINK or similar. This would require the stack to have the capability to be integrated with a program timer, though, which currently it is not setup for.
I'm going to have to think about this one. Maybe changing the stack so a duplicate link message first calls SMPL_IOCTL(delete) and then attempts a relink?