📄 macp.nc
字号:
macPib.macCoordShortAddress = pdt->shortAddr; for(i=0; i<8; i++){ macPib.macCoordExtendedAddress.bytes[i] = pdt->extendedAddr.bytes[i]; } /** set p point at end of memory block **/ p = (uint8_t*)pJoinPkt + call Mem.getSize(pJoinPkt); /** set ZIGBEE_NUM **/ p--; *p = ZIGBEE_NUM_3; p--; *p = ZIGBEE_NUM_2; p--; *p = ZIGBEE_NUM_1; p--; *p = ZIGBEE_NUM_0; /** set capability information **/ p--; *p = myCapInfo; /** set mac cmd type field **/ p--; *p = MAC_CMD_TYPE_ASSOC_REQ; /** set source address field with long address **/ p -= 8; for(i=0; i<8; i++){ *(p+i) = macPib.pLongAddr->bytes[i]; } /** set source pan id filed with broadcast pan id **/ p -= 2; *(uint16_t*)p = 0xffff; /** set destination address field with intent father's short address **/ p -= 2; *(saddr_t*)p = pdt->shortAddr; /** set destination pan id field with intent father' pan id **/ p -= 2; *(nxle_uint16_t*)p = pdt->panId; /** set mac dsn **/ p--; *p = macPib.macDsn++; /** set fcf **/ p -= 2; *(nxle_uint16_t*)p = ( MAC_FRAME_TYPE_CMD << POS_MAC_FRAME_TYPE ) | ( 0 << POS_MAC_SECURITY ) | ( 0 << POS_MAC_FRAME_PENDING ) | ( 1 << POS_MAC_ACK_REQUEST ) | ( 0 << POS_MAC_INTRA_PAN ) | ( MAC_ADDR_MODE_SHORT << POS_MAC_DEST_ADDR_MODE ) | ( MAC_ADDR_MODE_LONG << POS_MAC_SOURCE_ADDR_MODE ); /** set memory block position **/ call Mem.setCurrentPos( pJoinPkt, (p-(uint8_t*)pJoinPkt) ); /** fill SendCache element **/ pSendCache->isAckSend = TRUE; pSendCache->type = CMD_ASSOC_REQ; pSendCache->psdu = pJoinPkt; pSendCache->dsn = macPib.macDsn - 1; /** put into SendCache full queue **/ call SendCache.putFull(pSendCache); mac_state = S_JOINING; /** start associate wait timer **/ call MacTimer.start(ASSOC_WAIT_TIME); return SUCCESS;}#endifasync event void MacTimer.fired(){ switch(mac_state){ case S_SCANNING: post positiveScanDone_task(); break; #ifndef IS_COORD case S_JOINING: /** have not detected right associate response frame in ASSOC_WAIT_TIME **/ joinDoneError = FAIL; joinAssignedAddr = 0; post joinDone_task(); break; #endif default:break; }}/** * currently just support data sending in the same pan. * do not support GTS transmission, indirect transmission, security enabled transmission. * source short address and pan id will automatically add by mac layer module. * * mac data frame format: * fcf(2) + dsn(1) + destPan(2) + destAddr(2/8) + srcAddr(2/8) + payload **/command error_t MldeSap.send(uint8_t srcAddrMode, uint8_t dstAddrMode, addr_union_t destAddr, uint8_t length, mem_head_t* pmsdu, bool ackSend){ mac_send_cache_t* pSendCache; uint8_t* p; int8_t pos; uint8_t i; /** check pmsdu free space **/ pos = (int8_t)( call Mem.getCurrentPos(pmsdu) ); if( srcAddrMode == MAC_ADDR_MODE_LONG ) pos -= 8; else pos -= 2; if( dstAddrMode == MAC_ADDR_MODE_LONG ) pos -= 8; else pos -= 2; if(pos < 6 ){ // 5 = fcf + dsn + destPanId + PHY_HEAD_LEN return FAIL; } /** dataSendPending is TRUE indicate MldeSap.send have been called without signal MldeSap.sendDone **/ if(dataSendPending){ return FAIL; } #ifdef IS_COORD if(mac_state != S_ESTABLISHED){ return FAIL; } #endif #ifndef IS_COORD if(mac_state != S_JOINED){ return FAIL; } #endif /** get a full element in SendCache **/ if( ( pSendCache = call SendCache.fetchFree() ) == NULL ){ return FAIL; } /** store MldeSap.send parameter **/ sendParameter.length = length; sendParameter.pmsdu = pmsdu; /** set p point at the beginning of mac payload **/ p = (uint8_t*)pmsdu + call Mem.getCurrentPos(pmsdu); /** add sourse address **/ if(srcAddrMode == MAC_ADDR_MODE_LONG){ p -= 8; for(i=0; i<8; i++){ *(p+i) = macPib.pLongAddr->bytes[i]; } } /** MAC_ADDR_MODE_SHORT and other **/ else{ p -= 2; *(saddr_t*)p = *(macPib.pShortAddr); } /** add dest address **/ if(dstAddrMode == MAC_ADDR_MODE_LONG){ p -= 8; for(i=0; i<8; i++){ *(p+i) = destAddr.laddr.bytes[i]; } } /*** MAC_ADDR_MODE_SHORT and other ***/ else{ p -= 2; *(saddr_t*)p = destAddr.saddr; } /** add pan id **/ p -= 2; *(nxle_uint16_t*)p = *(macPib.pPanId); /** add dsn **/ p--; *p = macPib.macDsn++; /** add fcf **/ p -= 2; *(nxle_uint16_t*)p = (MAC_FRAME_TYPE_DATA << POS_MAC_FRAME_TYPE) | (0 << POS_MAC_SECURITY) | (0 << POS_MAC_FRAME_PENDING) | (ackSend << POS_MAC_ACK_REQUEST) | (1 << POS_MAC_INTRA_PAN) | ( (dstAddrMode&0x3) << POS_MAC_DEST_ADDR_MODE ) | ( (srcAddrMode&0x3) << POS_MAC_SOURCE_ADDR_MODE ); /** set memory position at the start of mac fcf field **/ call Mem.setCurrentPos(pmsdu, (p - (uint8_t*)pmsdu) ); /** fill SendCache element **/ pSendCache->type = TYPE_DATA; pSendCache->isAckSend = ackSend; pSendCache->psdu = pmsdu; pSendCache->dsn = macPib.macDsn - 1; /** put into SendCache. **/ call SendCache.putFull(pSendCache); return SUCCESS; }task void sendTask(){ mac_send_cache_t* pSendCache; if(send_state != SEND_IDLE){ post sendTask(); return; } if( ( pSendCache = call SendCache.getFull() ) == NULL){ post sendTask(); return; } /*** send different frame ***/ if( call PdSap.send(pSendCache->psdu, pSendCache->isAckSend, pSendCache->dsn) != SUCCESS ){ call SendCache.fetchFull(); call SendCache.putFree(pSendCache); post sendTask(); switch (pSendCache->type){ case TYPE_DATA: sendParameter.error = FAIL; post sendDone_task(); break; #ifndef IS_COORD case CMD_BEACON_REQ: mac_state = S_IDLE; call MacTimer.stop(); post positiveScanDone_task(); break; case CMD_ASSOC_REQ: mac_state = S_SCAN_DONE; call MacTimer.stop(); joinDoneError = FAIL; joinAssignedAddr = 0; post joinDone_task(); break; #endif case TYPE_BEACON: case CMD_ASSOC_RESPON: default:break; } } else{ send_state = SEND_BUSY; }} event void PdSap.sendDone(error_t error, mem_head_t* psdu){ mac_send_cache_t* pSendCache; /*** fetch the frame just send ***/ pSendCache = call SendCache.fetchFull(); switch(pSendCache->type){ case TYPE_DATA: sendParameter.error = error; post sendDone_task(); break; #ifndef IS_COORD case CMD_BEACON_REQ: if(error == FAIL){ mac_state = S_IDLE; post positiveScanDone_task(); /** stop wait beacon timer **/ call MacTimer.stop(); } /** this packet is generate in mac layer module, so should be freed by mac layer module. **/ call Mem.free(pSendCache->psdu); break; case CMD_ASSOC_REQ: if(error == FAIL){ mac_state = S_SCAN_DONE; call MacTimer.stop(); joinDoneError = FAIL; joinAssignedAddr = 0; post joinDone_task(); } call Mem.free(pSendCache->psdu); break; #endif case TYPE_BEACON: case CMD_ASSOC_RESPON: default: call Mem.free(pSendCache->psdu); break; } send_state = SEND_IDLE; /*** put this SendCache elment into free queue ***/ call SendCache.putFree(pSendCache); /*** sendTask can send frame when send_state == SEND_IDLE ***/ post sendTask(); }task void sendDone_task(){ uint8_t pos; pos = call Mem.getCurrentPos(sendParameter.pmsdu); /** set memory block position at the beginning of mac layer payload **/ call Mem.setCurrentPos( sendParameter.pmsdu, (pos+sendParameter.length) ); signal MldeSap.sendDone(sendParameter.error, sendParameter.pmsdu); dataSendPending = FALSE;}event void PdSap.receive(uint8_t length, mem_head_t* psdu, uint8_t lqi){ mac_receive_cache_t* pReceiveCache; if( ( pReceiveCache = call ReceiveCache.fetchFree() ) != SUCCESS ){ call Mem.free(psdu); return; } pReceiveCache->lqi = lqi; pReceiveCache->length = length; pReceiveCache->psdu = psdu; call ReceiveCache.putFull(pReceiveCache);}task void receiveTask(){ uint8_t* p; uint8_t length; mac_receive_cache_t* pReceiveCache; /** mac cmd frame type **/ uint8_t cmdType; /** generate mac layer frame when needed after receiving mac cmd packet **/ mem_head_t* pSendPkt; mac_send_cache_t* pSendCache; /** used when receive associate request frame or associate response frame **/ saddr_t assignedAddr; mac_error_t assocError; uint8_t capInfo; uint8_t i; /*** no frame in receive cache ***/ if( ( pReceiveCache = call ReceiveCache.fetchFull() ) == NULL ){ post receiveTask(); return; } /** parse mac head into receiveHead and set psdu to payload position **/ parseHead(pReceiveCache->psdu); /** calculate mac frame payload beginning position **/ p = (uint8_t*)pReceiveCache->psdu + call Mem.getCurrentPos(pReceiveCache->psdu); /** * get mac frame payload length, length1 is length + 2(FCS) * length1 = call Mem.getSize(pReceiveCache->psdu) - call Mem.getCurrentPos(pReceiveCache->psdu); **/ length = call Mem.getSize(pReceiveCache->psdu) - call Mem.getCurrentPos(pReceiveCache->psdu) - 2; /*** * check fcf first * security and frame pending bit shuld not be set, ACK bit field do not care **/ if( ( ( (receiveHead.fcf&MASK_MAC_SECURITY) >> POS_MAC_SECURITY ) == 1 ) || ( ( (receiveHead.fcf&MASK_MAC_FRAME_PENDING) >> POS_MAC_FRAME_PENDING ) == 1 ) ){ call Mem.free(pReceiveCache->psdu); call ReceiveCache.putFree(pReceiveCache); post receiveTask(); return; } /** handle different frame type **/ switch(receiveHead.type){ case MAC_FRAME_TYPE_BEACON: if(mac_state == S_SCANNING){ handleBeacon(length, p, pReceiveCache->lqi); } call Mem.free(pReceiveCache->psdu); break; case MAC_FRAME_TYPE_DATA: #ifdef IS_COORD if(mac_state != S_ESTABLISHED){ call Mem.free(pReceiveCache->psdu); call ReceiveCache.putFree(pReceiveCache); post receiveTask(); return; } #endif #ifndef IS_COORD if(mac_state != S_JOINED){ call Mem.free(pReceiveCache->psdu); call ReceiveCache.putFree(pReceiveCache); post receiveTask(); return; } #endif /** * mac data frame format: * fcf(2) + dsn(1) + destPan(2) + destAddr(2/8) + srcAddr(2/8) + payload * * currently do not support receiving frame from different pan * address field must be short address or long address **/ if( ( (receiveHead.fcf&MASK_MAC_INTRA_PAN) == 0 ) || (receiveHead.dstAddrMode == MAC_ADDR_MODE_NONE) || (receiveHead.srcAddrMode == MAC_ADDR_MODE_NONE) ){ call Mem.free(pReceiveCache->psdu); call ReceiveCache.putFree(pReceiveCache); post receiveTask(); return; } /** notify next high layer **/ signal MldeSap.receive(receiveHead.srcAddrMode, receiveHead.srcAddr, receiveHead.dstAddrMode, receiveHead.dstAddr, length, pReceiveCache->psdu, pReceiveCache->lqi); break; case MAC_FRAME_TYPE_CMD: /** get cmd frame type **/ cmdType = *(uint8_t*)p; /** skip cmd type field byte **/ p++; /** handle different cmd frame **/ switch(cmdType){ /** * FCF(2)+DSN(1)+DST_PANID(2)+DST_SADDR(2)+CMD_TYPE(1) * length = 1; **/ case MAC_CMD_TYPE_BEACON_REQ: /** free this memory block **/ call Mem.free(pReceiveCache->psdu); /** check length filed **/ if(length != 1){ call ReceiveCache.putFree(pReceiveCache); post receiveTask(); return; } /** coordinator must be in established mode to handle this frame **/ #ifdef IS_COORD if(mac_state != S_ESTABLISHED){ call ReceiveCache.putFree(pReceiveCache); post receiveTask(); return; } #endif /** router must be in joined mode to handle this frame, be sure all node are FFD **/ #ifndef IS_COORD if(mac_state != S_JOINED){ call ReceiveCache.putFree(pReceiveCache); post receiveTask(); return; } #endif /** malloc beacon frame memory block and get a pointer to SendCache element **/ if( ( call Mem.malloc(&pSendPkt, BEACON_FRAME_LEN+PHY_HEAD_LEN) ) != SUCCESS ){ call ReceiveCache.putFree(pReceiveCache); post receiveTask(); return; } if( ( ( pSendCache = call SendCache.fetchFree() ) == NULL ) ){ call Mem.free(pSendPkt); call ReceiveCache.putFree(pReceiveCache); post receiveTask(); return; } /** generate beacon and send it **/ generateBeacon(pSendPkt); /** fill this SendCache element **/ pSendCache->type = TYPE_BEACON; pSendCache->isAckSend = FALSE; pSendCache->psdu = pSendPkt; pSendCache->dsn = macPib.macDsn - 1;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -