📄 swszigbeenwk.c
字号:
// PARAMETERS:
// ADDRESS deviceAddress
// The extended address of the device requesting association
// BYTE capabilityInformation
// The operational capabilities of the device requesting association
// CI_ALTERNATE_PAN_COORD_BM 0x01
// CI_DEVICE_TYPE_IS_FFD_BM 0x02
// CI_POWER_SOURCE_BM 0x04
// CI_RX_ON_WHEN_IDLE_BM 0x08
// CI_SECURITY_CAPABILITY_BM 0x40
// CI_ALLOCATE_ADDRESS_BM 0x80
// ZBOOL securityUse
// An indication of whether the received MAC command frame is using security. This value set to
// TRUE if the security enable subfield was set to 1 or FALSE if the security enabled subfield
// was set to 0
// UINT8 aclEntry
// The macSecurityMode parameter value from the ACL entry associated with the sender of the
// data frame. This value is set to 0x08 if the sender of the data frame was not found in the
// ACL.
//-------------------------------------------------------------------------------------------------------
void mlmeAssociateIndication(ADDRESS* deviceAddress, BYTE capabilityInformation, ZBOOL securityUse, UINT8 aclEntry)
{
UINT16 invalidShortAddress;
BYTE i;
invalidShortAddress=0xFFff;
//use the long address of the device.
ByteArrayContentCopy(macAssociateIndicationInfo.deviceAddress.Extended, deviceAddress->Extended, 8);
macAssociateIndicationInfo.capabilityInformation=capabilityInformation;
macAssociateIndicationInfo.securityUse=securityUse;
macAssociateIndicationInfo.aclEntry=aclEntry;
//prepare the parameter for the mlmeAssociateResponse function.
ByteArrayContentCopy(macAssociateResponseInfo.deviceAddress.Extended,deviceAddress->Extended,8);
if (NWKLookupNodeByLongAddr(macAssociateIndicationInfo.deviceAddress.Extended) != INVALID_NEIGHBOR_INDEX)
{
macAssociateResponseInfo.assocShortAddress= currentNeighborRecord.shortAddress;
macAssociateResponseInfo.status=ASSOCIATION_SUCCESS;
mlmeAssociateResponse(&macAssociateResponseInfo.deviceAddress, macAssociateResponseInfo.assocShortAddress, macAssociateResponseInfo.status, macAssociateIndicationInfo.aclEntry);
}
else
{
//if there is enough resource in the neighbor table to add the device
if (CanAddChildNode())
{
if ((CanAddNeighborNode()) != INVALID_NEIGHBOR_INDEX)
{
AddChildNode();
// Save off the Capability Information, so we can send it back with the NLME_JOIN_indication
// after we get the MLME_ASSOCIATE_response.
macAssociateResponseInfo.assocShortAddress= currentNeighborRecord.shortAddress;
macAssociateResponseInfo.status=ASSOCIATION_SUCCESS;
mlmeAssociateResponse(&macAssociateResponseInfo.deviceAddress, macAssociateResponseInfo.assocShortAddress, macAssociateResponseInfo.status, macAssociateIndicationInfo.aclEntry);
}
}
//there is no capacity!!
macAssociateResponseInfo.status= ASSOCIATION_PAN_AT_CAPACITY;
macAssociateResponseInfo.assocShortAddress= invalidShortAddress;
//ByteArrayContentCopy(macAssociateResponseInfo.assocShortAddress, invalidShortAddress, 2);
mlmeAssociateResponse(&macAssociateResponseInfo.deviceAddress, macAssociateResponseInfo.assocShortAddress, macAssociateResponseInfo.status, macAssociateIndicationInfo.aclEntry);
}
}
#endif
//-------------------------------------------------------------------------------------------------------
// void mlmeAssociateConfirm(WORD assocShortAddress, MAC_ENUM status)
//
// DESCRIPTION:
// mlmeAssociateConfirm is generated by the MAC layer when an association attempt has succeeded or
// failed (initiated by mlmeAssociateRequest(...)).
// Function must be implemented by the higher layer
//
// PARAMETERS:
// UINT16 assocShortAddress
// The short device address allocated by the coordinator on successful association. This
// parameter will be equal to 0xFFFF if the association attempt was unsuccessful.
// MAC_ENUM status
// The status of the association attempt (SUCCESS, CHANNEL_ACCESS_FAILURE, MAC_NO_DATA, etc.)
//-------------------------------------------------------------------------------------------------------
void mlmeAssociateConfirm(UINT16 AssocShortAddress, MAC_ENUM status)
{
UINT16 assocShortAddress;
BYTE i;
UINT16 invalidMacPANId;
UINT16 macCoordShortAddess;
volatile MAC_ENUM setResult;
setResult=NWK_UNSUPPORTED_ATTRIBUTE;
invalidMacPANId=INVALID_MAC_PAN_ID;
assocShortAddress=AssocShortAddress;
macAssociateConfirmInfo.assocShortAddress=assocShortAddress;
// ByteArrayContentCopy(macAssociateConfirmInfo.assocShortAddress, assocShortAddress, 2);
macAssociateConfirmInfo.status=status;
if(macAssociateConfirmInfo.status!=MAC_SUCCESS)
{
deviceInfo.deviceInNetwork=0;
deviceInfo.deviceJoinedNetwork=0;
setResult=mlmeSetRequest(MAC_PAN_ID,&invalidMacPANId);
}
else
{
// I have joined a network. Set my address information
setResult=mlmeSetRequest(MAC_SHORT_ADDRESS,&assocShortAddress);
deviceInfo.deviceJoinedNetwork=1;
/*TODO:store the the allocated short address on the hardware*/
// Store the final parentNeighborTableIndex in NVM.
WriteNeighborTableInfoIntoROM();
// Set parent relationship in neighbor table
#ifndef NWK_OPT_ZIGBEE_PAN_COORDINATOR
pCurrentNeighborRecord = &neighborTable[currentNeighborTableInfo.parentNeighborTableIndex];
#endif
ReadNeighborRecordIntoRAM( ¤tNeighborRecord, (void*)pCurrentNeighborRecord );
currentNeighborRecord.deviceInfo.bits.relationship = NEIGHBOR_IS_PARENT;
WriteNeighborRecordIntoROM(pCurrentNeighborRecord, (BYTE*)¤tNeighborRecord);
macCoordShortAddess= currentNeighborRecord.shortAddress;
// ByteArrayContentCopy(macCoordShortAddess, currentNeighborRecord.shortAddress, 2);
setResult=mlmeSetRequest(MAC_COORD_SHORT_ADDRESS, &macCoordShortAddess);
// Initialize my information. We'll do it here since we have our parent's depth.
#ifndef NWK_OPT_RFD
currentNeighborTableInfo.depth = currentNeighborRecord.deviceInfo.bits.depth+1; // Our depth in the network
currentNeighborTableInfo.cSkip = GetCskipVal( currentNeighborTableInfo.depth ); // Address block size
currentNeighborTableInfo.nextEndDeviceAddr = assocShortAddress+ currentNeighborTableInfo.cSkip * nnib.nwkMaxRouters+ 1; // Next address available to give to an end device
currentNeighborTableInfo.nextRouterAddr = assocShortAddress + 1; // Next address available to give to a router
currentNeighborTableInfo.numChildren = 0;
currentNeighborTableInfo.numChildRouters = 0;
ConfigBeaconPayload();
#endif
}
}
//-------------------------------------------------------------------------------------------------------
// void mlmeDisassociateConfirm(MAC_ENUM status)
//
// DESCRIPTION:
// Callback generated by the MAC sublayer to the higher layer upon completion of a
// mlmeDisassociateRequest(...) call from the higher layer.
// Function must be implemented by the higher layer.
//
// PARAMETERS:
// MAC_ENUM status
// Status returned by the callback
// (SUCCESS | TRANSACTION_OVERFLOW | TRANSACTION_EXPIRED | NO_ACK |
// CHANNEL_ACCESS_FAILURE | UNAVAILABLE_KEY | FAILED_SECURITY_CHECK |
// INVALID_PARAMETER)
//-------------------------------------------------------------------------------------------------------
void mlmeDisassociateConfirm(MAC_ENUM status)
{
//this function will return the result of the execution of the mlmeDisassociateRequest.
ADDRESS *deviceAddress;
UINT8 numberOfChilderenLeft;
deviceInfo.deviceInNetwork=0;
deviceInfo.deviceJoinedNetwork=0;
GetMACAddress(deviceAddress->Extended);
NumberOfChildrenInNeighborTable(&numberOfChilderenLeft);
if(nwkLeaveInfo.leaveReason==DEVICE_WISHES_TO_LEAVE)
{
#ifdef NWK_OPT_RFD
if(status==MAC_SUCCESS)
#else
if ((status==MAC_SUCCESS) &&((nwkLeaveInfo.removeChildren)&&(!currentNeighborTableInfo.numChildren )&&(!numberOfChilderenLeft)))
#endif
{
nlmeLeaveConfirm(deviceAddress, NWK_SUCCESS);
}
else
{
nlmeLeaveConfirm(deviceAddress, NWK_LEAVE_UNCONFIRM);
}
}
else
{
//nwkLeaveInfo.leaveReason==COORD_WISHES_DEVICE_TO_LEAVE;
//call the nlmeLeaveIndication
nlmeLeaveIndication(deviceAddress );
}
}
//-------------------------------------------------------------------------------------------------------
// void mlmeDisassociateIndication(ADDRESS* deviceAddress, BYTE disassociateReason, ZBOOL securityUse, ...
//
// DESCRIPTION:
// Callback generated by the MAC sublayer to the higher layer upon reception of a
// disassociation notification command frame
// Function must be implemented by the higher layer of a FFD device
//
// PARAMETERS:
// QWORD deviceAddress
// Extended address of the device requesting disassociation
// BYTE disassociateReason
// The disassociate reason (COORD_WISHES_DEVICE_TO_LEAVE | DEVICE_WISHES_TO_LEAVE)
// ZBOOL securityUse
// Security enabled for the incoming frame?
// UINT8 aclEntry
// The macSecurityMode parameter value from the ACL entry associated with the sender of
// the data frame. This value is set to 0x08 if the sender of the data frame was not
// found in the ACL.
//-------------------------------------------------------------------------------------------------------
void mlmeDisassociateIndication(ADDRESS* deviceAddress, BYTE disassociateReason, ZBOOL securityUse, UINT8 aclEntry)
{
BYTE i;
TICK endTimeStamp;
TICK leaveDuration;
INT8 minusOne;
UINT8 numberOfLeftChildren;
minusOne=-1;
if(nwkLeaveInfo.removeChildren==TRUE)
#ifndef NWK_OPT_RFD
leaveDuration=nnib.nwkTransactionPersistenceTime*currentNeighborTableInfo.cSkip;
#else
leaveDuration=nnib.nwkTransactionPersistenceTime;
#endif
else
leaveDuration=nnib.nwkTransactionPersistenceTime;
endTimeStamp=getCurrentime();
NumberOfChildrenInNeighborTable(&numberOfLeftChildren);
if((( minusOne=CompareTime(nwkLeaveInfo.leaveStartTime,endTimeStamp,leaveDuration))==-1)&&((!nwkLeaveInfo.removeChildren)||((nwkLeaveInfo.removeChildren)&&(numberOfLeftChildren==0))))
{
nlmeLeaveConfirm(deviceAddress , NWK_SUCCESS);
}
else
nlmeLeaveConfirm(deviceAddress,NWK_LEAVE_UNCONFIRM);
/*TODO*/
//Change the neighbor table entry field of the 'relationShip'
//we should call nlmeLeaveConfirm function in this function
//and the parameter Status should be determined
//i=NWKLookupNodeByLongAddr(deviceAddress);
//if(i!=INVALID_NEIGHBOR_INDEX)
//{
// if(currentNeighborRecord.deviceInfo.bits.relationShip==NEIGHBOR_IS_PARENT)
// {
// //this device recived a leave command frame from its parent
// /*free the neighbor entry occupied by the parent*/
// currentNeighborRecord.deviceInfo.bits.relationShip=NEIGHBOR_IS_NONE;
//
// }
// if(currentNeighborRecord.deviceInfo.bits.relaionShip==NEIGHBOR_IS_CHILD)
//
// {
// /*free the neighbor entry occupied by the child*/
// currentNeighborRecord.deviceInfo.bits.relationShip==NEIGHBOR_IS_NONE;
// }
// }
}
//-------------------------------------------------------------------------------------------------------
// void mcpsDataIndication(MCPS_DATA_INDICATION *pMDI)
//
// DESCRIPTION:
// MAC callback to the higher layer upon reception of a MAC data frame
// Multi-buffering is handled internally in the MAC sublayer
// Function must be implemented by the higher layer
//
// PARAMETERS:
// MCPS_DATA_INDICATION *pMDI
// Pointer to the MCPS_DATA_INDICATION data indication struct
//-------------------------------------------------------------------------------------------------------
void mcpsDataIndication(MCPS_DATA_INDICATION *pMDI){
UINT8 rreqDealTaskNumber;
BYTE i;
MAC_ENUM getMyAddressResult;
PACKET_ROUTING_STATUS routeStatus;
UINT16 nextHopAddress;
mcpsDataIndicationInfo.aclEntry=pMDI->aclEntry;
mcpsDataIndicationInfo.dstAddr=pMDI->dstAddr;
mcpsDataIndicationInfo.dstAddrMode=pMDI->dstAddrMode;
mcpsDataIndicationInfo.dstPanId=pMDI->dstPanId;
mcpsDataIndicationInfo.mpduLinkQuality=pMDI->mpduLinkQuality;
mcpsDataIndicationInfo.msduLength=pMDI->msduLength;
memset(mcpsDataIndicationInfo.pMsdu,-1,aMaxPHYPacketSize - aMACMinFrameOverhead);
ByteArrayContentCopy(mcpsDataIndicationInfo.pMsdu,pMDI->pMsdu, pMDI->msduLength);
printf("\n收到的来自其它设备的帧为:\n");
for(i=0;/*i<14*/mcpsDataIndicationInfo.pMsdu[i]!=-1;i++)
{
printf("%d ",mcpsDataIndicationInfo.pMsdu[i]);
}
//mcpsDataIndicationInfo.pMsdu=pMDI->pMsdu;
mcpsDataIndicationInfo.securityUse=pMDI->securityUse;
mcpsDataIndicationInfo.srcAddr=pMDI->srcAddr;
mcpsDataIndicationInfo.srcAddrMode=pMDI->srcAddrMode;
mcpsDataIndicationInfo.srcPanId=pMDI->srcPanId;
getAddressInfoInNwkHeader();
printf("\nnwkSrcAddrInHeaderOfRecivedPacket is %x!\n",nwkSrcAddrInHeaderOfRecivedPacket);
printf("nwkDstAddrInHeaderOfRecivedPacket is %x!\n",nwkDstAddrInHeaderOfRecivedPacket);
if (pMDI != NULL){
// See if this is a broadcast packet.
if(mcpsDataIndicationInfo.dstAddrMode==AM_SHORT_16)
{
printf("\nI am going to test mcpsDataIndication function!\n");
if(mcpsDataIndicationInfo.dstAddr.Short!=nwkBroadcastAddress)
{
//this is a unicast frame
//if((mcpsDataIndicationInfo.pMsdu[NWK_HEADER_FRAME_CONTROL_FIELD_INDEX]&FRAME_TYPE_NWK_COMMAND)==1)
if (mcpsDataIndicationInfo.pMsdu[NWK_HEADER_FRAME_CONTROL_FIELD_INDEX]==5)
{
//this is a command frame
if(mcpsDataIndicationInfo.pMsdu[8]==NWK_CMD_LEAVE_REQUEST)
{
//this is a leave request command
nwkDealWithRecivedLeaveRequestFromMCPS();
}
else if(mcpsDataIndicationInfo.pMsdu[8]==NWK_CMD_LEAVE_INDICATION)
{
//this is a leave indication command
/*TODO:some operation about the leave indication command*/
nwkDealWithRecivedLeaveIndicationFromMCPS();
}
else if(mcpsDataIndicationInfo.pMsdu[8]==NWK_CMD_ROUTE_ERROR)
{
//this device recived a route error command from some remote device.
printf("\n我收到了来自其他设备的路由错误命令帧!\n");
nwkDealWithRecivedRerrFromMCPS();
}
else if(mcpsDataIndicationInfo.pMsdu[8]==NWK_CMD_ROUTE_REPLY)
{
printf("\n我收到了来自其他设备的路由应答命令帧!\n");
nwkDealWithRecivedRrepFromMCPS();
}
}
else
{
//this is a NWK unicast data frame from MAC
printf("\n我收到了来自其他设备的一个单播
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -