?? macp.nc
字號:
/** * */#include "ZBMAC.h"module MacP { provides interface Init; provides interface SplitControl; provides interface MldeSap; provides interface MlmeSap; uses interface SplitControl as PhyControl; uses interface PdSap; uses interface PlmeSap; uses interface Alarm<T32khz,uint32_t> as MacTimer; uses interface Mem; uses interface ZbCache<mac_send_cache_t> as SendCache; uses interface ZbCache<mac_receive_cache_t> as ReceiveCache; uses interface Leds;}implementation {/** * request beacon frame * FCF(2)+DSN(1)+DST_PANID(2)+DST_SADDR(2)+CMD_TYPE(1)+FCS(2) * * beacon frame format * FCF(2)+DSN(1)+SOURCE_PANID(2)+SOURCE_SADDR(2)+BEACON_INFO(2)+|-->PROTOCOL_ID(1)+NWK_INFO(2)+IEEEADDR(8)<--| * * assoc request packet * FCF(2)+DSN(1)+DST_PANID(2)+DST_SADDR(2)+SOURCE_PANID(2,0xffff)+SOURCE_LADDR(8)+CMD_TYPE(1)+CAP_INFO(1)+|ZIGBEE_NUM(4)| * length = 2+1+2+2+2+8+1+1+4 = 23 * * association response frame format: * FCF(2)+DSN(1)+DST_PANID(2)+DST_LADDR(8)+SOURCE_PANID(2)+SOURCE_LADDR(8)+CMD_TYPE(1)+SADDR(2)+ASSOC_STATUS(1) * length = 2+1+2+8+2+8+1+2+1 = 27 **/ #define BEACON_REQ_FRAME_LEN 2+1+2+2+1#define BEACON_DEF_PAYLOAD_LEN 1+2+8#define BEACON_MAX_PAYLOAD_LEN BEACON_DEF_PAYLOAD_LEN#define BEACON_FRAME_LEN BEACON_MAX_PAYLOAD_LEN + 2 + 1 + 2 + 2 + 2 #define ASSOC_REQ_FRAME_LEN 2+1+2+2+2+8+1+1+4#define ASSOC_WAIT_TIME 1024*32 //32us unit #define ASSOC_RESPON_FRAME_LEN 2+1+2+8+2+8+1+2+1#define PHY_HEAD_LEN 1 //1 byte length field/*** mac state enum ****/typedef enum { S_STOPPED, S_STARTING, S_IDLE, S_SCANNING, S_SCAN_DONE, #ifdef IS_COORD S_ESTABLISHING, S_ESTABLISHED,#endif#ifndef IS_COORD S_JOINING, S_JOINED,#endif S_STOPPING,} mac_state_t; /**** send state enum *****/ typedef enum { SEND_IDLE, SEND_BUSY,} send_state_t;/******** send task use mac_send_cache_t.type to distinguish packet. ********/enum { TYPE_DATA, TYPE_BEACON, CMD_ASSOC_REQ, CMD_ASSOC_RESPON, CMD_BEACON_REQ, CMD_ORPHAN_NOTIFY, CMD_COORD_REALIGN, CMD_DISASSOC_NOTIFY,}; /*** next hight layer's parameter store into this type when sending data ***/ typedef struct { uint8_t length; mem_head_t* pmsdu; error_t error;} send_parameter_t;/** below variable use to control next high layer send data. **/norace bool dataSendPending = FALSE;send_parameter_t sendParameter;task void sendDone_task();norace send_state_t send_state = SEND_IDLE;norace mac_state_t mac_state = S_STOPPED;norace mac_pib_t macPib;/** use by positive scanning **/ pan_descriptor_t panDescriptorTable[MAX_PAN_DESCRIPTOR_NUM];/*** if this value is 0, indicate scan failed beacause no pan_descriptor_t have store in panDescriptorTable. **/uint8_t panDescriptorNum;/** scan done task **/task void positiveScanDone_task();/** next high layer should get and set beaconPayload contents ***/uint8_t beaconPayload[BEACON_MAX_PAYLOAD_LEN];/** received mac frame header parameter **/typedef struct { uint16_t fcf; uint8_t type; uint8_t dstAddrMode; uint8_t srcAddrMode; nxle_uint8_t dsn; nxle_uint16_t dstPanId; addr_union_t dstAddr; nxle_uint16_t srcPanId; addr_union_t srcAddr;} receive_head_t;/** used by parseHead() function **/receive_head_t receiveHead;/** receiveTask call this function to parse mac head into receiveHead **/void parseHead(mem_head_t* pMacPkt);/** join done task **/task void joinDone_task();/** used for joinDone_task() **/mac_error_t joinDoneError;saddr_t joinAssignedAddr;/** sendTask's task is getting a packet from mac_send_cache and send it. **/task void sendTask();/** receiveTask's task is to getting a packet from mac_receive_cache and handle it. **/task void receiveTask();/** use to fill in pBeaconPkt with propriety beacon parameter. **/void generateBeacon(mem_head_t* pBeaconPkt);/** store beacon parameter into panDescritorTable. **/void handleBeacon(uint8_t length, uint8_t* pBuf, uint8_t lqi); /***************** function start *********************/command error_t Init.init(){ mac_state = S_STOPPED; send_state = SEND_IDLE; return SUCCESS;}command error_t SplitControl.start(){ if(mac_state != S_STOPPED){ return FAIL; } mac_state = S_STARTING; call PhyControl.start(); return SUCCESS;}command error_t SplitControl.stop(){ if(mac_state != S_IDLE){ return FAIL; } mac_state = S_STOPPING; call PhyControl.stop(); return SUCCESS;}/** * shuld set all mac layer module variable into default value if error == SUCCESS. **/event void PhyControl.startDone(error_t error){ if(error == SUCCESS){ /** set mac_state ***/ mac_state = S_IDLE; /** set pan descriptor table **/ panDescriptorNum = 0; /*** there shuld only one next high layer frame pending in SendCache ***/ dataSendPending = FALSE; /*** set mac pib ***/ macPib.bits.macAssociationPermit = TRUE; macPib.bits.ifReceiveAllFrame = TRUE; macPib.bits.macRxOnWhenIdle = FALSE; /*** set mac dsn to 0 ***/ macPib.macDsn = 0; /*** set macPib.pPanId point at phyPib.panId ***/ macPib.pPanId = call PlmeSap.getPanId(); /*** set macPib.pShortAddr point at phyPib.shortAddress **/ macPib.pShortAddr = call PlmeSap.getShortAddr(); /*** set macPib.pLongAddr point at phyPib.longAddress ***/ macPib.pLongAddr = call PlmeSap.getLongAddr(); signal SplitControl.startDone(SUCCESS); } else{ mac_state = S_STOPPED; signal SplitControl.startDone(FAIL); } }event void PhyControl.stopDone(error_t error){ if(error == SUCCESS){ mac_state = S_STOPPED; signal SplitControl.stopDone(SUCCESS); } else{ mac_state = S_IDLE; signal SplitControl.stopDone(FAIL); } }event void PlmeSap.directSetShortAddrDone(error_t error){ #ifndef IS_COORD if(error == SUCCESS){ mac_state = S_JOINED; post joinDone_task(); } else{ mac_state = S_SCAN_DONE; joinDoneError = FAIL; post joinDone_task(); } #endif }/** * currently only use default channel, parameter scanChannel is not use * * scanDuration range from 0-14, * scan time is ( aBaseSuperframeDuration (60*16symbol period) ) * ( 2**scanDuration + 1 ) * symbol period is 64k. * * request beacon frame * FCF(2)+DSN(1)+DST_PANID(2)+DST_SADDR(2)+CMD_TYPE(1) **/ command error_t MlmeSap.positiveScan(uint32_t scanChannel, uint8_t scanDuration){ uint8_t i; /*** use for calculate scan time duration ***/ uint32_t scanTime = 1; /*** point to beacon request frame memory block ***/ mem_head_t* pScanPkt; /*** use to fill data **/ uint8_t* p; /*** a SendCache element pointer ***/ mac_send_cache_t* pSendCache; if(mac_state != S_IDLE){ return FAIL; } if(scanDuration > 14){ return FAIL; } /** malloc beacon request frame memory block and get a pointer to SendCache element **/ if( ( call Mem.malloc( &pScanPkt, (BEACON_REQ_FRAME_LEN + PHY_HEAD_LEN) ) ) != SUCCESS ){ return FAIL; } if( ( pSendCache = call SendCache.fetchFree() ) == NULL ){ call Mem.free(pScanPkt); return FAIL; } /** set p point at end of memory block **/ p = (uint8_t*)pScanPkt + call Mem.getSize(pScanPkt); /** set mac cmd type **/ p--; *p = MAC_CMD_TYPE_BEACON_REQ; /** add destination broadcast address **/ p -= 2; *(nxle_uint16_t*)p = 0xFFFF; /** add destination broadcast pan id **/ p -= 2; *(nxle_uint16_t*)p = 0xFFFF; /** 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 ) | ( 0 << POS_MAC_ACK_REQUEST ) | ( 1 << POS_MAC_INTRA_PAN ) | ( MAC_ADDR_MODE_SHORT << POS_MAC_DEST_ADDR_MODE ) | ( MAC_ADDR_MODE_NONE << POS_MAC_SOURCE_ADDR_MODE ); /*** set memory current position **/ call Mem.setCurrentPos( pScanPkt, (p - (uint8_t*)pScanPkt) ); /** calculate scan time, in symbol unit **/ for(i=0; i<scanDuration; i++){ scanTime *= 2; } scanTime++; /*** 60*16)/2 is aBaseSuperframeDuration in 32k time unit ***/ scanTime *= (60*16)/2; /** fill SendCache element **/ pSendCache->type = CMD_BEACON_REQ; pSendCache->psdu = pScanPkt; pSendCache->isAckSend = FALSE; /*** dsn isn't use when isAckSend == FALSE ***/ pSendCache->dsn = macPib.macDsn - 1; /** put it into SendCache **/ call SendCache.putFull(pSendCache); post sendTask(); mac_state = S_SCANNING; /*** set scan duration timer ***/ call MacTimer.start(scanTime); return SUCCESS; }#ifdef IS_COORD/*** * **/command error_t MlmeSap.establish(uint8_t channel, panid_t panId){ uint8_t* p = beaconPayload; uint8_t i; if(mac_state != S_IDLE){ return FAIL; } /** * set beacon payload. * if this node is a router, beacon payload shuld be set by next high layer after signal joinDone. **/ macPib.beaconPayloadLen = BEACON_DEF_PAYLOAD_LEN; /*** set PROTOCOL_ID ***/ *p = PROTOCOL_ID; p++; /*** set NWK_INFO filed ***/ *(nxle_uint16_t*)p = ( NWK_INFO_STACK_PROFILE_ID << POS_NWK_INFO_STACK_PROFILE ) | ( NWK_INFO_VERSION_ID << POS_NWK_INFO_VERSION ) | ( 1 << POS_NWK_INFO_ROUTER_CAP ) | ( 0 << POS_NWK_INFO_DEPTH ) | ( 1 << POS_NWK_INFO_END_DEVICE_CAP ); /*** set IEEE address field ***/ p += 2;// *(laddr_t*)p = *(macPib.pLongAddr); for(i=0; i<8; i++){ *p++ = macPib.pLongAddr->bytes[i]; } /*** set short address to 0 **/ call PlmeSap.setShortAddr(0); /*** set pan id ***/ call PlmeSap.setPanId(panId); /*** sync with cc2420 ram ***/ call PlmeSap.sync(); mac_state = S_ESTABLISHING; return SUCCESS;}#endifevent void PlmeSap.syncDone(error_t error){ /*** coordinator establishing ***/ #ifdef IS_COORD if(error == SUCCESS){ mac_state = S_ESTABLISHED; signal MlmeSap.establishDone(SUCCESS); } else{ mac_state = S_IDLE; signal MlmeSap.establishDone(FAIL); } #endif /**** router or rfd joinning ***/ #ifndef IS_COORD if(error == SUCCESS){ mac_state = S_JOINED; signal MlmeSap.joinDone(joinAssignedAddr, joinDoneError); } else{ mac_state = S_SCAN_DONE; joinDoneError = FAIL; signal MlmeSap.joinDone(joinAssignedAddr, joinDoneError); } #endif}#ifndef IS_COORD/** * assoc request packet * FCF(2)+DSN(1)+DST_PANID(2)+DST_SADDR(2)+SOURCE_PANID(2,0xffff)+SOURCE_LADDR(8)+CMD_TYPE(1)+CAP_INFO(1)+|ZIGBEE_NUM(4)|+FCS(2) * length = 2+1+2+2+2+8+1+1+4 = 23 **/command error_t MlmeSap.joinRequest(uint8_t descriptorSequence, uint8_t myCapInfo){ mac_send_cache_t* pSendCache; mem_head_t* pJoinPkt; pan_descriptor_t* pdt; uint8_t* p; uint8_t i; if( descriptorSequence >= MAX_PAN_DESCRIPTOR_NUM ){ return FAIL; } if(mac_state != S_SCAN_DONE){ return FAIL; } /** malloc associate request frame memory block and get a pointer to SendCache element **/ if( ( call Mem.malloc(&pJoinPkt, ASSOC_REQ_FRAME_LEN+PHY_HEAD_LEN) ) != SUCCESS){ return FAIL; } if( ( pSendCache = call SendCache.fetchFree() ) == NULL ){ call Mem.free(pJoinPkt); return FAIL; } /** set pdt point at intent father node's descriptor **/ pdt = &panDescriptorTable[descriptorSequence]; /*** pre set intent father's pan id, short address and long address **/ call PlmeSap.setPanId(pdt->panId);
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -