Other Parts Discussed in Thread: Z-STACK
Tool/software: TI-RTOS
Check the file bdb_finding_and_binding.c in every version of z-stack and search the variable bdb_FindingBindingTargetSimpleDesc.
This struct-type variable has to member, pAppInClusterList and pAppOutClusterList. They will be allocated memory buffer by ZDO_ParseSimpleDescBuf when bdb_ProcessSimpleDesc is called, but it will not be free when bdb_ProcessIEEEAddrRsp binding success. The bdb_FindingBindingTargetSimpleDesc needs to be freed by bdb_zclSimpleDescClusterListClean when bdb_ProcessIEEEAddrRsp finish.
so the function bdb_ProcessIEEEAddrRsp need to be fix like this
void bdb_ProcessIEEEAddrRsp(zdoIncomingMsg_t *pMsg)
{
ZDO_NwkIEEEAddrResp_t *pAddrRsp = NULL;
bdbFindingBindingRespondent_t *pCurr = NULL;
pAddrRsp = ZDO_ParseAddrRsp( pMsg );
if(pAddrRsp == NULL)
{
return;
}
bdb_setEpDescListToActiveEndpoint();
pCurr = bdb_findRespondentNode(bdb_FindingBindingTargetSimpleDesc.EndPoint, pAddrRsp->nwkAddr);
//Does the entry exist and we were waiting an IEEE addr rsp from this device?
if((pCurr != NULL) && (pCurr->attempts > FINDING_AND_BINDING_MISSING_IEEE_ADDR))
{
if(pAddrRsp->status == ZSuccess )
{
uint8 extAddr[8];
AddrMgrEntry_t entry;
entry.nwkAddr = pAddrRsp->nwkAddr;
entry.user = ADDRMGR_USER_BINDING;
AddrMgrExtAddrSet(entry.extAddr, pAddrRsp->extAddr);
//Add it as bind entry
if(AddrMgrEntryUpdate(&entry) == FALSE)
{
//No space, then report F&B table full
//If periodic was triggered, then finish it
if(FINDING_AND_BINDING_PERIODIC_ENABLE == TRUE)
{
bdb_FB_InitiatorCurrentCyclesNumber = 0;
osal_stop_timerEx(bdb_TaskID, BDB_FINDING_AND_BINDING_PERIOD_TIMEOUT);
}
bdb_zclSimpleDescClusterListClean( &bdb_FindingBindingTargetSimpleDesc );
osal_stop_timerEx( bdb_TaskID, BDB_RESPONDENT_PROCESS_TIMEOUT );
bdb_exitFindingBindingWStatus( BDB_COMMISSIONING_FB_BINDING_TABLE_FULL );
return;
}
//search for the matching clusters to be added this time as we have the IEEE addrs
bdb_checkMatchingEndpoints(TRUE, pAddrRsp->nwkAddr, &pCurr);
(void)extAddr; //dummy
}
//Bind cannot be added if the device was not found
pCurr->attempts = FINDING_AND_BINDING_RESPONDENT_COMPLETE;
}
//release the memory
osal_mem_free( pAddrRsp );
bdb_zclSimpleDescClusterListClean( &bdb_FindingBindingTargetSimpleDesc );// SimpleDesc needs to be freed.
}
and bdb_ProcessSimpleDesc also need to be fix
void bdb_ProcessSimpleDesc( zdoIncomingMsg_t *msgPtr )
{
zAddrType_t dstAddr;
bdbFindingBindingRespondent_t *pCurr = NULL;
uint8 isRespondantReadyToBeAdded = FALSE;
bdb_setEpDescListToActiveEndpoint();
if ( !(bdb_CurrEpDescriptorList->epDesc->epType & BDB_FINDING_AND_BINDING_INITIATOR ))
{
//We should not be processing these commands as we are not initiator
return;
}
dstAddr.addr.shortAddr = BUILD_UINT16( msgPtr->asdu[1], msgPtr->asdu[2] );
dstAddr.addrMode = Addr16Bit;
bdb_zclSimpleDescClusterListClean( &bdb_FindingBindingTargetSimpleDesc ); // make sure it has been freed.
ZDO_ParseSimpleDescBuf( &msgPtr->asdu[4], &bdb_FindingBindingTargetSimpleDesc );
pCurr = bdb_findRespondentNode(bdb_FindingBindingTargetSimpleDesc.EndPoint, dstAddr.addr.shortAddr);
//Just for safety check this is a valid entry
if(pCurr != NULL)
{
uint8 extAddr[Z_EXTADDR_LEN];
if(AddrMgrExtAddrLookup( pCurr->data.addr.shortAddr, extAddr ))
{
isRespondantReadyToBeAdded = TRUE;
}
else
{
//Save the simple desc to don't ask for it again
pCurr->SimpleDescriptor = &bdb_FindingBindingTargetSimpleDesc;
}
(void)extAddr; //dummy
}
else
{
//This simple desc rsp was not requested by BDB F&B
return;
}
bdb_checkMatchingEndpoints(isRespondantReadyToBeAdded, dstAddr.addr.shortAddr, &pCurr);
//If the respondent got process complete, then release the entry
if(pCurr->attempts == FINDING_AND_BINDING_RESPONDENT_COMPLETE)
{
bdb_zclSimpleDescClusterListClean( &bdb_FindingBindingTargetSimpleDesc );
}
}