📄 mac.c
字号:
phy_pib.currentTxFrm--;
*phy_pib.currentTxFrm = LRWPAN_NWK_MAGICNUM_B0;
#endif
phy_pib.currentTxFrm--;
*phy_pib.currentTxFrm = mac_pib.macCapInfo;
phy_pib.currentTxFrm--;
*phy_pib.currentTxFrm = LRWPAN_MACCMD_ASSOC_REQ;
phy_pib.currentTxFlen = LRWPAN_MACCMD_ASSOC_REQ_PAYLOAD_LEN;
}
#ifndef LRWPAN_COORDINATOR
//parse the association response
static void macParseAssocResponse(void){
BYTE *ptr;
SADDR saddr;
//first, ensure that the payload length is correct
//the +1 is because the offset takes into account the lenght byte at the start of the packet
if ( (*(a_mac_rx_data.orgpkt->data)-a_mac_rx_data.pload_offset-PACKET_FOOTER_SIZE +1)
!= LRWPAN_MACCMD_ASSOC_RSP_PAYLOAD_LEN ) {
DEBUG_STRING( DBG_INFO, "MAC: Failed to join, illegal assoc response\n");
return; //wrong length
}
ptr = a_mac_rx_data.orgpkt->data + a_mac_rx_data.pload_offset;
//check the status first which is last byte of the payload
if (LRWPAN_GET_ASSOC_STATUS(*(ptr+LRWPAN_MACCMD_ASSOC_RSP_PAYLOAD_LEN-1)) != LRWPAN_ASSOC_STATUS_SUCCESS) {
//failed to join
DEBUG_STRING( DBG_INFO, "MAC: Failed to join, remote node rejected us.\n");
return;
}
ptr++; //skip command byte
//successful join, get my short SADDR
saddr = (BYTE) *ptr;
ptr++;
saddr += (((UINT16) *ptr) << 8);
macSetShortAddr(saddr);
ptr++;
//our PANID is our parent's panid.
mac_pib.macPANID = a_mac_rx_data.SrcPANID;
halSetRadioPANID(a_mac_rx_data.SrcPANID);
#ifndef IEEE_802_COMPLY
//the short address of the parent are extra bytes in this payload
mac_pib.macCoordShortAddress = (BYTE) *ptr;
ptr++;
mac_pib.macCoordShortAddress += (((UINT16) *ptr) << 8);
ptr++;
//get the depth of parent, our depth is 1+ that of our parent
mac_pib.depth = *ptr + 1;
#else
#ifndef LRWPAN_FORCE_ASSOCIATION_TARGET
//if we are not using forced association, then the beacon response
//we got had the short address that we used for the association request,
//so the short address of the beacon responder is our parent
mac_pib.macCoordShortAddress = mac_pib.bcnSADDR;
//beacon response also has the depth of our parent, so our depth is 1+ this
mac_pib.depth = mac_pib.bcnDepth+1;
#endif
#endif
//copy the SRC long address as my coordinator long address
mac_pib.macCoordExtendedAddress.bytes[0] = a_mac_rx_data.SrcAddr.laddr.bytes[0];
mac_pib.macCoordExtendedAddress.bytes[1] = a_mac_rx_data.SrcAddr.laddr.bytes[1];
mac_pib.macCoordExtendedAddress.bytes[2] = a_mac_rx_data.SrcAddr.laddr.bytes[2];
mac_pib.macCoordExtendedAddress.bytes[3] = a_mac_rx_data.SrcAddr.laddr.bytes[3];
mac_pib.macCoordExtendedAddress.bytes[4] = a_mac_rx_data.SrcAddr.laddr.bytes[4];
mac_pib.macCoordExtendedAddress.bytes[5] = a_mac_rx_data.SrcAddr.laddr.bytes[5];
mac_pib.macCoordExtendedAddress.bytes[6] = a_mac_rx_data.SrcAddr.laddr.bytes[6];
mac_pib.macCoordExtendedAddress.bytes[7] = a_mac_rx_data.SrcAddr.laddr.bytes[7];
//indicate that the association was successful
mac_pib.flags.bits.macIsAssociated = 1;
mac_pib.flags.bits.ackPending = 0; //only one outstanding association req, clear the ack bit
DEBUG_STRING(DBG_INFO,"MAC:Received good association response!\n");
}
#endif
#ifndef LRWPAN_COORDINATOR
//Parse the coordinator realignment (Orphan response)
static void macParseOrphanResponse(void){
BYTE *ptr;
UINT16 tmp;
//first, ensure that the payload length is correct
//the +1 is because the offset takes into account the lenght byte at the start of the packet
if ( (*(a_mac_rx_data.orgpkt->data)-a_mac_rx_data.pload_offset-PACKET_FOOTER_SIZE +1)
!= LRWPAN_MACCMD_COORD_REALIGN_PAYLOAD_LEN ) {
DEBUG_STRING( DBG_INFO, "MAC: illegal Coord Alignment packet\n");
return; //wrong length
}
ptr = a_mac_rx_data.orgpkt->data + a_mac_rx_data.pload_offset;
DEBUG_STRING(DBG_INFO, "Received Coord Realign (Orphan response)\n");
mac_pib.flags.bits.GotOrphanResponse = 1;
mac_pib.flags.bits.macIsAssociated = 1; //we are associated with somebody!
mac_pib.flags.bits.ackPending = 0;
ptr++; //skip command byte
//get the PANID
tmp = (BYTE) *ptr;
ptr++;
tmp += (((UINT16) *ptr) << 8);
ptr++;
macSetPANID(tmp);
//get the coordinator short address
mac_pib.macCoordShortAddress = (BYTE) *ptr;
ptr++;
mac_pib.macCoordShortAddress += (((UINT16) *ptr) << 8);
ptr++;
tmp =(BYTE) *ptr; //get the channel
ptr++;
macSetChannel(tmp); //set the channel
#ifndef LRWPAN_COORDINATOR
//copy the SRC long address as my coordinator long address
mac_pib.macCoordExtendedAddress.bytes[0] = a_mac_rx_data.SrcAddr.laddr.bytes[0];
mac_pib.macCoordExtendedAddress.bytes[1] = a_mac_rx_data.SrcAddr.laddr.bytes[1];
mac_pib.macCoordExtendedAddress.bytes[2] = a_mac_rx_data.SrcAddr.laddr.bytes[2];
mac_pib.macCoordExtendedAddress.bytes[3] = a_mac_rx_data.SrcAddr.laddr.bytes[3];
mac_pib.macCoordExtendedAddress.bytes[4] = a_mac_rx_data.SrcAddr.laddr.bytes[4];
mac_pib.macCoordExtendedAddress.bytes[5] = a_mac_rx_data.SrcAddr.laddr.bytes[5];
mac_pib.macCoordExtendedAddress.bytes[6] = a_mac_rx_data.SrcAddr.laddr.bytes[6];
mac_pib.macCoordExtendedAddress.bytes[7] = a_mac_rx_data.SrcAddr.laddr.bytes[7];
#endif
#ifdef LRWPAN_RFD
//get our short address
tmp = (BYTE) *ptr;
ptr++;
tmp += (((UINT16) *ptr) << 8);
ptr++;
macSetShortAddr(tmp);
#else
//this is a router
//get our short ADDR
tmp = (BYTE) *ptr;
ptr++;
tmp += (((UINT16) *ptr) << 8);
ptr++;
if (tmp != macGetShortAddr()) {
//our short address has changed!
//everything may have changed,
//clear neighbor table, and address map
ntInitAddressMap();
ntInitTable();
}
macSetShortAddr(tmp);
#endif
}
#endif
static void macFormatOrphanNotify(void){
phy_pib.currentTxFrm = &tmpTxBuff[LRWPAN_MAX_FRAME_SIZE-1];
*phy_pib.currentTxFrm = LRWPAN_MACCMD_ORPHAN;
phy_pib.currentTxFlen = 1;
}
#ifdef LRWPAN_FFD
static void macFormatCoordRealign(SADDR orphan_saddr){
//format and send the realignment packet
//first is the orphans short address
phy_pib.currentTxFrm = &tmpTxBuff[LRWPAN_MAX_FRAME_SIZE-1];
*phy_pib.currentTxFrm = (BYTE) (orphan_saddr >>8);
--phy_pib.currentTxFrm;
*phy_pib.currentTxFrm = (BYTE) (orphan_saddr);
//logical channel
--phy_pib.currentTxFrm;
*phy_pib.currentTxFrm = phy_pib.phyCurrentChannel;
//our short addresss
--phy_pib.currentTxFrm;
*phy_pib.currentTxFrm = (BYTE) (macGetShortAddr()>>8);
--phy_pib.currentTxFrm;
*phy_pib.currentTxFrm = (BYTE) (macGetShortAddr());
//our PANID
--phy_pib.currentTxFrm;
*phy_pib.currentTxFrm = (BYTE) (mac_pib.macPANID>>8);
--phy_pib.currentTxFrm;
*phy_pib.currentTxFrm = (BYTE) (mac_pib.macPANID);
--phy_pib.currentTxFrm;
*phy_pib.currentTxFrm = LRWPAN_MACCMD_COORD_REALIGN;
phy_pib.currentTxFlen = LRWPAN_MACCMD_COORD_REALIGN_PAYLOAD_LEN;
}
static void macFormatAssociationResponse(void){
NAYBORENTRY *ntptr;
UINT16 new_saddr;
BYTE tmp, capinfo;
new_saddr = 0xFFFF;
tmp = LRWPAN_ASSOC_STATUS_DENIED; //default status
//check reasons to reject first
//check payload length
if ( (*(a_mac_rx_data.orgpkt->data)-a_mac_rx_data.pload_offset-PACKET_FOOTER_SIZE+1 )
!= LRWPAN_MACCMD_ASSOC_REQ_PAYLOAD_LEN) {
//invalid payload length
DEBUG_STRING(DBG_INFO,"MAC:Invalid association request, rejecting node!\n");
goto macFormatAssociationResponse_dopkt;
}
#ifndef IEEE_802_COMPLY
{
BYTE *ptr;
//Check Magic Number
ptr = a_mac_rx_data.orgpkt->data + a_mac_rx_data.pload_offset;
if (*(ptr+2) != LRWPAN_NWK_MAGICNUM_B0){
goto macFormatAssociationResponse_dopkt;
}
if (*(ptr+3) != LRWPAN_NWK_MAGICNUM_B1){
goto macFormatAssociationResponse_dopkt;
}
if (*(ptr+4) != LRWPAN_NWK_MAGICNUM_B2){
goto macFormatAssociationResponse_dopkt;
}
if (*(ptr+5) != LRWPAN_NWK_MAGICNUM_B3){
goto macFormatAssociationResponse_dopkt;
}
}
#endif
//now, see if this node is in the table
ntptr = ntFindByLADDR(&a_mac_rx_data.SrcAddr.laddr);
if (ntptr) {
new_saddr = mac_addr_tbl[ntptr->map_index].saddr;
tmp = LRWPAN_ASSOC_STATUS_SUCCESS;
goto macFormatAssociationResponse_dopkt;
}
//node is not in table. Look at capability info byte and see if we
//have room for this node type
capinfo = *(a_mac_rx_data.orgpkt->data + a_mac_rx_data.pload_offset + 1);
//node is not in table. Do final check with user
if (!usrJoinVerifyCallback(&a_mac_rx_data.SrcAddr.laddr, capinfo)) {
tmp = LRWPAN_ASSOC_STATUS_DENIED;
goto macFormatAssociationResponse_dopkt;
}
if ( ((LRWPAN_GET_CAPINFO_DEVTYPE(capinfo)) && (mac_pib.ChildRouters == LRWPAN_MAX_ROUTERS_PER_PARENT))
||
(!(LRWPAN_GET_CAPINFO_DEVTYPE(capinfo)) && (mac_pib.ChildRFDs == LRWPAN_MAX_NON_ROUTER_CHILDREN)))
//no room left
{
//no room
tmp = LRWPAN_ASSOC_STATUS_NOROOM;
goto macFormatAssociationResponse_dopkt;
}
//not in table, Add this node
new_saddr = ntAddNeighbor(&a_mac_rx_data.SrcAddr.laddr.bytes[0],capinfo);
if (new_saddr == LRWPAN_BCAST_SADDR) {
//this is an error indication, adding neighbor failed
tmp = LRWPAN_ASSOC_STATUS_NOROOM;
goto macFormatAssociationResponse_dopkt;
}
DEBUG_STRING(DBG_INFO,"MAC:Sending good association response!\n");
tmp = LRWPAN_ASSOC_STATUS_SUCCESS;
usrJoinNotifyCallback(&a_mac_rx_data.SrcAddr.laddr);
macFormatAssociationResponse_dopkt:
if (tmp == LRWPAN_ASSOC_STATUS_SUCCESS) {
DEBUG_STRING(DBG_INFO,"MAC:Sending good association response!\n");
} else {
DEBUG_STRING(DBG_INFO,"MAC:Rejecting assoc request: ");
DEBUG_UINT8(DBG_INFO,tmp);
DEBUG_STRING(DBG_INFO,"\n");
}
//format and send the packet
//status byte
phy_pib.currentTxFrm = &tmpTxBuff[LRWPAN_MAX_FRAME_SIZE-1];
*phy_pib.currentTxFrm = tmp;
#ifndef IEEE_802_COMPLY
//put our depth, short address so that the RFD will know both
//the radius, short and long addresses even if Beacon request has not been done
--phy_pib.currentTxFrm;
*phy_pib.currentTxFrm = mac_pib.depth;
--phy_pib.currentTxFrm;
*phy_pib.currentTxFrm = (BYTE) (macGetShortAddr()>>8);
--phy_pib.currentTxFrm;
*phy_pib.currentTxFrm = (BYTE) (macGetShortAddr());
#endif
//new short address for the RFD
--phy_pib.currentTxFrm;
*phy_pib.currentTxFrm = (BYTE) (new_saddr>>8);
--phy_pib.currentTxFrm;
*phy_pib.currentTxFrm = (BYTE) (new_saddr);
//CMD
--phy_pib.currentTxFrm;
*phy_pib.currentTxFrm = LRWPAN_MACCMD_ASSOC_RSP;
phy_pib.currentTxFlen = LRWPAN_MACCMD_ASSOC_RSP_PAYLOAD_LEN;
}
#endif
//check for DATA packets
//For RFD, just check if this packet came from parent
//For Routers, if this uses SHORT addressing, then check
//to see if this is associated with us
static BOOL macCheckDataRejection(void){
BYTE AddrMode,i;
//if not associated, reject
#ifndef LRWPAN_COORDINATOR
if (!mac_pib.flags.bits.macIsAssociated) {
DEBUG_STRING(DBG_INFO, "MAC: Rejecting data pkt as we are not associated\n");
return(FALSE);
}
#endif
AddrMode = LRWPAN_GET_DST_ADDR(a_mac_rx_data.fcfmsb);
if (AddrMode == LRWPAN_ADDRMODE_LADDR) {
//this packet send directly to our long address. accept it.
return(TRUE);
}
//check the parent
AddrMode = LRWPAN_GET_SRC_ADDR(a_mac_rx_data.fcfmsb);
if (AddrMode == LRWPAN_ADDRMODE_SADDR) {
//check parent short address
if (a_mac_rx_data.SrcAddr.saddr == mac_pib.macCoordShortAddress)
return(TRUE);
} else if (AddrMode == LRWPAN_ADDRMODE_LADDR){
//check parent long address.
for (i=0;i<8;i++) {
if (a_mac_rx_data.SrcAddr.laddr.bytes[i] !=
mac_pib.macCoordExtendedAddress.bytes[i])
break;
}
if (i==8) return(TRUE); //have a match
}
#ifdef LRWPAN_RFD
DEBUG_STRING(DBG_INFO, "MAC: Rejecting data pkt from unassociated node\n");
return(FALSE);
#else
//ok, for FFDs, check the neighbor table
if (AddrMode == LRWPAN_ADDRMODE_SADDR){
if (ntFindBySADDR (a_mac_rx_data.SrcAddr.saddr) !=(NAYBORENTRY *) NULL)
return(TRUE);
}else if (AddrMode == LRWPAN_ADDRMODE_LADDR){
if (ntFindByLADDR (&a_mac_rx_data.SrcAddr.laddr))
return(TRUE);
}
DEBUG_STRING(DBG_INFO, "MAC: Rejecting data pkt from unassociated node\n");
return(FALSE);
#endif
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -