*pBuf++=LO_UINT16(OutClusterList[i]);
*pBuf++=HI_UINT16(OutClusterList[i]);
}
}
//以上是进行网络地址,PROfileID,输入输出簇数量及其对应的簇的具体内容进行保存,保存在全局变量ZDP_TmpBuf中,并通过下面的函数fillAndSend函数发送
returnfillAndSend(&ZDP_TransID,dstAddr,Match_Desc_req,len);//注意簇ID为Match_Desc_req
}
while(zdpMsgProcs[x].clusterID!
=0xFFFF)//重点注意该函数及其结构体,里面有对应的根据簇ID进行相应处理的函数
{
if(zdpMsgProcs[x].clusterID==inMsg.clusterID)//注意该部分满足簇ID等于Match_Desc_req,会执行对应的处理函
数
{
zdpMsgProcs[x].pFn(&inMsg);
return;
}
x++;
}
上面重要的函数及其结构体的处理如下所示
typedefstruct
{
uint16clusterID;
pfnZDPMsgProcessorpFn;
}zdpMsgProcItem_t;
CONSTzdpMsgProcItem_tzdpMsgProcs[]=
{
{NWK_addr_req,zdpProcessAddrReq},
{IEEE_addr_req,zdpProcessAddrReq},
{Node_Desc_req,ZDO_ProcessNodeDescReq},
{Power_Desc_req,ZDO_ProcessPowerDescReq},
{Simple_Desc_req,ZDO_ProcessSimpleDescReq},
{Active_EP_req,ZDO_ProcessActiveEPReq},
{Match_Desc_req,ZDO_ProcessMatchDescReq},
}
由上面可以知道对应的处函数为ZDO_ProcessMatchDescReq
/*********************************************************************
*@fnZDO_ProcessMatchDescReq
*
*@briefThisfunctionprocessesandrespondstothe
*Match_Desc_reqmessage.
*
*@paraminMsg-incomingmessage(request)
*
*@returnnone
*/
voidZDO_ProcessMatchDescReq(zdoIncomingMsg_t*inMsg)
{
uint8epCnt=0;
uint8numInClusters;
uint16*inClusters=NULL;
uint8numOutClusters;
uint16*outClusters=NULL;
epList_t*epDesc;
SimpleDescriptionFormat_t*sDesc=NULL;
uint8allocated;
uint8*msg;
uint16aoi;
uint16profileID;
//Parsetheincomingmessage
msg=inMsg->asdu;
aoi=BUILD_UINT16(msg[0],msg[1]);//保存网络地址
profileID=BUILD_UINT16(msg[2],msg[3]);//保存空中接收过来的ProfileID
msg+=4;
if(ADDR_BCAST_NOT_ME==NLME_IsAddressBroadcast(aoi))
{
ZDP_MatchDescRsp(inMsg->TransSeq,&(inMsg->srcAddr),ZDP_INVALID_REQTYPE,
ZDAppNwkAddr.addr.shortAddr,0,NULL,inMsg->SecurityUse);
return;
}
elseif((ADDR_NOT_BCAST==NLME_IsAddressBroadcast(aoi))&&(aoi!
=ZDAppNwkAddr.addr.shortAddr))
{
ZDP_MatchDescRsp(inMsg->TransSeq,&(inMsg->srcAddr),ZDP_INVALID_REQTYPE,
ZDAppNwkAddr.addr.shortAddr,0,NULL,inMsg->SecurityUse);
return;
}
numInClusters=*msg++;
if(numInClusters)
{
inClusters=(uint16*)osal_mem_alloc(numInClusters*sizeof(uint16));
msg=ZDO_ConvertOTAClusters(numInClusters,msg,inClusters);//将空中传过来的输入簇列表进行整理保存
}
numOutClusters=*msg++;
if(numOutClusters)
{
outClusters=(uint16*)osal_mem_alloc(numOutClusters*sizeof(uint16));
msg=ZDO_ConvertOTAClusters(numOutClusters,msg,outClusters);//将空中传过来的输出簇列表进行整理保存
}
//Firstcountthenumberofendpointsthatmatch.//数出跟空中传过来消息匹配的端口数量
epDesc=epList;//保存本设备的注册端点列表
while(epDesc)
{
//Don'tsearchendpoint0andcheckifresponseisallowed
if(epDesc->epDesc->endPoint!
=ZDO_EP&&(epDesc->flags&eEP_AllowMatch))//本设备满条件:
端点号不为0并且允许匹配
{
if(epDesc->pfnDescCB)//?
?
?
什么意思处理的回调函数,该选项默认为NULL
{
sDesc=(SimpleDescriptionFormat_t*)epDesc->pfnDescCB(AF_DESCRIPTOR_SIMPLE,epDesc->epDesc->endPoint);
allocated=TRUE;
}
else
{
sDesc=epDesc->epDesc->simpleDesc;//保存本设备简单描述符在sDesc!
!
!
!
allocated=FALSE;
}
if(sDesc&&sDesc->AppProfId==profileID)//本设备的简单描述符不为空并且ProfileID等于空中传过来要匹配的ProfileID
{
uint8*uint8Buf=(uint8*)ZDOBuildBuf;
//Iftherearenosearchinput/ouputclusters-respond
if(((numInClusters==0)&&(numOutClusters==0))//或者输入簇数量跟输出簇数量为零
//Aretherematchinginputclusters?
||(ZDO_AnyClusterMatches(numInClusters,inClusters,
sDesc->AppNumInClusters,sDesc->pAppInClusterList))//或者空中输入簇和本设备的输入簇匹配
//Aretherematchingoutputclusters?
||(ZDO_AnyClusterMatches(numOutClusters,outClusters,
sDesc->AppNumOutClusters,sDesc->pAppOutClusterList))//或者空中输出簇和本设备的输出簇匹配)
{
//Notifytheendpointofthematch.公告匹配的设备
uint8bufLen=sizeof(ZDO_MatchDescRspSent_t)+(numOutClusters+numInClusters)*sizeof(uint16);
ZDO_MatchDescRspSent_t*pRspSent=(ZDO_MatchDescRspSent_t*)osal_msg_allocate(bufLen);
if(pRspSent)
{
pRspSent->hdr.event=ZDO_MATCH_DESC_RSP_SENT;
pRspSent->nwkAddr=inMsg->srcAddr.addr.shortAddr;//保存空中源地址
pRspSent->numInClusters=numInClusters;
pRspSent->numOutClusters=numOutClusters;
if(numInClusters)
{
pRspSent->pInClusters=(uint16*)(pRspSent+1);
osal_memcpy(pRspSent->pInClusters,inClusters,numInClusters*sizeof(uint16));//将空中的输入簇列表进行了保存
}
else
{
pRspSent->pInClusters=NULL;
}
if(numOutClusters)
{
pRspSent->pOutClusters=(uint16*)(pRspSent+1)+numInClusters;
osal_memcpy(pRspSent->pOutClusters,outClusters,numOutClusters*sizeof(uint16));//将空中的输出簇列表进行了保存
}
else
{
pRspSent->pOutClusters=NULL;
}
osal_msg_send(*epDesc->epDesc->task_id,(uint8*)pRspSent);//
}
uint8Buf[epCnt++]=sDesc->EndPoint;
}
}
if(allocated)
osal_mem_free(sDesc);
}
epDesc=epDesc->nextDesc;//找下一个端点
}
//Sendthemessageonlyifatleastonematchfound.
if(epCnt)
{
if(ZSuccess==ZDP_MatchDescRsp(inMsg->TransSeq,&(inMsg->srcAddr),ZDP_SUCCESS,
ZDAppNwkAddr.addr.shortAddr,epCnt,(uint8*)ZDOBuildBuf,inMsg->SecurityUse))//见下
{
#ifdefined(LCD_SUPPORTED)
HalLcdWriteScreen("MatchDescReq","RspSent");
#endif
}
}
else
{
#ifdefined(LCD_SUPPORTED)
HalLcdWriteScreen("MatchDescReq","NonMatched");
#endif
}
if(inClusters)
osal_mem_free(inClusters);
if(outClusters)
osal_mem_free(outClusters);
}
/*
*ZDP_MatchDescRsp-Sendanlistofendpointthatmatch
*/
#defineZDP_MatchDescRsp(TransSeq,dstAddr,Status,nwkAddr,Count,\
pEPList,SecurityEnable)\
ZDP_EPRsp(Match_Desc_rsp,TransSeq,dstAddr,Status,\
nwkAddr,Count,pEPList,SecurityEnable)//注意簇ID为Match_Desc_rsp
*********************************************************************
*@fnZDP_EPRsp
*
*@briefThisbuildsandsendanendpointlist.Usedin
*Active_EP_rspandMatch_Desc_Rsp
*message.Thisfunctionsendsunicastmessagetothe
*requestingdevice.
*
*@paramMsgType-eitherActive_EP_rsporMatch_Desc_Rsp
*@paramdstAddr-destinationaddress
*@paramStatus-messagestatus(ZDP_SUCCESSorother)
*@paramnwkAddr-Device'sshortaddressthatthisresponsedescribes
*@paramCount-numberofendpoint/interfacesinlist
*@parampEPIntfList-ArrayofEndpoint/Interfaces
*@paramSecurityEnable-SecurityOptions
*
*@returnafStatus_t
*/
afStatus_tZDP_EPRsp(uint16MsgType,byteTransSeq,zAddrType_t*dstAddr,
byteStatus,uint16nwkAddr,byteCount,
byte*pEPList,
byteSecurityEnable)
{
byte*pBuf=ZDP_TmpBuf;
bytelen=1+2+1;//Status+nwkAddr+endpoint/interfacecount.
bytetxOptions;
if(MsgType==Match_Desc_rsp)
txOptions=AF_MSG_ACK_REQUEST;
else
txOptions=0;
*pBuf++=Status;
*pBuf++=LO_UINT16(nwkAddr);
*pBuf++=HI_UINT16(nwkAddr);//分装本设备的网络地址
*pBuf++=Count;//Endpoint/Interfacecount//簇匹配的数量
if(Count)
{
len+=Count;
osal_memcpy(pBuf,pEPList,Count);
}
FillAndSendTxOptions(&TransSeq,dstAddr,MsgType,len,txOptions);
}
#defineFillAndSendTxOptions(TRANSSEQ,ADDR,ID,LEN,TxO){\
afStatus_tstat;\
ZDP_TxOptions=(TxO);\
stat=fillAndSend((TRANSSEQ),(ADDR),(ID),(LEN));\
ZDP_TxOptions=AF_TX_OPTIONS_NONE;\
returnstat;
staticafStatus_tfillAndSend(uint8*transSeq,zAddrType_t*addr,cId_tclusterID,bytelen)
{
afAddrType_tafAddr;
ZADDR_TO_AFADDR(addr,afAddr);
*(ZDP_TmpBuf-1)=*transSeq;
returnAF_DataRequest(&afAddr,&ZDApp_epDesc,clusterID,
(uint16)(len+1),(uint8*)(ZDP_TmpBuf-1),
transSeq,ZDP_TxOptions,AF_DEFAULT_RADIUS);
}
voidZDApp_ProcessOSALMsg(osal_event_hdr_t*msgPtr)
{
//DataConfirmationmessagefields
bytesentEP;//Thisshouldalwaysbe0
bytesentStatus;
afDataConfirm_t*afDataConfirm;
switch(msgPtr->event)
{
//IncomingZDOMessage
caseAF_INCOMING_MSG_CMD:
ZDP_IncomingData((afIncomingMSGPacket_t*)msgPtr);
break;
caseZDO_CB_MSG:
Z