From: a_cunha Date: Mon, 11 Feb 2008 17:49:58 +0000 (+0000) Subject: *** empty log message *** X-Git-Tag: release_tinyos_2_1_0_0~563 X-Git-Url: https://oss.titaniummirror.com/gitweb/?a=commitdiff_plain;h=c7e8cf17b09c2d39226aab0db0b7d39bd7e63250;p=tinyos-2.x.git *** empty log message *** --- diff --git a/tos/lib/net/zigbee/apps/AssociationExample/AssociationExample.nc b/tos/lib/net/zigbee/apps/AssociationExample/AssociationExample.nc new file mode 100644 index 00000000..75aa75fc --- /dev/null +++ b/tos/lib/net/zigbee/apps/AssociationExample/AssociationExample.nc @@ -0,0 +1,61 @@ +/* + * @author IPP HURRAY http://www.hurray.isep.ipp.pt/art-wise + * @author Andre Cunha + * + */ +#include + +#include "associationexample.h" +#include "phy_const.h" +#include "phy_enumerations.h" +#include "mac_const.h" +#include "mac_enumerations.h" +#include "mac_func.h" + + +configuration AssociationExample { +} +implementation { + + components MainC; + components LedsC; + components AssociationExampleM; + + AssociationExampleM.Boot -> MainC; + + components Mac; + + AssociationExampleM.Leds -> LedsC; + + components new TimerMilliC() as Timer0; + AssociationExampleM.Timer0 -> Timer0; + + components new TimerMilliC() as Timer_Send; + AssociationExampleM.Timer_Send ->Timer_Send; + + + //MAC interfaces + + AssociationExampleM.MLME_START -> Mac.MLME_START; + + AssociationExampleM.MLME_GET ->Mac.MLME_GET; + AssociationExampleM.MLME_SET ->Mac.MLME_SET; + + AssociationExampleM.MLME_BEACON_NOTIFY ->Mac.MLME_BEACON_NOTIFY; + AssociationExampleM.MLME_GTS -> Mac.MLME_GTS; + + AssociationExampleM.MLME_ASSOCIATE->Mac.MLME_ASSOCIATE; + AssociationExampleM.MLME_DISASSOCIATE->Mac.MLME_DISASSOCIATE; + + AssociationExampleM.MLME_ORPHAN->Mac.MLME_ORPHAN; + AssociationExampleM.MLME_SYNC->Mac.MLME_SYNC; + AssociationExampleM.MLME_SYNC_LOSS->Mac.MLME_SYNC_LOSS; + AssociationExampleM.MLME_RESET->Mac.MLME_RESET; + + AssociationExampleM.MLME_SCAN->Mac.MLME_SCAN; + + + AssociationExampleM.MCPS_DATA->Mac.MCPS_DATA; + + +} diff --git a/tos/lib/net/zigbee/apps/AssociationExample/AssociationExampleM.nc b/tos/lib/net/zigbee/apps/AssociationExample/AssociationExampleM.nc new file mode 100644 index 00000000..99e4c799 --- /dev/null +++ b/tos/lib/net/zigbee/apps/AssociationExample/AssociationExampleM.nc @@ -0,0 +1,489 @@ +/* + * @author IPP HURRAY http://www.hurray.isep.ipp.pt/art-wise + * @author Andre Cunha + * + */ +#include +#include "printfUART.h" + +module AssociationExampleM { + + uses interface Boot; + uses interface Leds; + + uses interface Timer as Timer0; + + uses interface Timer as Timer_Send; + //MAC interfaces + + uses interface MLME_START; + + uses interface MLME_GET; + uses interface MLME_SET; + + uses interface MLME_BEACON_NOTIFY; + uses interface MLME_GTS; + + uses interface MLME_ASSOCIATE; + uses interface MLME_DISASSOCIATE; + + uses interface MLME_ORPHAN; + + uses interface MLME_SYNC; + uses interface MLME_SYNC_LOSS; + + uses interface MLME_RESET; + + uses interface MLME_SCAN; + + + uses interface MCPS_DATA; + +} +implementation { + + + //number of data frames sent after association and before dissassociation + uint16_t frame_counter=0; + + //associated devices + uint16_t address_poll = 0x0003; + + neighbour_table associated_devices[4]; + + uint16_t search_associated_devices(uint32_t ext1, uint32_t ext2); + + uint8_t number_associations =0; + + PANDescriptor pan_des; + + void try_disassociation(); + + uint16_t my_short_address= 0xffff; + + uint8_t received_beacon_count=0; + uint32_t coordinator_addr[2]; + + uint8_t go_associate =0; + + event void Boot.booted() { + + printfUART_init(); + + if (TYPE_DEVICE == COORDINATOR) + { + //assign the short address of the device + my_short_address = 0x0000; + call Timer0.startOneShot(3000); + } + else + { + call Timer0.startOneShot(8000); + } + + } + + + +event void Timer0.fired() { + + uint8_t v_temp[2]; + uint32_t c_addr[2]; + + if (TYPE_DEVICE == COORDINATOR) + { + + associated_devices[0].extended1=0x00000002; + associated_devices[0].extended2=0x00000002; + associated_devices[0].assigned_short=0x0004; + + //set the MAC short address variable + v_temp[0] = (uint8_t)(my_short_address >> 8); + v_temp[1] = (uint8_t)(my_short_address ); + + call MLME_SET.request(MACSHORTADDRESS,v_temp); + + //set the MAC PANID variable + v_temp[0] = (uint8_t)(MAC_PANID >> 8); + v_temp[1] = (uint8_t)(MAC_PANID ); + + call MLME_SET.request(MACPANID,v_temp); + + //start sending beacons + call MLME_START.request(MAC_PANID, LOGICAL_CHANNEL, BEACON_ORDER, SUPERFRAME_ORDER,1,0,0,0,0); + + //call Timer_Send.startPeriodic(3000); + } + else + { + //the device will try to scan all the channels looking for a suitable PAN coordinator + //only the ACTIVE SCAN/ED SCAN and a full channel scan is implemented + //call MLME_SCAN.request(PASSIVE_SCAN,0xFFFFFFFF,7); + //call MLME_SCAN.request(ED_SCAN,0xFFFFFFFF,0x10); + + c_addr[0] = 0x00000000; + c_addr[1] = 0x00000000; + + call MLME_ASSOCIATE.request(0x15,SHORT_ADDRESS,0x1234,c_addr,0x00,0x00); + + //call Leds.redOn(); + call Timer0.stop(); + } +} + +event void Timer_Send.fired() { + + uint32_t SrcAddr[2]; + uint32_t DstAddr[2]; + + uint8_t msdu_payload[4]; + + frame_counter++; + + if (frame_counter == 5) + { + //after sending 5 data frames the device tries to dissassociate from the PAN + call Timer_Send.stop(); + try_disassociation(); + + } + else + { + if (my_short_address == 0x0000ffff) + return; + + SrcAddr[0]=0x00000000; + SrcAddr[1]=my_short_address; + + DstAddr[0]=0x00000000; + DstAddr[1]=0x00000000; + + call MCPS_DATA.request(SHORT_ADDRESS, MAC_PANID, SrcAddr, SHORT_ADDRESS, MAC_PANID, DstAddr, 4, msdu_payload,1,set_txoptions(1,0,0,0)); + } +} + +/*****************************************************************************************************/ +/**************************************MLME-SCAN*******************************************************/ +/*****************************************************************************************************/ +event error_t MLME_SCAN.confirm(uint8_t status,uint8_t ScanType, uint32_t UnscannedChannels, uint8_t ResultListSize, uint8_t EnergyDetectList[], SCAN_PANDescriptor PANDescriptorList[]) +{ +//the device channel scan ends with a scan confirm containing a list of the PANs (beacons received during the scan) + + int i; + uint8_t max_lqi=0; + uint8_t best_pan_index=0; + + //call Leds.redOff(); + + printfUART("MLME_SCAN.confirm %i\n", ScanType); + + if (ScanType == ORPHAN_SCAN) + { + printfUART("new scan \n", ""); + + call MLME_SCAN.request(PASSIVE_SCAN,0xFFFFFFFF,7); + return SUCCESS; + } + + + + if(ScanType == ED_SCAN) + { + for(i=0;i> 8); + v_temp[1] = my_short_address; + + //call Leds.redOn(); + call MLME_SET.request(MACSHORTADDRESS,v_temp); + + call Timer_Send.startPeriodic(3000); + + call Timer0.stop(); + } + return SUCCESS; +} +/*****************************************************************************************************/ +/**************************************MLME-DISASSOCIATE**********************************************/ +/*****************************************************************************************************/ +event error_t MLME_DISASSOCIATE.indication(uint32_t DeviceAddress[], uint8_t DisassociateReason, bool SecurityUse, uint8_t ACLEntry) +{ + return SUCCESS; +} + +event error_t MLME_DISASSOCIATE.confirm(uint8_t status) +{ + return SUCCESS; +} +/*****************************************************************************************************/ +/*****************************************************************************************************/ +/**************** MCPS EVENTS *************************************/ +/*****************************************************************************************************/ +/*****************************************************************************************************/ + + +/*****************************************************************************************************/ +/********************* MCPS-DATA ***************************************/ +/*****************************************************************************************************/ +event error_t MCPS_DATA.confirm(uint8_t msduHandle, uint8_t status) +{ + +return SUCCESS; +} +event error_t MCPS_DATA.indication(uint16_t SrcAddrMode, uint16_t SrcPANId, uint32_t SrcAddr[2], uint16_t DstAddrMode, uint16_t DestPANId, uint32_t DstAddr[2], uint16_t msduLength,uint8_t msdu[100],uint16_t mpduLinkQuality, uint16_t SecurityUse, uint16_t ACLEntry) +{ + //call Leds.led1Toggle(); + +return SUCCESS; +} + + + +void try_disassociation() +{ + + uint32_t coordinator_addr1[2]; + + coordinator_addr1[0] = 0x00000001; + + coordinator_addr1[1] = 0x00000001; + + call MLME_DISASSOCIATE.request(coordinator_addr1,MAC_PAN_DEVICE_LEAVE,0x00); + + +return; +} + +} + diff --git a/tos/lib/net/zigbee/apps/AssociationExample/Makefile b/tos/lib/net/zigbee/apps/AssociationExample/Makefile new file mode 100644 index 00000000..61dcca8f --- /dev/null +++ b/tos/lib/net/zigbee/apps/AssociationExample/Makefile @@ -0,0 +1,12 @@ +COMPONENT=AssociationExample + +PFLAGS += -I$(TOSROOT)/tos/lib/net/zigbee/ieee802154/includes \ + -I$(TOSROOT)/tos/lib/net/zigbee/ieee802154/mac \ + -I$(TOSROOT)/tos/lib/net/zigbee/ieee802154/phy \ + -I$(TOSROOT)/tos/lib/net/zigbee/ieee802154/timerasync \ + -I$(TOSROOT)/tos/lib/net/zigbee/ieee802154/interfaces \ + -I$(TOSROOT)/tos/lib/net/zigbee/ieee802154/interfaces/mac \ + -I$(TOSROOT)/tos/lib/net/zigbee/ieee802154/interfaces/phy \ + -I$(TOSROOT)/tos/lib/net/zigbee/cc2420 +include $(MAKERULES) + diff --git a/tos/lib/net/zigbee/apps/AssociationExample/associationexample.h b/tos/lib/net/zigbee/apps/AssociationExample/associationexample.h new file mode 100644 index 00000000..a8bde4af --- /dev/null +++ b/tos/lib/net/zigbee/apps/AssociationExample/associationexample.h @@ -0,0 +1,27 @@ +enum { + COORDINATOR = 0x00, + ROUTER =0x01, + END_DEVICE = 0x02 + }; + +#define BEACON_ORDER 6 +#define SUPERFRAME_ORDER 4 +//the starting channel needs to be diferrent that the existent coordinator operating channels +#define LOGICAL_CHANNEL 0x15 + + +#define TYPE_DEVICE END_DEVICE +//#define TYPE_DEVICE COORDINATOR + +//PAN VARIABLES +#define MAC_PANID 0x1234 + +typedef struct{ + +uint32_t extended1; +uint32_t extended2; +uint16_t assigned_short; + +}neighbour_table; + + diff --git a/tos/lib/net/zigbee/apps/DataSendExample/DataSendExample.nc b/tos/lib/net/zigbee/apps/DataSendExample/DataSendExample.nc new file mode 100644 index 00000000..1463b31c --- /dev/null +++ b/tos/lib/net/zigbee/apps/DataSendExample/DataSendExample.nc @@ -0,0 +1,60 @@ +/** + * @author IPP HURRAY http://www.hurray.isep.ipp.pt/art-wise + * @author Andre Cunha + */ +#include + +#include "datasendexample.h" +#include "phy_const.h" +#include "phy_enumerations.h" +#include "mac_const.h" +#include "mac_enumerations.h" +#include "mac_func.h" + +configuration DataSendExample { +} + +implementation +{ + components MainC; + components LedsC; + components DataSendExampleM; + + DataSendExampleM.Boot -> MainC; + + components Mac; + + DataSendExampleM.Leds -> LedsC; + + components new TimerMilliC() as Timer0; + DataSendExampleM.Timer0 -> Timer0; + + components new TimerMilliC() as Timer_Send; + DataSendExampleM.Timer_Send ->Timer_Send; + + + //MAC interfaces + + DataSendExampleM.MLME_START -> Mac.MLME_START; + + DataSendExampleM.MLME_GET ->Mac.MLME_GET; + DataSendExampleM.MLME_SET ->Mac.MLME_SET; + + DataSendExampleM.MLME_BEACON_NOTIFY ->Mac.MLME_BEACON_NOTIFY; + DataSendExampleM.MLME_GTS -> Mac.MLME_GTS; + + DataSendExampleM.MLME_ASSOCIATE->Mac.MLME_ASSOCIATE; + DataSendExampleM.MLME_DISASSOCIATE->Mac.MLME_DISASSOCIATE; + + DataSendExampleM.MLME_ORPHAN->Mac.MLME_ORPHAN; + DataSendExampleM.MLME_SYNC->Mac.MLME_SYNC; + DataSendExampleM.MLME_SYNC_LOSS->Mac.MLME_SYNC_LOSS; + DataSendExampleM.MLME_RESET->Mac.MLME_RESET; + + DataSendExampleM.MLME_SCAN->Mac.MLME_SCAN; + + DataSendExampleM.MCPS_DATA->Mac.MCPS_DATA; + + +} + diff --git a/tos/lib/net/zigbee/apps/DataSendExample/DataSendExampleM.nc b/tos/lib/net/zigbee/apps/DataSendExample/DataSendExampleM.nc new file mode 100644 index 00000000..fd8760b8 --- /dev/null +++ b/tos/lib/net/zigbee/apps/DataSendExample/DataSendExampleM.nc @@ -0,0 +1,315 @@ +/* + * + * @author IPP HURRAY http://www.hurray.isep.ipp.pt/art-wise + * @author Andre Cunha + * + */ + +#include +#include "printfUART.h" + +module DataSendExampleM { + + uses interface Boot; + uses interface Leds; + + uses interface Timer as Timer0; + + uses interface Timer as Timer_Send; + //MAC interfaces + + uses interface MLME_START; + + uses interface MLME_GET; + uses interface MLME_SET; + + uses interface MLME_BEACON_NOTIFY; + uses interface MLME_GTS; + + uses interface MLME_ASSOCIATE; + uses interface MLME_DISASSOCIATE; + + uses interface MLME_ORPHAN; + + uses interface MLME_SYNC; + uses interface MLME_SYNC_LOSS; + + uses interface MLME_RESET; + + uses interface MLME_SCAN; + + uses interface MCPS_DATA; + +} +implementation { + + uint8_t beacon_present=0; + uint8_t on_sync=0; + + PANDescriptor pan_des; + + uint32_t my_short_address=0x00000000; + uint32_t my_pan_id=0x00001234; + + uint32_t DestinationMote[2]; + + + event void Boot.booted() { + + printfUART_init(); + + printfUART("i_am_pan: %i\n", TYPE_DEVICE); + + DestinationMote[0]=0x00000000; + DestinationMote[1]=0x00000002; + + if (TYPE_DEVICE == COORDINATOR) + { + my_short_address = 0x0000; + call Timer0.startOneShot(3000); + } + else + { + call Timer0.startOneShot(8000); + } + + } + + + event void Timer0.fired() { + + uint8_t v_temp[2]; + + + if (TYPE_DEVICE == END_DEVICE) + { + + my_short_address = TOS_NODE_ID; + + //set the MAC short address variable + v_temp[0] = (uint8_t)(my_short_address >> 8); + v_temp[1] = (uint8_t)(my_short_address ); + + call MLME_SET.request(MACSHORTADDRESS,v_temp); + + //set the MAC PANID variable + v_temp[0] = (uint8_t)(MAC_PANID >> 8); + v_temp[1] = (uint8_t)(MAC_PANID ); + + call MLME_SET.request(MACPANID,v_temp); + + call Timer_Send.startPeriodic(3000); + + } + else + { + //set the MAC short address variable + v_temp[0] = (uint8_t)(my_short_address >> 8); + v_temp[1] = (uint8_t)(my_short_address ); + + call MLME_SET.request(MACSHORTADDRESS,v_temp); + + //set the MAC PANID variable + v_temp[0] = (uint8_t)(MAC_PANID >> 8); + v_temp[1] = (uint8_t)(MAC_PANID ); + + call MLME_SET.request(MACPANID,v_temp); + + //start sending beacons + call MLME_START.request(MAC_PANID, LOGICAL_CHANNEL, BEACON_ORDER, SUPERFRAME_ORDER,1,0,0,0,0); + + //call Timer_send.start(TIMER_REPEAT,8000); + } + + + + + } + +event void Timer_Send.fired() { + + + uint32_t SrcAddr[2]; + + uint8_t msdu_payload[4]; + + SrcAddr[0]=0x00000000; + SrcAddr[1]=TOS_NODE_ID; + + //DestinationMote[0]=0x00000000; + //DestinationMote[1]=0x0000FFFF; + + + + if(TYPE_DEVICE == COORDINATOR) + { + + SrcAddr[0]=0x00000000; + SrcAddr[1]=TOS_NODE_ID; + + if (DestinationMote[1]==0x00000002) + { + DestinationMote[1]=0x00000003; + }else{ + DestinationMote[1]=0x00000002; + } + //printfUART("send to: %i\n", DestinationMote[1]); + //call Leds.greenToggle(); + //set_txoptions(ack, gts, indirect_transmission, security) + call MCPS_DATA.request(SHORT_ADDRESS, MAC_PANID, SrcAddr, SHORT_ADDRESS, MAC_PANID, DestinationMote, 4, msdu_payload,1,set_txoptions(1,0,0,0)); + } + else + { + + DestinationMote[0]=0x00000000; + DestinationMote[1]=0x00000000; + //set_txoptions(ack, gts, indirect_transmission, security) + call MCPS_DATA.request(SHORT_ADDRESS, MAC_PANID, SrcAddr, SHORT_ADDRESS, MAC_PANID, DestinationMote, 4, msdu_payload,1,set_txoptions(1,0,0,0)); + } + + + } +/*****************************************************************************************************/ +/**************************************MLME-SCAN*******************************************************/ +/*****************************************************************************************************/ +event error_t MLME_SCAN.confirm(uint8_t status,uint8_t ScanType, uint32_t UnscannedChannels, uint8_t ResultListSize, uint8_t EnergyDetectList[], SCAN_PANDescriptor PANDescriptorList[]) +{ + + + return SUCCESS; +} + +/*****************************************************************************************************/ +/**************************************MLME-ORPHAN*******************************************************/ +/*****************************************************************************************************/ + +event error_t MLME_ORPHAN.indication(uint32_t OrphanAddress[1], uint8_t SecurityUse, uint8_t ACLEntry) +{ + +return SUCCESS; +} + +/*****************************************************************************************************/ +/**************************************MLME-RESET*******************************************************/ +/*****************************************************************************************************/ +event error_t MLME_RESET.confirm(uint8_t status) +{ + +return SUCCESS; +} + + + /*****************************************************************************************************/ +/**************************************MLME-SYNC-LOSS*******************************************************/ +/*****************************************************************************************************/ +event error_t MLME_SYNC_LOSS.indication(uint8_t LossReason) +{ + +return SUCCESS; +} + + + /*****************************************************************************************************/ +/**************************************MLME-GTS*******************************************************/ +/*****************************************************************************************************/ + +event error_t MLME_GTS.confirm(uint8_t GTSCharacteristics, uint8_t status) +{ + + return SUCCESS; +} + +event error_t MLME_GTS.indication(uint16_t DevAddress, uint8_t GTSCharacteristics, bool SecurityUse, uint8_t ACLEntry) +{ + return SUCCESS; +} + /*****************************************************************************************************/ +/**************************************MLME-BEACON NOTIFY*********************************************/ +/*****************************************************************************************************/ + +event error_t MLME_BEACON_NOTIFY.indication(uint8_t BSN,PANDescriptor pan_descriptor, uint8_t PenAddrSpec, uint8_t AddrList, uint8_t sduLength, uint8_t sdu[]) +{ + + return SUCCESS; +} +/*****************************************************************************************************/ +/**************************************MLME-START*****************************************************/ +/*****************************************************************************************************/ + event error_t MLME_START.confirm(uint8_t status) + { + + + return SUCCESS; + } + /*****************************************************************************************************/ +/********************** MLME-SET ******************************************/ +/*****************************************************************************************************/ + + event error_t MLME_SET.confirm(uint8_t status,uint8_t PIBAttribute) + { + + + return SUCCESS; + } + /*****************************************************************************************************/ +/************************* MLME-GET ******************************************/ +/*****************************************************************************************************/ + event error_t MLME_GET.confirm(uint8_t status,uint8_t PIBAttribute, uint8_t PIBAttributeValue[]) + { + + + return SUCCESS; + } + + + /*****************************************************************************************************/ +/**************************************MLME-ASSOCIATE*************************************************/ +/*****************************************************************************************************/ +event error_t MLME_ASSOCIATE.indication(uint32_t DeviceAddress[], uint8_t CapabilityInformation, bool SecurityUse, uint8_t ACLEntry) +{ + + return SUCCESS; +} + +event error_t MLME_ASSOCIATE.confirm(uint16_t AssocShortAddress, uint8_t status) +{ + + return SUCCESS; +} + /*****************************************************************************************************/ +/**************************************MLME-DISASSOCIATE**********************************************/ +/*****************************************************************************************************/ +event error_t MLME_DISASSOCIATE.indication(uint32_t DeviceAddress[], uint8_t DisassociateReason, bool SecurityUse, uint8_t ACLEntry) +{ + return SUCCESS; +} + +event error_t MLME_DISASSOCIATE.confirm(uint8_t status) +{ + return SUCCESS; +} + /*****************************************************************************************************/ +/*****************************************************************************************************/ +/**************** MCPS EVENTS *************************************/ +/*****************************************************************************************************/ +/*****************************************************************************************************/ + + +/*****************************************************************************************************/ +/********************* MCPS-DATA ***************************************/ +/*****************************************************************************************************/ +event error_t MCPS_DATA.confirm(uint8_t msduHandle, uint8_t status) +{ + +return SUCCESS; +} +event error_t MCPS_DATA.indication(uint16_t SrcAddrMode, uint16_t SrcPANId, uint32_t SrcAddr[2], uint16_t DstAddrMode, uint16_t DestPANId, uint32_t DstAddr[2], uint16_t msduLength,uint8_t msdu[100],uint16_t mpduLinkQuality, uint16_t SecurityUse, uint16_t ACLEntry) +{ + //call Leds.led1Toggle(); + +return SUCCESS; +} + + +} + diff --git a/tos/lib/net/zigbee/apps/DataSendExample/Makefile b/tos/lib/net/zigbee/apps/DataSendExample/Makefile new file mode 100644 index 00000000..f9e6b4b5 --- /dev/null +++ b/tos/lib/net/zigbee/apps/DataSendExample/Makefile @@ -0,0 +1,11 @@ +COMPONENT=DataSendExample + +PFLAGS += -I$(TOSROOT)/tos/lib/net/zigbee/ieee802154/includes \ + -I$(TOSROOT)/tos/lib/net/zigbee/ieee802154/mac \ + -I$(TOSROOT)/tos/lib/net/zigbee/ieee802154/phy \ + -I$(TOSROOT)/tos/lib/net/zigbee/ieee802154/timerasync \ + -I$(TOSROOT)/tos/lib/net/zigbee/ieee802154/interfaces \ + -I$(TOSROOT)/tos/lib/net/zigbee/ieee802154/interfaces/mac \ + -I$(TOSROOT)/tos/lib/net/zigbee/ieee802154/interfaces/phy \ + -I$(TOSROOT)/tos/lib/net/zigbee/cc2420 +include $(MAKERULES) diff --git a/tos/lib/net/zigbee/apps/DataSendExample/datasendexample.h b/tos/lib/net/zigbee/apps/DataSendExample/datasendexample.h new file mode 100644 index 00000000..5878f4f8 --- /dev/null +++ b/tos/lib/net/zigbee/apps/DataSendExample/datasendexample.h @@ -0,0 +1,19 @@ +enum { + COORDINATOR = 0x00, + ROUTER =0x01, + END_DEVICE = 0x02 + }; + +#define BEACON_ORDER 6 +#define SUPERFRAME_ORDER 4 + +#define LOGICAL_CHANNEL 0x15 + + +#define TYPE_DEVICE END_DEVICE +//#define TYPE_DEVICE COORDINATOR + +//PAN VARIABLES +#define MAC_PANID 0x1234 + + diff --git a/tos/lib/net/zigbee/apps/GTSManagementExample/GTSManagementExample.nc b/tos/lib/net/zigbee/apps/GTSManagementExample/GTSManagementExample.nc new file mode 100644 index 00000000..fda840ee --- /dev/null +++ b/tos/lib/net/zigbee/apps/GTSManagementExample/GTSManagementExample.nc @@ -0,0 +1,61 @@ +/** + * @author IPP HURRAY http://www.hurray.isep.ipp.pt/art-wise + * @author Andre Cunha + */ +#include + +#include "gtsmanagementexample.h" +#include "phy_const.h" +#include "phy_enumerations.h" +#include "mac_const.h" +#include "mac_enumerations.h" +#include "mac_func.h" + + +configuration GTSManagementExample { +} +implementation { + + components MainC; + components LedsC; + components GTSManagementExampleM; + + GTSManagementExampleM.Boot -> MainC; + + components Mac; + + GTSManagementExampleM.Leds -> LedsC; + + components new TimerMilliC() as Timer0; + GTSManagementExampleM.Timer0 -> Timer0; + + components new TimerMilliC() as Timer_Send; + GTSManagementExampleM.Timer_Send ->Timer_Send; + + + //MAC interfaces + + GTSManagementExampleM.MLME_START -> Mac.MLME_START; + + GTSManagementExampleM.MLME_GET ->Mac.MLME_GET; + GTSManagementExampleM.MLME_SET ->Mac.MLME_SET; + + GTSManagementExampleM.MLME_BEACON_NOTIFY ->Mac.MLME_BEACON_NOTIFY; + GTSManagementExampleM.MLME_GTS -> Mac.MLME_GTS; + + GTSManagementExampleM.MLME_ASSOCIATE->Mac.MLME_ASSOCIATE; + GTSManagementExampleM.MLME_DISASSOCIATE->Mac.MLME_DISASSOCIATE; + + GTSManagementExampleM.MLME_ORPHAN->Mac.MLME_ORPHAN; + GTSManagementExampleM.MLME_SYNC->Mac.MLME_SYNC; + GTSManagementExampleM.MLME_SYNC_LOSS->Mac.MLME_SYNC_LOSS; + GTSManagementExampleM.MLME_RESET->Mac.MLME_RESET; + + GTSManagementExampleM.MLME_SCAN->Mac.MLME_SCAN; + + + GTSManagementExampleM.MCPS_DATA->Mac.MCPS_DATA; + + +} + diff --git a/tos/lib/net/zigbee/apps/GTSManagementExample/GTSManagementExampleM.nc b/tos/lib/net/zigbee/apps/GTSManagementExample/GTSManagementExampleM.nc new file mode 100644 index 00000000..5ba55566 --- /dev/null +++ b/tos/lib/net/zigbee/apps/GTSManagementExample/GTSManagementExampleM.nc @@ -0,0 +1,339 @@ +/* + * + * @author IPP HURRAY http://www.hurray.isep.ipp.pt/art-wise + * @author Andre Cunha + * + */ +/* + * @author IPP HURRAY http://www.hurray.isep.ipp.pt/art-wise + * @author Andre Cunha + * + */ +#include +#include "printfUART.h" + +module GTSManagementExampleM { + + uses interface Boot; + uses interface Leds; + + uses interface Timer as Timer0; + + uses interface Timer as Timer_Send; + //MAC interfaces + + uses interface MLME_START; + + uses interface MLME_GET; + uses interface MLME_SET; + + uses interface MLME_BEACON_NOTIFY; + uses interface MLME_GTS; + + uses interface MLME_ASSOCIATE; + uses interface MLME_DISASSOCIATE; + + uses interface MLME_ORPHAN; + + uses interface MLME_SYNC; + uses interface MLME_SYNC_LOSS; + + uses interface MLME_RESET; + + uses interface MLME_SCAN; + + uses interface MCPS_DATA; + +} +implementation { + + + uint8_t beacon_present=0; + uint8_t on_sync=0; + uint8_t gts_allocated=0; + + uint8_t gts_superframe_count=0; + + PANDescriptor pan_des; + + uint32_t my_short_address=0x00000000; + uint32_t my_pan_id=0x00000001; + + + + event void Boot.booted() { + + printfUART_init(); + + if (TYPE_DEVICE == COORDINATOR) + { + //assign the short address of the device + my_short_address = 0x0000; + call Timer0.startOneShot(5000); + } + else + { + call Timer0.startOneShot(8000); + } + + } + + + + event void Timer0.fired() { + + uint8_t v_temp[2]; + + + + if (TYPE_DEVICE == COORDINATOR) + { + + //set the MAC short address variable + v_temp[0] = (uint8_t)(my_short_address >> 8); + v_temp[1] = (uint8_t)(my_short_address ); + + call MLME_SET.request(MACSHORTADDRESS,v_temp); + + //set the MAC PANID variable + v_temp[0] = (uint8_t)(MAC_PANID >> 8); + v_temp[1] = (uint8_t)(MAC_PANID ); + + call MLME_SET.request(MACPANID,v_temp); + + //start sending beacons + call MLME_START.request(MAC_PANID, LOGICAL_CHANNEL, BEACON_ORDER, SUPERFRAME_ORDER,1,0,0,0,0); + + //call Timer_Send.startPeriodic(3000); + } + else + { + my_short_address = TOS_NODE_ID; + v_temp[0] = (uint8_t)(my_short_address >> 8); + v_temp[1] = (uint8_t)(my_short_address ); + + call MLME_SET.request(MACSHORTADDRESS,v_temp); + + //call Leds.greenOn(); + gts_superframe_count=0; + + + printfUART("GTS req: %i\n", TYPE_DEVICE); + + + //allocate a transmission GTS - enables a GTS time slot allocation for the device transmission to the PAN Coordinator + call MLME_GTS.request(set_gts_characteristics(1, GTS_TX_ONLY,1),0x00); + + //allocate a transmission GTS - enables a GTS time slot allocation for the PAN coordinator transmission to the device + //call MLME_GTS.request(set_gts_characteristics(1, GTS_RX_ONLY,1),0x00); + + + //enable the transmission of the device to the PAN coordinator in the allocated transmit GTS + call Timer_Send.startPeriodic(1000); + + } + + } + +event void Timer_Send.fired() { + + + uint32_t SrcAddr[2]; + uint32_t DstAddr[2]; + uint8_t msdu_payload[4]; + + if (TYPE_DEVICE == COORDINATOR) + { + SrcAddr[0]=0x00000000; + SrcAddr[1]=TOS_NODE_ID; + + DstAddr[0]=0x00000000; + DstAddr[1]=0x00000002; + + call MCPS_DATA.request(SHORT_ADDRESS, MAC_PANID, SrcAddr, SHORT_ADDRESS, MAC_PANID, DstAddr, 4, msdu_payload,1,set_txoptions(1,1,0,0)); + } + else + { + call Leds.led1Toggle(); + + + SrcAddr[0]=0x00000000; + SrcAddr[1]=TOS_NODE_ID; + + DstAddr[0]=0x00000000; + DstAddr[1]=0x00000000; + + call MCPS_DATA.request(SHORT_ADDRESS, MAC_PANID, SrcAddr, SHORT_ADDRESS, MAC_PANID, DstAddr, 4, msdu_payload,1,set_txoptions(1,1,0,0)); + } + +} + + +/*****************************************************************************************************/ +/**************************************MLME-SCAN*******************************************************/ +/*****************************************************************************************************/ +event error_t MLME_SCAN.confirm(uint8_t status,uint8_t ScanType, uint32_t UnscannedChannels, uint8_t ResultListSize, uint8_t EnergyDetectList[], SCAN_PANDescriptor PANDescriptorList[]) +{ + + return SUCCESS; +} + +/*****************************************************************************************************/ +/**************************************MLME-ORPHAN****************************************************/ +/*****************************************************************************************************/ +event error_t MLME_ORPHAN.indication(uint32_t OrphanAddress[1], uint8_t SecurityUse, uint8_t ACLEntry) +{ + + return SUCCESS; +} +/*****************************************************************************************************/ +/**************************************MLME-RESET*****************************************************/ +/*****************************************************************************************************/ +event error_t MLME_RESET.confirm(uint8_t status) +{ + + + + return SUCCESS; +} +/*****************************************************************************************************/ +/**************************************MLME-SYNC-LOSS*************************************************/ +/*****************************************************************************************************/ +event error_t MLME_SYNC_LOSS.indication(uint8_t LossReason) +{ + + return SUCCESS; +} + +/*****************************************************************************************************/ +/**************************************MLME-GTS*******************************************************/ +/*****************************************************************************************************/ + +event error_t MLME_GTS.confirm(uint8_t GTSCharacteristics, uint8_t status) +{ + switch(status) + { + case MAC_SUCCESS: gts_allocated=1; + call Leds.led1Toggle(); + break; + + case MAC_DENIED: gts_allocated=0; + break; + + case MAC_NO_SHORT_ADDRESS: gts_allocated=0; + break; + + case MAC_CHANNEL_ACCESS_FAILURE: gts_allocated=0; + break; + + case MAC_NO_ACK: gts_allocated=0;break; + + case MAC_NO_DATA: gts_allocated=0;break; + + + default: break; + + } + + return SUCCESS; +} + +event error_t MLME_GTS.indication(uint16_t DevAddress, uint8_t GTSCharacteristics, bool SecurityUse, uint8_t ACLEntry) +{ + return SUCCESS; +} + /*****************************************************************************************************/ +/**************************************MLME-BEACON NOTIFY*********************************************/ +/*****************************************************************************************************/ + +event error_t MLME_BEACON_NOTIFY.indication(uint8_t BSN,PANDescriptor pan_descriptor, uint8_t PenAddrSpec, uint8_t AddrList, uint8_t sduLength, uint8_t sdu[]) +{ + gts_superframe_count++; + if (gts_superframe_count==30) + { + //call Leds.greenOff(); + call MLME_GTS.request(set_gts_characteristics(1, GTS_TX_ONLY,0),0x00); + } + return SUCCESS; +} +/*****************************************************************************************************/ +/**************************************MLME-START*****************************************************/ +/*****************************************************************************************************/ + event error_t MLME_START.confirm(uint8_t status) + { + + + return SUCCESS; + } + /*****************************************************************************************************/ +/********************** MLME-SET ******************************************/ +/*****************************************************************************************************/ + + event error_t MLME_SET.confirm(uint8_t status,uint8_t PIBAttribute) + { + + + return SUCCESS; + } + /*****************************************************************************************************/ +/************************* MLME-GET ******************************************/ +/*****************************************************************************************************/ + event error_t MLME_GET.confirm(uint8_t status,uint8_t PIBAttribute, uint8_t PIBAttributeValue[]) + { + + + return SUCCESS; + } + + + /*****************************************************************************************************/ +/**************************************MLME-ASSOCIATE*************************************************/ +/*****************************************************************************************************/ +event error_t MLME_ASSOCIATE.indication(uint32_t DeviceAddress[], uint8_t CapabilityInformation, bool SecurityUse, uint8_t ACLEntry) +{ + + return SUCCESS; +} + +event error_t MLME_ASSOCIATE.confirm(uint16_t AssocShortAddress, uint8_t status) +{ + + return SUCCESS; +} + /*****************************************************************************************************/ +/**************************************MLME-DISASSOCIATE**********************************************/ +/*****************************************************************************************************/ +event error_t MLME_DISASSOCIATE.indication(uint32_t DeviceAddress[], uint8_t DisassociateReason, bool SecurityUse, uint8_t ACLEntry) +{ + return SUCCESS; +} + +event error_t MLME_DISASSOCIATE.confirm(uint8_t status) +{ + return SUCCESS; +} + /*****************************************************************************************************/ +/*****************************************************************************************************/ +/**************** MCPS EVENTS *************************************/ +/*****************************************************************************************************/ +/*****************************************************************************************************/ + + +/*****************************************************************************************************/ +/********************* MCPS-DATA ***************************************/ +/*****************************************************************************************************/ +event error_t MCPS_DATA.confirm(uint8_t msduHandle, uint8_t status) +{ + +return SUCCESS; +} +event error_t MCPS_DATA.indication(uint16_t SrcAddrMode, uint16_t SrcPANId, uint32_t SrcAddr[2], uint16_t DstAddrMode, uint16_t DestPANId, uint32_t DstAddr[2], uint16_t msduLength,uint8_t msdu[100],uint16_t mpduLinkQuality, uint16_t SecurityUse, uint16_t ACLEntry) +{ + + +return SUCCESS; +} + + +} + diff --git a/tos/lib/net/zigbee/apps/GTSManagementExample/Makefile b/tos/lib/net/zigbee/apps/GTSManagementExample/Makefile new file mode 100644 index 00000000..13e57082 --- /dev/null +++ b/tos/lib/net/zigbee/apps/GTSManagementExample/Makefile @@ -0,0 +1,11 @@ +COMPONENT=GTSManagementExample + +PFLAGS += -I$(TOSROOT)/tos/lib/net/zigbee/ieee802154/includes \ + -I$(TOSROOT)/tos/lib/net/zigbee/ieee802154/mac \ + -I$(TOSROOT)/tos/lib/net/zigbee/ieee802154/phy \ + -I$(TOSROOT)/tos/lib/net/zigbee/ieee802154/timerasync \ + -I$(TOSROOT)/tos/lib/net/zigbee/ieee802154/interfaces \ + -I$(TOSROOT)/tos/lib/net/zigbee/ieee802154/interfaces/mac \ + -I$(TOSROOT)/tos/lib/net/zigbee/ieee802154/interfaces/phy \ + -I$(TOSROOT)/tos/lib/net/zigbee/cc2420 +include $(MAKERULES) \ No newline at end of file diff --git a/tos/lib/net/zigbee/apps/GTSManagementExample/gtsmanagementexample.h b/tos/lib/net/zigbee/apps/GTSManagementExample/gtsmanagementexample.h new file mode 100644 index 00000000..2d1ffcae --- /dev/null +++ b/tos/lib/net/zigbee/apps/GTSManagementExample/gtsmanagementexample.h @@ -0,0 +1,18 @@ +enum { + COORDINATOR = 0x00, + ROUTER =0x01, + END_DEVICE = 0x02 + }; + +#define BEACON_ORDER 6 +#define SUPERFRAME_ORDER 4 +//the starting channel needs to be diferrent that the existent coordinator operating channels +#define LOGICAL_CHANNEL 0x15 + + +#define TYPE_DEVICE END_DEVICE +//#define TYPE_DEVICE COORDINATOR + +//PAN VARIABLES +#define MAC_PANID 0x1234 + diff --git a/tos/lib/net/zigbee/apps/Makefile b/tos/lib/net/zigbee/apps/Makefile new file mode 100644 index 00000000..7ca8632f --- /dev/null +++ b/tos/lib/net/zigbee/apps/Makefile @@ -0,0 +1,50 @@ +#-*-makefile-*- +###################################################################### +# +# Makes the entire suite of TinyOS applications for a given platform. +# +# Author: Martin Turon +# Date: August 18, 2005 +# +###################################################################### +# $Id$ + +# MAKECMDGOALS is the way to get the arguments passed into a Makefile ... +TARGET=$(MAKECMDGOALS) +NESDOC_TARGET=$(filter-out nesdoc,$(TARGET)) + +# Here is a way to get the list of subdirectories in a Makefile ... +ROOT=. +SUBDIRS := $(shell find * -type d) + +# Okay, match any target, and recurse the subdirectories +%: + @for i in $(SUBDIRS); do \ + HERE=$$PWD; \ + if [ -f $$i/Makefile ]; then \ + echo Building ... $(PWD)/$$i; \ + echo make $(TARGET); \ + cd $$i; \ + $(MAKE) $(TARGET); \ + cd $$HERE; \ + fi; \ + done + +BASEDIR = $(shell pwd | sed 's@\(.*\)/apps.*$$@\1@' ) +# The output directory for generated documentation +DOCDIR = $(BASEDIR)/doc/nesdoc + +nesdoc: + @echo This target rebuilds documentation for all known platforms. + @echo It DOES NOT overwrite any existing documentation, thus, it + @echo is best run after deleting all old documentation. + @echo + @echo To delete all old documentation, delete the contents of the + @echo $(DOCDIR) directory. + @echo + @echo Press Enter to continue, or ^C to abort. + @read + for platform in `ncc -print-platforms`; do \ + $(MAKE) $$platform docs.nohtml.preserve; \ + nesdoc -o $(DOCDIR) -html -target=$$platform; \ + done diff --git a/tos/lib/net/zigbee/apps/SimpleRoutingExample/Makefile b/tos/lib/net/zigbee/apps/SimpleRoutingExample/Makefile new file mode 100644 index 00000000..4c3b2fcf --- /dev/null +++ b/tos/lib/net/zigbee/apps/SimpleRoutingExample/Makefile @@ -0,0 +1,11 @@ +COMPONENT=SimpleRoutingExample + +PFLAGS += -I$(TOSROOT)/tos/lib/net/zigbee/ieee802154/includes \ + -I$(TOSROOT)/tos/lib/net/zigbee/ieee802154/mac \ + -I$(TOSROOT)/tos/lib/net/zigbee/ieee802154/phy \ + -I$(TOSROOT)/tos/lib/net/zigbee/ieee802154/timerasync \ + -I$(TOSROOT)/tos/lib/net/zigbee/ieee802154/interfaces \ + -I$(TOSROOT)/tos/lib/net/zigbee/ieee802154/interfaces/mac \ + -I$(TOSROOT)/tos/lib/net/zigbee/ieee802154/interfaces/phy \ + -I$(TOSROOT)/tos/lib/net/zigbee/cc2420 +include $(MAKERULES) \ No newline at end of file diff --git a/tos/lib/net/zigbee/apps/SimpleRoutingExample/SimpleRoutingExample.nc b/tos/lib/net/zigbee/apps/SimpleRoutingExample/SimpleRoutingExample.nc new file mode 100644 index 00000000..115572bf --- /dev/null +++ b/tos/lib/net/zigbee/apps/SimpleRoutingExample/SimpleRoutingExample.nc @@ -0,0 +1,61 @@ +/** + * @author IPP HURRAY http://www.hurray.isep.ipp.pt/art-wise + * @author Andre Cunha + */ +#include + +#include "simpleroutingexample.h" +#include "phy_const.h" +#include "phy_enumerations.h" +#include "mac_const.h" +#include "mac_enumerations.h" +#include "mac_func.h" + + configuration SimpleRoutingExample { +} + +implementation +{ + components MainC; + components LedsC; + components SimpleRoutingExampleM; + + SimpleRoutingExampleM.Boot -> MainC; + + components Mac; + + SimpleRoutingExampleM.Leds -> LedsC; + + components new TimerMilliC() as Timer0; + SimpleRoutingExampleM.Timer0 -> Timer0; + + components new TimerMilliC() as Timer_Send; + SimpleRoutingExampleM.Timer_Send ->Timer_Send; + + + //MAC interfaces + + SimpleRoutingExampleM.MLME_START -> Mac.MLME_START; + + SimpleRoutingExampleM.MLME_GET ->Mac.MLME_GET; + SimpleRoutingExampleM.MLME_SET ->Mac.MLME_SET; + + SimpleRoutingExampleM.MLME_BEACON_NOTIFY ->Mac.MLME_BEACON_NOTIFY; + SimpleRoutingExampleM.MLME_GTS -> Mac.MLME_GTS; + + SimpleRoutingExampleM.MLME_ASSOCIATE->Mac.MLME_ASSOCIATE; + SimpleRoutingExampleM.MLME_DISASSOCIATE->Mac.MLME_DISASSOCIATE; + + SimpleRoutingExampleM.MLME_ORPHAN->Mac.MLME_ORPHAN; + SimpleRoutingExampleM.MLME_SYNC->Mac.MLME_SYNC; + SimpleRoutingExampleM.MLME_SYNC_LOSS->Mac.MLME_SYNC_LOSS; + SimpleRoutingExampleM.MLME_RESET->Mac.MLME_RESET; + + SimpleRoutingExampleM.MLME_SCAN->Mac.MLME_SCAN; + + + SimpleRoutingExampleM.MCPS_DATA->Mac.MCPS_DATA; + + +} + diff --git a/tos/lib/net/zigbee/apps/SimpleRoutingExample/SimpleRoutingExampleM.nc b/tos/lib/net/zigbee/apps/SimpleRoutingExample/SimpleRoutingExampleM.nc new file mode 100644 index 00000000..8f25b938 --- /dev/null +++ b/tos/lib/net/zigbee/apps/SimpleRoutingExample/SimpleRoutingExampleM.nc @@ -0,0 +1,308 @@ +/* + * + * @author IPP HURRAY http://www.hurray.isep.ipp.pt/art-wise + * @author Andre Cunha + * + */ + +#include +#include "printfUART.h" + +module SimpleRoutingExampleM { + + uses interface Boot; + uses interface Leds; + + uses interface Timer as Timer0; + + uses interface Timer as Timer_Send; + //MAC interfaces + + uses interface MLME_START; + + uses interface MLME_GET; + uses interface MLME_SET; + + uses interface MLME_BEACON_NOTIFY; + uses interface MLME_GTS; + + uses interface MLME_ASSOCIATE; + uses interface MLME_DISASSOCIATE; + + uses interface MLME_ORPHAN; + + uses interface MLME_SYNC; + uses interface MLME_SYNC_LOSS; + + uses interface MLME_RESET; + + uses interface MLME_SCAN; + + uses interface MCPS_DATA; + +} +implementation { + + PANDescriptor pan_des; + + uint32_t my_short_address=0x00000000; + + uint32_t DestinationMote[2]; + uint32_t SourceMoteAddr[2]; + + //number of routed packet (coordinator) + uint8_t routed_packets = 0x00; + + + event void Boot.booted() { + + printfUART_init(); + + printfUART("i_am_pan: %i\n", TYPE_DEVICE); + + DestinationMote[0]=0x00000000; + DestinationMote[1]=0x00000002; + + if (TYPE_DEVICE == COORDINATOR) + { + my_short_address = 0x0000; + call Timer0.startOneShot(4000); + } + else + { + call Timer0.startOneShot(4000); + } + + } + + + event void Timer0.fired() { + + uint8_t v_temp[2]; + + + if (TYPE_DEVICE == END_DEVICE) + { + + my_short_address = TOS_NODE_ID; + + //set the MAC short address variable + v_temp[0] = (uint8_t)(my_short_address >> 8); + v_temp[1] = (uint8_t)(my_short_address ); + + call MLME_SET.request(MACSHORTADDRESS,v_temp); + + //set the MAC PANID variable + v_temp[0] = (uint8_t)(MAC_PANID >> 8); + v_temp[1] = (uint8_t)(MAC_PANID ); + + call MLME_SET.request(MACPANID,v_temp); + + call Timer_Send.startPeriodic(3000); + + } + else + { + //set the MAC short address variable + v_temp[0] = (uint8_t)(my_short_address >> 8); + v_temp[1] = (uint8_t)(my_short_address ); + + call MLME_SET.request(MACSHORTADDRESS,v_temp); + + //set the MAC PANID variable + v_temp[0] = (uint8_t)(MAC_PANID >> 8); + v_temp[1] = (uint8_t)(MAC_PANID ); + + call MLME_SET.request(MACPANID,v_temp); + + //start sending beacons + call MLME_START.request(MAC_PANID, LOGICAL_CHANNEL, BEACON_ORDER, SUPERFRAME_ORDER,1,0,0,0,0); + + //call Timer_send.start(TIMER_REPEAT,8000); + } + + } + +event void Timer_Send.fired() { + + + uint8_t msdu_payload[4]; + + DestinationMote[0]=0x00000000; + DestinationMote[1]=0x00000000; + + //NKL destination address, coordinator will route packet to this address + msdu_payload[0] = 0x00; + msdu_payload[1] = 0x03; + + SourceMoteAddr[0]=0x00000000; + SourceMoteAddr[1]=TOS_NODE_ID; + + if (TOS_NODE_ID == 0x02) + { + call Leds.led2Toggle(); //set_txoptions(ack, gts, indirect_transmission, security) + call MCPS_DATA.request(SHORT_ADDRESS, MAC_PANID, SourceMoteAddr, SHORT_ADDRESS, MAC_PANID, DestinationMote, 2, msdu_payload,1,set_txoptions(1,0,0,0)); + } + + + } + +/*****************************************************************************************************/ +/**************************************MLME-SCAN*******************************************************/ +/*****************************************************************************************************/ +event error_t MLME_SCAN.confirm(uint8_t status,uint8_t ScanType, uint32_t UnscannedChannels, uint8_t ResultListSize, uint8_t EnergyDetectList[], SCAN_PANDescriptor PANDescriptorList[]) +{ + + return SUCCESS; +} + +/*****************************************************************************************************/ +/**************************************MLME-ORPHAN****************************************************/ +/*****************************************************************************************************/ +event error_t MLME_ORPHAN.indication(uint32_t OrphanAddress[1], uint8_t SecurityUse, uint8_t ACLEntry) +{ + + return SUCCESS; +} +/*****************************************************************************************************/ +/**************************************MLME-RESET*****************************************************/ +/*****************************************************************************************************/ +event error_t MLME_RESET.confirm(uint8_t status) +{ + + + + return SUCCESS; +} +/*****************************************************************************************************/ +/**************************************MLME-SYNC-LOSS*************************************************/ +/*****************************************************************************************************/ +event error_t MLME_SYNC_LOSS.indication(uint8_t LossReason) +{ + + return SUCCESS; +} + +/*****************************************************************************************************/ +/**************************************MLME-GTS*******************************************************/ +/*****************************************************************************************************/ +event error_t MLME_GTS.confirm(uint8_t GTSCharacteristics, uint8_t status) +{ + + return SUCCESS; +} + +event error_t MLME_GTS.indication(uint16_t DevAddress, uint8_t GTSCharacteristics, bool SecurityUse, uint8_t ACLEntry) +{ + return SUCCESS; +} +/*****************************************************************************************************/ +/**************************************MLME-BEACON NOTIFY*********************************************/ +/*****************************************************************************************************/ +event error_t MLME_BEACON_NOTIFY.indication(uint8_t BSN,PANDescriptor pan_descriptor, uint8_t PenAddrSpec, uint8_t AddrList, uint8_t sduLength, uint8_t sdu[]) +{ + + return SUCCESS; +} +/*****************************************************************************************************/ +/**************************************MLME-START*****************************************************/ +/*****************************************************************************************************/ +event error_t MLME_START.confirm(uint8_t status) +{ + + +return SUCCESS; +} + /*****************************************************************************************************/ +/********************** MLME-SET ******************************************/ +/*****************************************************************************************************/ + +event error_t MLME_SET.confirm(uint8_t status,uint8_t PIBAttribute) +{ + + +return SUCCESS; +} +/*****************************************************************************************************/ +/************************* MLME-GET ******************************************/ +/*****************************************************************************************************/ +event error_t MLME_GET.confirm(uint8_t status,uint8_t PIBAttribute, uint8_t PIBAttributeValue[]) +{ + + +return SUCCESS; +} + + +/*****************************************************************************************************/ +/**************************************MLME-ASSOCIATE*************************************************/ +/*****************************************************************************************************/ +event error_t MLME_ASSOCIATE.indication(uint32_t DeviceAddress[], uint8_t CapabilityInformation, bool SecurityUse, uint8_t ACLEntry) +{ + + return SUCCESS; +} + +event error_t MLME_ASSOCIATE.confirm(uint16_t AssocShortAddress, uint8_t status) +{ + + return SUCCESS; +} + /*****************************************************************************************************/ +/**************************************MLME-DISASSOCIATE**********************************************/ +/*****************************************************************************************************/ +event error_t MLME_DISASSOCIATE.indication(uint32_t DeviceAddress[], uint8_t DisassociateReason, bool SecurityUse, uint8_t ACLEntry) +{ + return SUCCESS; +} + +event error_t MLME_DISASSOCIATE.confirm(uint8_t status) +{ + return SUCCESS; +} + /*****************************************************************************************************/ +/*****************************************************************************************************/ +/**************** MCPS EVENTS *************************************/ +/*****************************************************************************************************/ +/*****************************************************************************************************/ + + +/*****************************************************************************************************/ +/********************* MCPS-DATA ***************************************/ +/*****************************************************************************************************/ +event error_t MCPS_DATA.confirm(uint8_t msduHandle, uint8_t status) +{ + +return SUCCESS; +} +event error_t MCPS_DATA.indication(uint16_t SrcAddrMode, uint16_t SrcPANId, uint32_t SrcAddr[2], uint16_t DstAddrMode, uint16_t DestPANId, uint32_t DstAddr[2], uint16_t msduLength,uint8_t msdu[100],uint16_t mpduLinkQuality, uint16_t SecurityUse, uint16_t ACLEntry) +{ + +//routing procedure, the short address of the destination device is the first 2 bytes of the data payload + if (TYPE_DEVICE == COORDINATOR) + { + + //route to the desired address + DestinationMote[0]=0x00000000; + DestinationMote[1]=(uint32_t) msdu[1]; + + routed_packets++; + msdu[0] = routed_packets; + //set_txoptions(ack, gts, indirect_transmission, security) + call MCPS_DATA.request(SHORT_ADDRESS, MAC_PANID, SrcAddr, SHORT_ADDRESS, MAC_PANID, DestinationMote, 1, msdu,1,set_txoptions(1,0,0,0)); + } + else + { + + call Leds.led1Toggle(); + + } + + + +return SUCCESS; +} + + +} + diff --git a/tos/lib/net/zigbee/apps/SimpleRoutingExample/simpleroutingexample.h b/tos/lib/net/zigbee/apps/SimpleRoutingExample/simpleroutingexample.h new file mode 100644 index 00000000..30d9e101 --- /dev/null +++ b/tos/lib/net/zigbee/apps/SimpleRoutingExample/simpleroutingexample.h @@ -0,0 +1,19 @@ +enum { + COORDINATOR = 0x00, + ROUTER =0x01, + END_DEVICE = 0x02 + }; + +#define BEACON_ORDER 6 +#define SUPERFRAME_ORDER 4 +//the starting channel needs to be diferrent that the existent coordinator operating channels +#define LOGICAL_CHANNEL 0x15 + + +#define TYPE_DEVICE END_DEVICE +//#define TYPE_DEVICE COORDINATOR + +//PAN VARIABLES +#define MAC_PANID 0x1234 + + diff --git a/tos/lib/net/zigbee/apps/Test_APL/Makefile b/tos/lib/net/zigbee/apps/Test_APL/Makefile new file mode 100644 index 00000000..04386a64 --- /dev/null +++ b/tos/lib/net/zigbee/apps/Test_APL/Makefile @@ -0,0 +1,15 @@ +COMPONENT=Test_APL + +PFLAGS += -I$(TOSROOT)/tos/lib/net/zigbee/ieee802154/includes \ + -I$(TOSROOT)/tos/lib/net/zigbee/ieee802154/macTDBS \ + -I$(TOSROOT)/tos/lib/net/zigbee/ieee802154/phy \ + -I$(TOSROOT)/tos/lib/net/zigbee/ieee802154/timerasyncTDBS \ + -I$(TOSROOT)/tos/lib/net/zigbee/ieee802154/interfaces \ + -I$(TOSROOT)/tos/lib/net/zigbee/ieee802154/interfaces/mac \ + -I$(TOSROOT)/tos/lib/net/zigbee/ieee802154/interfaces/phy \ + -I$(TOSROOT)/tos/lib/net/zigbee/cc2420 \ + -I$(TOSROOT)/tos/lib/net/zigbee/ieee802154/interfaces/nwk \ + -I$(TOSROOT)/tos/lib/net/zigbee/ieee802154/nwk + +include $(MAKERULES) + diff --git a/tos/lib/net/zigbee/apps/Test_APL/Test_APL.nc b/tos/lib/net/zigbee/apps/Test_APL/Test_APL.nc new file mode 100644 index 00000000..3ea6d59a --- /dev/null +++ b/tos/lib/net/zigbee/apps/Test_APL/Test_APL.nc @@ -0,0 +1,68 @@ +/* + * @author IPP HURRAY http://www.hurray.isep.ipp.pt/art-wise + * @author Andre Cunha + * + */ +#include + +#include "phy_const.h" +#include "phy_enumerations.h" +#include "mac_const.h" +#include "mac_enumerations.h" +#include "mac_func.h" + +#include "nwk_const.h" +#include "nwk_enumerations.h" +#include "nwk_func.h" +#include "UserButton.h" + +configuration Test_APL { +} +implementation { + + components MainC; + components LedsC; + components Test_APLM; + + Test_APLM.Boot -> MainC; + + components NWK; + + Test_APLM.Leds -> LedsC; + + + components new TimerMilliC() as T_init; + Test_APLM.T_init -> T_init; + + components new TimerMilliC() as T_test; + Test_APLM.T_test -> T_test; + + components new TimerMilliC() as T_schedule; + Test_APLM.T_schedule -> T_schedule; + + + //User Button + components UserButtonC; + + Test_APLM.Get -> UserButtonC; + Test_APLM.Notify -> UserButtonC; + + + Test_APLM.NLDE_DATA ->NWK.NLDE_DATA; + + Test_APLM.NLME_NETWORK_DISCOVERY -> NWK.NLME_NETWORK_DISCOVERY; + Test_APLM.NLME_NETWORK_FORMATION -> NWK.NLME_NETWORK_FORMATION; + /*Test_APLM.NLME_PERMIT_JOINING-> NWK_control.NLME_PERMIT_JOINING; + */ + Test_APLM.NLME_START_ROUTER -> NWK.NLME_START_ROUTER; + Test_APLM.NLME_JOIN -> NWK.NLME_JOIN; + /*Test_APLM.NLME_DIRECT_JOIN -> NWK_control.NLME_DIRECT_JOIN; + */ + Test_APLM.NLME_LEAVE -> NWK.NLME_LEAVE; + /*Test_APLM.NLME_RESET -> NWK_control.NLME_RESET; + */ + Test_APLM.NLME_SYNC -> NWK.NLME_SYNC; + Test_APLM.NLME_GET -> NWK.NLME_GET; + Test_APLM.NLME_SET -> NWK.NLME_SET; +} + diff --git a/tos/lib/net/zigbee/apps/Test_APL/Test_APLM.nc b/tos/lib/net/zigbee/apps/Test_APL/Test_APLM.nc new file mode 100644 index 00000000..7e58da6d --- /dev/null +++ b/tos/lib/net/zigbee/apps/Test_APL/Test_APLM.nc @@ -0,0 +1,873 @@ +/* + * @author IPP HURRAY http://www.hurray.isep.ipp.pt/art-wise + * @author Andre Cunha + * + */ +#include +#include "printfUART.h" + +module Test_APLM { + + uses interface Boot; + uses interface Leds; + + uses interface NLDE_DATA; +//NLME NWK Management services + uses interface NLME_NETWORK_DISCOVERY; + uses interface NLME_NETWORK_FORMATION; + uses interface NLME_START_ROUTER; + uses interface NLME_JOIN; + uses interface NLME_LEAVE; + uses interface NLME_SYNC; + + /* + uses interface NLME_PERMIT_JOINING; + uses interface NLME_DIRECT_JOIN; + uses interface NLME_RESET; + */ + + uses interface NLME_GET; + uses interface NLME_SET; + + uses interface Timer as T_init; + + uses interface Timer as T_test; + + uses interface Timer as T_schedule; + +//user button + uses interface Get; + uses interface Notify; + +} +implementation { + + //descriptor of the Parent device + networkdescriptor PAN_network; + //boolean variable definig if the device has joined to the PAN + uint8_t joined =0x00; + //boolean variable defining if the device is waiting for the beacon request response + uint8_t requested_scheduling = 0x00; + //function used to start the beacon broadcast (router devices) + task void start_sending_beacons_request(); + //function used to schedule the beacon requests (PAN coordinator) + void process_beacon_scheduling(uint16_t source_address,uint8_t beacon_order, uint8_t superframe_order); + + void process_beacon_scheduling(uint16_t source_address,uint8_t beacon_order, uint8_t superframe_order) + { + + uint8_t nsdu_pay[6]; + + beacon_scheduling *beacon_scheduling_ptr; + + beacon_scheduling_ptr = (beacon_scheduling *)&nsdu_pay[0]; + + switch(source_address) + { + + /*****************************************************************************/ + /*DEPTH + mwkMaxChildren (Cm) 6 + nwkMaxDepth (Lm) 4 + mwkMaxRouters (Rm) 4 + */ + /* + case 0x0001: + beacon_scheduling_ptr->request_type = SCHEDULING_ACCEPT; + beacon_scheduling_ptr->beacon_order = beacon_order; + beacon_scheduling_ptr->superframe_order = superframe_order; + beacon_scheduling_ptr->transmission_offset[0] = 0x00; + beacon_scheduling_ptr->transmission_offset[1] = 0x3C; + beacon_scheduling_ptr->transmission_offset[2] = 0x00; + break; + case 0x0002: + beacon_scheduling_ptr->request_type = SCHEDULING_ACCEPT; + beacon_scheduling_ptr->beacon_order = beacon_order; + beacon_scheduling_ptr->superframe_order = superframe_order; + beacon_scheduling_ptr->transmission_offset[0] = 0x00; + beacon_scheduling_ptr->transmission_offset[1] = 0x3C; + beacon_scheduling_ptr->transmission_offset[2] = 0x00; + break; + case 0x0021: + beacon_scheduling_ptr->request_type = SCHEDULING_ACCEPT; + beacon_scheduling_ptr->beacon_order = beacon_order; + beacon_scheduling_ptr->superframe_order = superframe_order; + beacon_scheduling_ptr->transmission_offset[0] = 0x01; + beacon_scheduling_ptr->transmission_offset[1] = 0x2C; + beacon_scheduling_ptr->transmission_offset[2] = 0x00; + break; + case 0x0003: + beacon_scheduling_ptr->request_type = SCHEDULING_ACCEPT; + beacon_scheduling_ptr->beacon_order = beacon_order; + beacon_scheduling_ptr->superframe_order = superframe_order; + beacon_scheduling_ptr->transmission_offset[0] = 0x00; + beacon_scheduling_ptr->transmission_offset[1] = 0x3C; + beacon_scheduling_ptr->transmission_offset[2] = 0x00; + break; + case 0x0022: + beacon_scheduling_ptr->request_type = SCHEDULING_ACCEPT; + beacon_scheduling_ptr->beacon_order = beacon_order; + beacon_scheduling_ptr->superframe_order = superframe_order; + beacon_scheduling_ptr->transmission_offset[0] = 0x00; + beacon_scheduling_ptr->transmission_offset[1] = 0x3C; + beacon_scheduling_ptr->transmission_offset[2] = 0x00; + break; + case 0x0004: + beacon_scheduling_ptr->request_type = SCHEDULING_ACCEPT; + beacon_scheduling_ptr->beacon_order = beacon_order; + beacon_scheduling_ptr->superframe_order = superframe_order; + beacon_scheduling_ptr->transmission_offset[0] = 0x00; + beacon_scheduling_ptr->transmission_offset[1] = 0x3C; + beacon_scheduling_ptr->transmission_offset[2] = 0x00; + break; + case 0x0005: + beacon_scheduling_ptr->request_type = SCHEDULING_ACCEPT; + beacon_scheduling_ptr->beacon_order = beacon_order; + beacon_scheduling_ptr->superframe_order = superframe_order; + beacon_scheduling_ptr->transmission_offset[0] = 0x00; + beacon_scheduling_ptr->transmission_offset[1] = 0x78; + beacon_scheduling_ptr->transmission_offset[2] = 0x00; + break; + + case 0x0023: + beacon_scheduling_ptr->request_type = SCHEDULING_ACCEPT; + beacon_scheduling_ptr->beacon_order = beacon_order; + beacon_scheduling_ptr->superframe_order = superframe_order; + beacon_scheduling_ptr->transmission_offset[0] = 0x00; + beacon_scheduling_ptr->transmission_offset[1] = 0x3C; + beacon_scheduling_ptr->transmission_offset[2] = 0x00; + break; + + case 0x0024: + beacon_scheduling_ptr->request_type = SCHEDULING_ACCEPT; + beacon_scheduling_ptr->beacon_order = beacon_order; + beacon_scheduling_ptr->superframe_order = superframe_order; + beacon_scheduling_ptr->transmission_offset[0] = 0x00; + beacon_scheduling_ptr->transmission_offset[1] = 0x78; + beacon_scheduling_ptr->transmission_offset[2] = 0x00; + break; + */ + /*****************************************************************************/ + /*NORMAL TEST + mwkMaxChildren (Cm) 6 + nwkMaxDepth (Lm) 3 + mwkMaxRouters (Rm) 4 +*/ + case 0x0001: + beacon_scheduling_ptr->request_type = SCHEDULING_ACCEPT; + beacon_scheduling_ptr->beacon_order = beacon_order; + beacon_scheduling_ptr->superframe_order = superframe_order; + beacon_scheduling_ptr->transmission_offset[0] = 0x00; + beacon_scheduling_ptr->transmission_offset[1] = 0x3C; + beacon_scheduling_ptr->transmission_offset[2] = 0x00; + break; + case 0x0020: + beacon_scheduling_ptr->request_type = SCHEDULING_ACCEPT; + beacon_scheduling_ptr->beacon_order = beacon_order; + beacon_scheduling_ptr->superframe_order = superframe_order; + beacon_scheduling_ptr->transmission_offset[0] = 0x01; + beacon_scheduling_ptr->transmission_offset[1] = 0xE0; + beacon_scheduling_ptr->transmission_offset[2] = 0x00; + break; + case 0x0002: + beacon_scheduling_ptr->request_type = SCHEDULING_ACCEPT; + beacon_scheduling_ptr->beacon_order = beacon_order; + beacon_scheduling_ptr->superframe_order = superframe_order; + beacon_scheduling_ptr->transmission_offset[0] = 0x00; + beacon_scheduling_ptr->transmission_offset[1] = 0x3C; + beacon_scheduling_ptr->transmission_offset[2] = 0x00; + break; + case 0x0009: + beacon_scheduling_ptr->request_type = SCHEDULING_ACCEPT; + beacon_scheduling_ptr->beacon_order = beacon_order; + beacon_scheduling_ptr->superframe_order = superframe_order; + beacon_scheduling_ptr->transmission_offset[0] = 0x00; + beacon_scheduling_ptr->transmission_offset[1] = 0xF0; + beacon_scheduling_ptr->transmission_offset[2] = 0x00; + break; + case 0x0021: + beacon_scheduling_ptr->request_type = SCHEDULING_ACCEPT; + beacon_scheduling_ptr->beacon_order = beacon_order; + beacon_scheduling_ptr->superframe_order = superframe_order; + beacon_scheduling_ptr->transmission_offset[0] = 0x00; + beacon_scheduling_ptr->transmission_offset[1] = 0x3C; + beacon_scheduling_ptr->transmission_offset[2] = 0x00; + break; + case 0x0028: + beacon_scheduling_ptr->request_type = SCHEDULING_ACCEPT; + beacon_scheduling_ptr->beacon_order = beacon_order; + beacon_scheduling_ptr->superframe_order = superframe_order; + beacon_scheduling_ptr->transmission_offset[0] = 0x00; + beacon_scheduling_ptr->transmission_offset[1] = 0xF0; + beacon_scheduling_ptr->transmission_offset[2] = 0x00; + break; + case 0x0003: + beacon_scheduling_ptr->request_type = SCHEDULING_ACCEPT; + beacon_scheduling_ptr->beacon_order = beacon_order; + beacon_scheduling_ptr->superframe_order = superframe_order; + beacon_scheduling_ptr->transmission_offset[0] = 0x00; + beacon_scheduling_ptr->transmission_offset[1] = 0x3C; + beacon_scheduling_ptr->transmission_offset[2] = 0x00; + break; + case 0x0004: + beacon_scheduling_ptr->request_type = SCHEDULING_ACCEPT; + beacon_scheduling_ptr->beacon_order = beacon_order; + beacon_scheduling_ptr->superframe_order = superframe_order; + beacon_scheduling_ptr->transmission_offset[0] = 0x00; + beacon_scheduling_ptr->transmission_offset[1] = 0x78; + beacon_scheduling_ptr->transmission_offset[2] = 0x00; + break; + case 0x000a: + beacon_scheduling_ptr->request_type = SCHEDULING_ACCEPT; + beacon_scheduling_ptr->beacon_order = beacon_order; + beacon_scheduling_ptr->superframe_order = superframe_order; + beacon_scheduling_ptr->transmission_offset[0] = 0x00; + beacon_scheduling_ptr->transmission_offset[1] = 0x3C; + beacon_scheduling_ptr->transmission_offset[2] = 0x00; + break; + case 0x000b: + beacon_scheduling_ptr->request_type = SCHEDULING_ACCEPT; + beacon_scheduling_ptr->beacon_order = beacon_order; + beacon_scheduling_ptr->superframe_order = superframe_order; + beacon_scheduling_ptr->transmission_offset[0] = 0x00; + beacon_scheduling_ptr->transmission_offset[1] = 0x78; + beacon_scheduling_ptr->transmission_offset[2] = 0x00; + break; + case 0x0022: + beacon_scheduling_ptr->request_type = SCHEDULING_ACCEPT; + beacon_scheduling_ptr->beacon_order = beacon_order; + beacon_scheduling_ptr->superframe_order = superframe_order; + beacon_scheduling_ptr->transmission_offset[0] = 0x00; + beacon_scheduling_ptr->transmission_offset[1] = 0x3C; + beacon_scheduling_ptr->transmission_offset[2] = 0x00; + break; + case 0x0023: + beacon_scheduling_ptr->request_type = SCHEDULING_ACCEPT; + beacon_scheduling_ptr->beacon_order = beacon_order; + beacon_scheduling_ptr->superframe_order = superframe_order; + beacon_scheduling_ptr->transmission_offset[0] = 0x00; + beacon_scheduling_ptr->transmission_offset[1] = 0x78; + beacon_scheduling_ptr->transmission_offset[2] = 0x00; + break; + case 0x0029: + beacon_scheduling_ptr->request_type = SCHEDULING_ACCEPT; + beacon_scheduling_ptr->beacon_order = beacon_order; + beacon_scheduling_ptr->superframe_order = superframe_order; + beacon_scheduling_ptr->transmission_offset[0] = 0x00; + beacon_scheduling_ptr->transmission_offset[1] = 0x3C; + beacon_scheduling_ptr->transmission_offset[2] = 0x00; + break; + case 0x002a: + beacon_scheduling_ptr->request_type = SCHEDULING_ACCEPT; + beacon_scheduling_ptr->beacon_order = beacon_order; + beacon_scheduling_ptr->superframe_order = superframe_order; + beacon_scheduling_ptr->transmission_offset[0] = 0x00; + beacon_scheduling_ptr->transmission_offset[1] = 0x78; + beacon_scheduling_ptr->transmission_offset[2] = 0x00; + break; + + /*******************************************************************/ + /* + case 0x0001: + beacon_scheduling_ptr->request_type = SCHEDULING_ACCEPT; + beacon_scheduling_ptr->beacon_order = beacon_order; + beacon_scheduling_ptr->superframe_order = superframe_order; + beacon_scheduling_ptr->transmission_offset[0] = 0x00; + beacon_scheduling_ptr->transmission_offset[1] = 0x3C; + beacon_scheduling_ptr->transmission_offset[2] = 0x00; + break; + case 0x0002: + beacon_scheduling_ptr->request_type = SCHEDULING_ACCEPT; + beacon_scheduling_ptr->beacon_order = beacon_order; + beacon_scheduling_ptr->superframe_order = superframe_order; + beacon_scheduling_ptr->transmission_offset[0] = 0x00; + beacon_scheduling_ptr->transmission_offset[1] = 0x3C; + beacon_scheduling_ptr->transmission_offset[2] = 0x00; + break; + case 0x0009: + beacon_scheduling_ptr->request_type = SCHEDULING_ACCEPT; + beacon_scheduling_ptr->beacon_order = beacon_order; + beacon_scheduling_ptr->superframe_order = superframe_order; + beacon_scheduling_ptr->transmission_offset[0] = 0x00; + beacon_scheduling_ptr->transmission_offset[1] = 0x78; + beacon_scheduling_ptr->transmission_offset[2] = 0x00; + break; + + + case 0x0020: + beacon_scheduling_ptr->request_type = SCHEDULING_ACCEPT; + beacon_scheduling_ptr->beacon_order = beacon_order; + beacon_scheduling_ptr->superframe_order = superframe_order; + beacon_scheduling_ptr->transmission_offset[0] = 0x00; + beacon_scheduling_ptr->transmission_offset[1] = 0xF0; + beacon_scheduling_ptr->transmission_offset[2] = 0x00; + break; + case 0x0021: + beacon_scheduling_ptr->request_type = SCHEDULING_ACCEPT; + beacon_scheduling_ptr->beacon_order = beacon_order; + beacon_scheduling_ptr->superframe_order = superframe_order; + beacon_scheduling_ptr->transmission_offset[0] = 0x00; + beacon_scheduling_ptr->transmission_offset[1] = 0x3C; + beacon_scheduling_ptr->transmission_offset[2] = 0x00; + break; + case 0x0028: + beacon_scheduling_ptr->request_type = SCHEDULING_ACCEPT; + beacon_scheduling_ptr->beacon_order = beacon_order; + beacon_scheduling_ptr->superframe_order = superframe_order; + beacon_scheduling_ptr->transmission_offset[0] = 0x00; + beacon_scheduling_ptr->transmission_offset[1] = 0x78; + beacon_scheduling_ptr->transmission_offset[2] = 0x00; + break; + + case 0x003F: + beacon_scheduling_ptr->request_type = SCHEDULING_ACCEPT; + beacon_scheduling_ptr->beacon_order = beacon_order; + beacon_scheduling_ptr->superframe_order = superframe_order; + beacon_scheduling_ptr->transmission_offset[0] = 0x01; + beacon_scheduling_ptr->transmission_offset[1] = 0xE0; + beacon_scheduling_ptr->transmission_offset[2] = 0x00; + break; + case 0x0040: + beacon_scheduling_ptr->request_type = SCHEDULING_ACCEPT; + beacon_scheduling_ptr->beacon_order = beacon_order; + beacon_scheduling_ptr->superframe_order = superframe_order; + beacon_scheduling_ptr->transmission_offset[0] = 0x00; + beacon_scheduling_ptr->transmission_offset[1] = 0x3C; + beacon_scheduling_ptr->transmission_offset[2] = 0x00; + break; + case 0x0047: + beacon_scheduling_ptr->request_type = SCHEDULING_ACCEPT; + beacon_scheduling_ptr->beacon_order = beacon_order; + beacon_scheduling_ptr->superframe_order = superframe_order; + beacon_scheduling_ptr->transmission_offset[0] = 0x00; + beacon_scheduling_ptr->transmission_offset[1] = 0x78; + beacon_scheduling_ptr->transmission_offset[2] = 0x00; + break; + + case 0x005e: + beacon_scheduling_ptr->request_type = SCHEDULING_ACCEPT; + beacon_scheduling_ptr->beacon_order = beacon_order; + beacon_scheduling_ptr->superframe_order = superframe_order; + beacon_scheduling_ptr->transmission_offset[0] = 0x02; + beacon_scheduling_ptr->transmission_offset[1] = 0xDC; + beacon_scheduling_ptr->transmission_offset[2] = 0x00; + break; + case 0x005f: + beacon_scheduling_ptr->request_type = SCHEDULING_ACCEPT; + beacon_scheduling_ptr->beacon_order = beacon_order; + beacon_scheduling_ptr->superframe_order = superframe_order; + beacon_scheduling_ptr->transmission_offset[0] = 0x00; + beacon_scheduling_ptr->transmission_offset[1] = 0x3C; + beacon_scheduling_ptr->transmission_offset[2] = 0x00; + break; + case 0x0066: + beacon_scheduling_ptr->request_type = SCHEDULING_ACCEPT; + beacon_scheduling_ptr->beacon_order = beacon_order; + beacon_scheduling_ptr->superframe_order = superframe_order; + beacon_scheduling_ptr->transmission_offset[0] = 0x00; + beacon_scheduling_ptr->transmission_offset[1] = 0x78; + beacon_scheduling_ptr->transmission_offset[2] = 0x00; + break; + */ + /*******************************************************************/ + /* + case 0x0001: + beacon_scheduling_ptr->request_type = SCHEDULING_ACCEPT; + beacon_scheduling_ptr->beacon_order = beacon_order; + beacon_scheduling_ptr->superframe_order = superframe_order; + beacon_scheduling_ptr->transmission_offset[0] = 0x00; + beacon_scheduling_ptr->transmission_offset[1] = 0x3C; + beacon_scheduling_ptr->transmission_offset[2] = 0x00; + break; + case 0x0002: + beacon_scheduling_ptr->request_type = SCHEDULING_ACCEPT; + beacon_scheduling_ptr->beacon_order = beacon_order; + beacon_scheduling_ptr->superframe_order = superframe_order; + beacon_scheduling_ptr->transmission_offset[0] = 0x00; + beacon_scheduling_ptr->transmission_offset[1] = 0x3C; + beacon_scheduling_ptr->transmission_offset[2] = 0x00; + break; + case 0x0009: + beacon_scheduling_ptr->request_type = SCHEDULING_ACCEPT; + beacon_scheduling_ptr->beacon_order = beacon_order; + beacon_scheduling_ptr->superframe_order = superframe_order; + beacon_scheduling_ptr->transmission_offset[0] = 0x00; + beacon_scheduling_ptr->transmission_offset[1] = 0x78; + beacon_scheduling_ptr->transmission_offset[2] = 0x00; + break; + case 0x00010: + beacon_scheduling_ptr->request_type = SCHEDULING_ACCEPT; + beacon_scheduling_ptr->beacon_order = beacon_order; + beacon_scheduling_ptr->superframe_order = superframe_order; + beacon_scheduling_ptr->transmission_offset[0] = 0x00; + beacon_scheduling_ptr->transmission_offset[1] = 0xB4; + beacon_scheduling_ptr->transmission_offset[2] = 0x00; + break; + case 0x0017: + beacon_scheduling_ptr->request_type = SCHEDULING_ACCEPT; + beacon_scheduling_ptr->beacon_order = beacon_order; + beacon_scheduling_ptr->superframe_order = superframe_order; + beacon_scheduling_ptr->transmission_offset[0] = 0x00; + beacon_scheduling_ptr->transmission_offset[1] = 0xF0; + beacon_scheduling_ptr->transmission_offset[2] = 0x00; + break; + + + case 0x0020: + beacon_scheduling_ptr->request_type = SCHEDULING_ACCEPT; + beacon_scheduling_ptr->beacon_order = beacon_order; + beacon_scheduling_ptr->superframe_order = superframe_order; + beacon_scheduling_ptr->transmission_offset[0] = 0x01; + beacon_scheduling_ptr->transmission_offset[1] = 0x68; + beacon_scheduling_ptr->transmission_offset[2] = 0x00; + break; + case 0x0021: + beacon_scheduling_ptr->request_type = SCHEDULING_ACCEPT; + beacon_scheduling_ptr->beacon_order = beacon_order; + beacon_scheduling_ptr->superframe_order = superframe_order; + beacon_scheduling_ptr->transmission_offset[0] = 0x00; + beacon_scheduling_ptr->transmission_offset[1] = 0x3C; + beacon_scheduling_ptr->transmission_offset[2] = 0x00; + break; + case 0x0028: + beacon_scheduling_ptr->request_type = SCHEDULING_ACCEPT; + beacon_scheduling_ptr->beacon_order = beacon_order; + beacon_scheduling_ptr->superframe_order = superframe_order; + beacon_scheduling_ptr->transmission_offset[0] = 0x00; + beacon_scheduling_ptr->transmission_offset[1] = 0x78; + beacon_scheduling_ptr->transmission_offset[2] = 0x00; + break; + case 0x0002F: + beacon_scheduling_ptr->request_type = SCHEDULING_ACCEPT; + beacon_scheduling_ptr->beacon_order = beacon_order; + beacon_scheduling_ptr->superframe_order = superframe_order; + beacon_scheduling_ptr->transmission_offset[0] = 0x00; + beacon_scheduling_ptr->transmission_offset[1] = 0xB4; + beacon_scheduling_ptr->transmission_offset[2] = 0x00; + break; + case 0x0036: + beacon_scheduling_ptr->request_type = SCHEDULING_ACCEPT; + beacon_scheduling_ptr->beacon_order = beacon_order; + beacon_scheduling_ptr->superframe_order = superframe_order; + beacon_scheduling_ptr->transmission_offset[0] = 0x00; + beacon_scheduling_ptr->transmission_offset[1] = 0xF0; + beacon_scheduling_ptr->transmission_offset[2] = 0x00; + break; + + + case 0x003F: + beacon_scheduling_ptr->request_type = SCHEDULING_ACCEPT; + beacon_scheduling_ptr->beacon_order = beacon_order; + beacon_scheduling_ptr->superframe_order = superframe_order; + beacon_scheduling_ptr->transmission_offset[0] = 0x02; + beacon_scheduling_ptr->transmission_offset[1] = 0xD0; + beacon_scheduling_ptr->transmission_offset[2] = 0x00; + break; + case 0x0040: + beacon_scheduling_ptr->request_type = SCHEDULING_ACCEPT; + beacon_scheduling_ptr->beacon_order = beacon_order; + beacon_scheduling_ptr->superframe_order = superframe_order; + beacon_scheduling_ptr->transmission_offset[0] = 0x00; + beacon_scheduling_ptr->transmission_offset[1] = 0x3C; + beacon_scheduling_ptr->transmission_offset[2] = 0x00; + break; + case 0x0047: + beacon_scheduling_ptr->request_type = SCHEDULING_ACCEPT; + beacon_scheduling_ptr->beacon_order = beacon_order; + beacon_scheduling_ptr->superframe_order = superframe_order; + beacon_scheduling_ptr->transmission_offset[0] = 0x00; + beacon_scheduling_ptr->transmission_offset[1] = 0x78; + beacon_scheduling_ptr->transmission_offset[2] = 0x00; + break; + case 0x0004E: + beacon_scheduling_ptr->request_type = SCHEDULING_ACCEPT; + beacon_scheduling_ptr->beacon_order = beacon_order; + beacon_scheduling_ptr->superframe_order = superframe_order; + beacon_scheduling_ptr->transmission_offset[0] = 0x00; + beacon_scheduling_ptr->transmission_offset[1] = 0xB4; + beacon_scheduling_ptr->transmission_offset[2] = 0x00; + break; + case 0x0055: + beacon_scheduling_ptr->request_type = SCHEDULING_ACCEPT; + beacon_scheduling_ptr->beacon_order = beacon_order; + beacon_scheduling_ptr->superframe_order = superframe_order; + beacon_scheduling_ptr->transmission_offset[0] = 0x00; + beacon_scheduling_ptr->transmission_offset[1] = 0xF0; + beacon_scheduling_ptr->transmission_offset[2] = 0x00; + break; + + + + case 0x005e: + beacon_scheduling_ptr->request_type = SCHEDULING_ACCEPT; + beacon_scheduling_ptr->beacon_order = beacon_order; + beacon_scheduling_ptr->superframe_order = superframe_order; + beacon_scheduling_ptr->transmission_offset[0] = 0x04; + beacon_scheduling_ptr->transmission_offset[1] = 0x38; + beacon_scheduling_ptr->transmission_offset[2] = 0x00; + break; + case 0x005F: + beacon_scheduling_ptr->request_type = SCHEDULING_ACCEPT; + beacon_scheduling_ptr->beacon_order = beacon_order; + beacon_scheduling_ptr->superframe_order = superframe_order; + beacon_scheduling_ptr->transmission_offset[0] = 0x00; + beacon_scheduling_ptr->transmission_offset[1] = 0x3C; + beacon_scheduling_ptr->transmission_offset[2] = 0x00; + break; + case 0x0066: + beacon_scheduling_ptr->request_type = SCHEDULING_ACCEPT; + beacon_scheduling_ptr->beacon_order = beacon_order; + beacon_scheduling_ptr->superframe_order = superframe_order; + beacon_scheduling_ptr->transmission_offset[0] = 0x00; + beacon_scheduling_ptr->transmission_offset[1] = 0x78; + beacon_scheduling_ptr->transmission_offset[2] = 0x00; + break; + case 0x0006D: + beacon_scheduling_ptr->request_type = SCHEDULING_ACCEPT; + beacon_scheduling_ptr->beacon_order = beacon_order; + beacon_scheduling_ptr->superframe_order = superframe_order; + beacon_scheduling_ptr->transmission_offset[0] = 0x00; + beacon_scheduling_ptr->transmission_offset[1] = 0xB4; + beacon_scheduling_ptr->transmission_offset[2] = 0x00; + break; + case 0x0074: + beacon_scheduling_ptr->request_type = SCHEDULING_ACCEPT; + beacon_scheduling_ptr->beacon_order = beacon_order; + beacon_scheduling_ptr->superframe_order = superframe_order; + beacon_scheduling_ptr->transmission_offset[0] = 0x00; + beacon_scheduling_ptr->transmission_offset[1] = 0xF0; + beacon_scheduling_ptr->transmission_offset[2] = 0x00; + break; + */ + default: + beacon_scheduling_ptr->request_type = SCHEDULING_DENY; + beacon_scheduling_ptr->beacon_order = beacon_order; + beacon_scheduling_ptr->superframe_order = superframe_order; + beacon_scheduling_ptr->transmission_offset[0] = 0x00; + beacon_scheduling_ptr->transmission_offset[1] = 0x00; + beacon_scheduling_ptr->transmission_offset[2] = 0x00; + break; + + } + + + call NLDE_DATA.request(source_address,0x06, nsdu_pay, 1, 1, 0x00, 0); + return; + } + + task void start_sending_beacons_request() + { + uint8_t nsdu_pay[6]; + + beacon_scheduling *beacon_scheduling_ptr; + + beacon_scheduling_ptr = (beacon_scheduling *)&nsdu_pay[0]; + + beacon_scheduling_ptr->request_type = SCHEDULING_REQUEST; + beacon_scheduling_ptr->beacon_order = BEACON_ORDER; + beacon_scheduling_ptr->superframe_order = SUPERFRAME_ORDER; + beacon_scheduling_ptr->transmission_offset[0] = 0x00; + beacon_scheduling_ptr->transmission_offset[1] = 0x00; + beacon_scheduling_ptr->transmission_offset[2] = 0x00; + + requested_scheduling = 0x01; + + //command result_t NLDE_DATA.request(uint16_t DstAddr, uint8_t NsduLength, uint8_t Nsdu[], uint8_t NsduHandle, uint8_t Radius, uint8_t DiscoverRoute, bool SecurityEnable) + call NLDE_DATA.request(0x0000,0x06, nsdu_pay, 0x01, 0x01, 0x00, 0x00); + + call T_schedule.startOneShot(20000); + //call Schedule_timer.start(TIMER_ONE_SHOT,20000); + return; + } + + + + event void Boot.booted() { + + call Notify.enable(); + + //using the telosb motes the used button enables the association to the network (routers and end devices) + //or the beacon broadcasting (PAN coordinator) + //in the MICAz motes a timer is needed to start all the above operations + + //if (TYPE_DEVICE == COORDINATOR) + // call T_init.startOneShot(12000); + + } + + +/***************************************************** +****************TIMER EVENTS*************************** +******************************************************/ + + +/*******************T_init**************************/ + event void T_init.fired() { + + //printfUART("Timer fired\n", ""); + if (TYPE_DEVICE == COORDINATOR) + { + //printfUART("coordinator procedure\n", ""); + //start forming a PAN + //command result_t request(uint32_t ScanChannels, uint8_t ScanDuration, uint8_t BeaconOrder, uint8_t SuperframeOrder, uint16_t PANId, bool BatteryLifeExtension); + call NLME_NETWORK_FORMATION.request(0x000000ff, 8, BEACON_ORDER, SUPERFRAME_ORDER, MAC_PANID,0); + + //call Leds.redOff(); + call Leds.led0Off(); + //call Test_timer.start(TIMER_REPEAT, 8000); + } + else + { + //printfUART("child procedure\n", ""); + + //call NLME_NETWORK_FORMATION.request(0x000000ff, 8, BEACON_ORDER, SUPERFRAME_ORDER, PANID,0); + + call NLME_NETWORK_DISCOVERY.request(0x000000ff, 8); + + //call Test_timer.start(TIMER_REPEAT,9000); + + } + return; + } + +/*******************T_test**************************/ + event void T_test.fired() { + + uint8_t nsdu_pay[20]; + //printfUART("Test_timer.fired\n", ""); + + nsdu_pay[0]=0x05; + nsdu_pay[1]=0x05; + nsdu_pay[2]=0x05; + nsdu_pay[3]=0x05; + nsdu_pay[4]=0x05; + nsdu_pay[5]=0x05; + nsdu_pay[6]=0x05; + + //call Leds.redToggle(); + + //command result_t NLDE_DATA.request(uint16_t DstAddr, uint8_t NsduLength, uint8_t Nsdu[], uint8_t NsduHandle, uint8_t Radius, uint8_t DiscoverRoute, bool SecurityEnable) + call NLDE_DATA.request(0x0000,0x07, nsdu_pay, 1, 1, 0x00, 0); + } + + /*******************T_schedule**************************/ + event void T_schedule.fired() { + //event that fires if the negotiation for beacon transmission is unsuccessful + //(the device does not receive any negotiation reply) + if(requested_scheduling == 0x01) + { + post start_sending_beacons_request(); + } + + } + + +/***************************************************** +****************NLDE EVENTS*************************** +******************************************************/ + +/*************************NLDE_DATA*****************************/ + +event error_t NLDE_DATA.confirm(uint8_t NsduHandle, uint8_t Status) +{ + //printfUART("NLME_DATA.confirm\n", ""); + + return SUCCESS; +} + +event error_t NLDE_DATA.indication(uint16_t SrcAddress, uint16_t NsduLength,uint8_t Nsdu[100], uint16_t LinkQuality) +{ + + uint32_t start_time=0x00000000; + uint16_t start_time1=0x0000; + uint16_t start_time2=0x0000; + + if (TYPE_DEVICE == COORDINATOR) + { + if(Nsdu[0] == SCHEDULING_REQUEST) + { + //the PAN coordinator receives a negotiation request + process_beacon_scheduling(SrcAddress,Nsdu[1],Nsdu[2]); + } + } + + if(TYPE_DEVICE==ROUTER && requested_scheduling ==0x01) + { + //the routes receives a negotiation reply + atomic requested_scheduling =0x00; + + if(Nsdu[0] == SCHEDULING_ACCEPT) + { + start_time1 =( (Nsdu[3] << 0) ) ; + start_time2 =( (Nsdu[4] << 8 ) | (Nsdu[5] << 0 ) ); + + start_time = ( ((uint32_t)start_time1 << 16) | (start_time2 << 0)); + + call NLME_START_ROUTER.request(Nsdu[1],Nsdu[2],0,start_time); + } + + } + + return SUCCESS; +} + +/***************************************************** +****************NLME EVENTS*************************** +******************************************************/ + +/*****************NLME_NETWORK_DISCOVERY**************************/ +event error_t NLME_NETWORK_DISCOVERY.confirm(uint8_t NetworkCount,networkdescriptor networkdescriptorlist[], uint8_t Status) +{ + //printfUART("NLME_NETWORK_DISCOVERY.confirm\n", ""); + + PAN_network = networkdescriptorlist[0]; + + if (TYPE_DEVICE == ROUTER) + { + //printfUART("go join router\n", ""); + call NLME_JOIN.request(networkdescriptorlist[0].PANId, 0x01, 0, 0x000000ff, 8, 0, 0, 0); + } + else + { + //printfUART("go join non router\n", ""); + call NLME_JOIN.request(networkdescriptorlist[0].PANId, 0x00, 0, 0x000000ff, 8, 0, 0, 0); + } + return SUCCESS; +} + + +/*****************NLME_NETWORK_FORMATION**********************/ + +event error_t NLME_NETWORK_FORMATION.confirm(uint8_t Status) +{ + //printfUART("NLME_NETWORK_FORMATION.confirm\n", ""); + + return SUCCESS; +} + +/*****************NLME_START_ROUTER*****************************/ +event error_t NLME_START_ROUTER.confirm(uint8_t Status) +{ + //printfUART("NLME_START_ROUTER.confirm\n", ""); + + return SUCCESS; +} + +/*************************NLME_JOIN*****************************/ + +event error_t NLME_JOIN.indication(uint16_t ShortAddress, uint32_t ExtendedAddress[], uint8_t CapabilityInformation, bool SecureJoin) +{ + //printfUART("NLME_JOIN.indication\n", ""); + + return SUCCESS; +} + +event error_t NLME_JOIN.confirm(uint16_t PANId, uint8_t Status) +{ + //printfUART("NLME_JOIN.confirm\n", ""); + + switch(Status) + { + + case NWK_SUCCESS: joined =0x01; + if (TYPE_DEVICE == ROUTER) + { + //join procedure successful + //call Leds.redOff(); + call Leds.led0Off(); + + requested_scheduling = 0x01; + + call T_schedule.startOneShot(9000); + + + //call Test_timer.start(TIMER_REPEAT, 8000); + } + else + { + //the device is an end device and starts transmitting data periodically + call T_test.startPeriodic(10000); + //call Test_timer.start(TIMER_REPEAT, 10000); + } + break; + + case NWK_NOT_PERMITTED: joined =0x00; + //join failed + break; + + default: //default procedure - join failed + joined =0x00; + break; + } + return SUCCESS; +} + + +/*************************NLME_LEAVE****************************/ + +event error_t NLME_LEAVE.indication(uint32_t DeviceAddress[]) +{ + ////printfUART("NLME_LEAVE.indication\n", ""); + return SUCCESS; +} + +event error_t NLME_LEAVE.confirm(uint32_t DeviceAddress[], uint8_t Status) +{ + //printfUART("NLME_LEAVE.confirm\n", ""); + return SUCCESS; +} + + + +/*************************NLME_SYNC*****************************/ + +event error_t NLME_SYNC.indication() +{ + //printfUART("NLME_SYNC.indication\n", ""); + return SUCCESS; +} + +event error_t NLME_SYNC.confirm(uint8_t Status) +{ + + return SUCCESS; +} + + +/*************************************************************/ +/***************** NLME-SET ********************/ +/*************************************************************/ + +event error_t NLME_SET.confirm(uint8_t Status, uint8_t NIBAttribute) +{ + +return SUCCESS; +} + +/*************************************************************/ +/***************** NLME-GET ********************/ +/*************************************************************/ + +event error_t NLME_GET.confirm(uint8_t Status, uint8_t NIBAttribute, uint16_t NIBAttributeLength, uint16_t NIBAttributeValue) +{ + + +return SUCCESS; +} + + + +event void Notify.notify( button_state_t state) +{ + if (state == BUTTON_PRESSED) { + call Leds.led0On(); + call T_init.startOneShot(5000); + + } + +} + + + +} + diff --git a/tos/lib/net/zigbee/ieee802154/includes/PrintfUART.h b/tos/lib/net/zigbee/ieee802154/includes/PrintfUART.h new file mode 100644 index 00000000..f19f13bf --- /dev/null +++ b/tos/lib/net/zigbee/ieee802154/includes/PrintfUART.h @@ -0,0 +1,336 @@ +/* + * Copyright (c) 2005 + * The President and Fellows of Harvard College. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE UNIVERSITY AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE UNIVERSITY OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +/* + * Writes printf like output to the UART. + * This works only on the AVR and MSP430 Microcontrollers! + *

+ * Note: For AVR we explicitly place the print statements in ROM; for + * MSP430 this is done by default! For AVR, if we don't place it + * explicitely in ROM, the statements will go in RAM, which will + * quickly cause a descent size program to run out of RAM. By default + * it doesn't disable the interupts; disabling the interupts when + * writing to the UART, slows down/makes the mote quite unresponsive, + * and can lead to problems! If you wish to disable all printfs to + * the UART, then comment the flag: PRINTFUART_ENABLED. + + *

+ * How to use:
+ *   // (1) Call printfUART_init() from your initialization function 
+ *   //     to initialize the UART
+ *   printfUART_init();
+ *   // (2) Set your UART client to the correct baud rate.  Look at 
+ *   //     the comments in printfUART_init(), to figure out what 
+ *   //     baud to use for your particular mote
+ *
+ *   // (3) Send printf statements like this:
+ *   printfUART("Hello World, we are in year= %i\n", 2004);
+ *
+ * Examples and caveats:
+ *   // (1) - If no parameters are passed, then the second quotes 
+ *            are required because of how the macro is defined
+ *   printfUART("Timer fired\n", ""); 
+ *   // (2) - Must use curly braces in single section statements
+ *   if (x < 3)
+ *       {printfUART("The value of x is %i\n", x);}
+ *   // (3) - Otherwise it more or less works like regular printf
+ *   printfUART("\nThe value of x=%i, and y=%i\n", x, y); 
+ * 
+ *
URL: http://www.eecs.harvard.edu/~konrad/projects/motetrack
+ * @author Konrad Lorincz + * @version 2.0, January 5, 2005 + */ +#ifndef PRINTFUART_H +#define PRINTFUART_H +#include +//#include + +// Comment out the line below to DISABLE printf statements. +//#define PRINTFUART_ENABLED + + +// ------------------------------------------------------------------- +#ifdef PRINTFUART_ENABLED + #define DEBUGBUF_SIZE 256 + char debugbuf[DEBUGBUF_SIZE]; + char debugbufROMtoRAM[DEBUGBUF_SIZE]; + + #if defined(PLATFORM_MICAZ) || defined(PLATFORM_MICA2) || defined(PLATFORM_MICA2DOT) + #define printfUART(__format, __args...) { \ + static const char strROM[] PROGMEM = __format; \ + strcpy_P((char*) &debugbufROMtoRAM, (PGM_P) &strROM); \ + sprintf(debugbuf, debugbufROMtoRAM, __args); \ + writedebug(); \ + } + #else // assume MSP430 architecture (e.g. TelosA, TelosB, etc.) + #define printfUART(__format, __args...) { \ + sprintf(debugbuf, __format, __args); \ + writedebug(); \ + } + #endif +#else + #define printfUART(__format, __args...) + void printfUART_init() {} +#endif + +#define NOprintfUART(__format, __args...) + + +/** Used for terminating the program from a non-nesc file. Calling exit(1) + * from a non-nesc file doesn't terminate the program immeditely + */ +static int EXIT_PROGRAM = 0; + + + +// ------------------------------------------------------------------- +#ifdef PRINTFUART_ENABLED + +/** + * Initialize the UART port. Call this from your startup routine. + */ +#define printfUART_init() {atomic printfUART_init_private();} +void printfUART_init_private() +{ + #if defined(PLATFORM_MICAZ) || defined(PLATFORM_MICA2) + // 56K baud + outp(0,UBRR0H); + outp(15, UBRR0L); //set baud rate + outp((1<> 8) & 0x0FF; + U1MCTL = l_mctl; + } + else { + U1BR0 = 0x03; // 9600 baud + U1BR1 = 0x00; + U1MCTL = 0x4A; + } + + ME2 &= ~USPIE1; // USART1 SPI module disable + ME2 |= (UTXE1 | URXE1); // USART1 UART module enable + + U1CTL &= ~SWRST; + + IFG2 &= ~(UTXIFG1 | URXIFG1); + IE2 &= ~(UTXIE1 | URXIE1); // interrupt disabled + + #endif + #endif +} + +#if defined(PLATFORM_MICAZ) || defined(PLATFORM_MICA2) || defined(PLATFORM_MICA2DOT) +#else // assume AVR architecture (e.g. TelosA, TelosB) + bool isTxIntrPending() + { + if (U1TCTL & TXEPT) { + return TRUE; + } + return FALSE; + } +#endif + +/** + * Outputs a char to the UART. + */ +void UARTPutChar(char c) +{ + if (c == '\n') + UARTPutChar('\r'); + + + #if defined(PLATFORM_MICAZ) || defined(PLATFORM_MICA2) || defined(PLATFORM_MICA2DOT) + loop_until_bit_is_set(UCSR0A, UDRE); + outb(UDR0,c); + #else // assume AVR architecture (e.g. TelosA, TelosB) + U1TXBUF = c; + while( !isTxIntrPending() ) + continue; + #endif +} + +/** + * Outputs the entire debugbuf to the UART, or until it encounters '\0'. + */ +void writedebug() +{ + uint16_t i = 0; + + while (debugbuf[i] != '\0' && i < DEBUGBUF_SIZE) + UARTPutChar(debugbuf[i++]); +} + + + +/** + * Simplified sprintf + */ +#define SCRATCH 16 +int sprintf(uint8_t *buf, const uint8_t *format, ...) +{ + uint8_t scratch[SCRATCH]; + uint8_t format_flag; + uint32_t u_val=0, base;//modified by Andre Cunha + uint8_t *ptr; + va_list ap; + + //memset(scratch, 0, SCRATCH); + + buf[0] = '\0'; // KLDEBUG - fixes subtle bug ... + va_start (ap, format); + for (;;){ + while ((format_flag = *format++) != '%'){ // Until '%' or '\0' + if (!format_flag) {va_end (ap); return (0);} + *buf = format_flag; buf++; *buf=0; + } + + switch (format_flag = *format++){ + + case 'c': + format_flag = va_arg(ap,int); + default: + *buf = format_flag; buf++; *buf=0; + continue; + case 'S': + case 's': + ptr = va_arg(ap,char *); + strcat(buf, ptr); + continue; + case 'o': + base = 8; + *buf = '0'; buf++; *buf=0; + goto CONVERSION_LOOP; + case 'i': + if (((int)u_val) < 0){ + u_val = - u_val; + *buf = '-'; buf++; *buf=0; + } + base = 10; + goto CONVERSION_LOOP; + // no break -> run into next case + case 'd'://added by Andre Cunha + if (((int32_t)u_val) < 0){ + u_val = - u_val; + *buf = '-'; buf++; *buf=0; + } + + base = 10; + goto CONVERSION_LOOP32; + case 'u': + base = 10; + goto CONVERSION_LOOP; + case 'x': + base = 16; + goto CONVERSION_LOOP; + + case 'y'://unsigned int 32 bits hexadecimal//added by Andre Cunha + base = 16; + goto CONVERSION_LOOP32; + + CONVERSION_LOOP: + u_val = va_arg(ap,int); + ptr = scratch + SCRATCH; + *--ptr = 0; + do { + char ch = u_val % base + '0'; + if (ch > '9') + ch += 'a' - '9' - 1; + *--ptr = ch; + u_val /= base; + } while (u_val); + strcat(buf, ptr); + buf += strlen(ptr); + break; + + CONVERSION_LOOP32: + u_val = va_arg(ap,int32_t); + ptr = scratch + SCRATCH; + *--ptr = 0; + do { + char ch = u_val % base + '0'; + if (ch > '9') + ch += 'a' - '9' - 1; + *--ptr = ch; + u_val /= base; + } while (u_val); + strcat(buf, ptr); + buf += strlen(ptr); + } + } +} + + +#endif // PRINTFUART_ENABLED +// ------------------------------------------------------------------- + +#endif // PRINTFUART_H + diff --git a/tos/lib/net/zigbee/ieee802154/includes/frame_format.h b/tos/lib/net/zigbee/ieee802154/includes/frame_format.h new file mode 100644 index 00000000..b8ddb79f --- /dev/null +++ b/tos/lib/net/zigbee/ieee802154/includes/frame_format.h @@ -0,0 +1,220 @@ +/* + * @author IPP HURRAY http://www.hurray.isep.ipp.pt/art-wise + * @author open-zb http://www.open-zb.net + * @author Andre Cunha + */ + +//MAC frame Superstructure + +#ifndef __FRAME_FORMAT__ +#define __FRAME_FORMAT__ + + +#define MPDU_HEADER_LEN 5 + +typedef struct MPDU +{ + uint8_t length; + //info on frame type/ack/etc + uint8_t frame_control1; + //info on addressing fields + uint8_t frame_control2; + //uint16_t frame_control; + uint8_t seq_num; + uint8_t data[120]; +}MPDU; + +typedef struct MPDUBuffer +{ + uint8_t length; + //uint16_t frame_control; + uint8_t frame_control1; + uint8_t frame_control2; + uint8_t seq_num; + uint8_t data[120]; + uint8_t retransmission; + uint8_t indirect; +}MPDUBuffer; + +//PD_DATA validation structures + + + +/*****************************************************/ +/* BEACON FRAME SCTRUCTURES */ +/*****************************************************/ + +//#define beacon_addr_short_length 7 +//#define beacon_addr_long_length 12 + + +typedef struct beacon_addr_short +{ + uint16_t destination_PAN_identifier; + uint16_t destination_address; + uint16_t source_address; + uint16_t superframe_specification; +}beacon_addr_short; +/* +typedef struct beacon_struct +{ + uint8_t length; + uint16_t frame_control; + uint8_t seq_num; + uint16_t source_PAN_identifier; + uint16_t destination_address; + uint16_t source_address; + uint16_t superframe_specification; +}beacon_struct; +*/ +/* +typedef struct beacon_addr_long +{ + uint16_t source_PAN_identifier; + uint32_t source_address0; + uint32_t source_address1; + uint16_t superframe_specification; +}beacon_addr_long; +*/ +/*****************************************************/ +/* ACK FRAME Structures */ +/*****************************************************/ + +typedef struct ACK +{ + uint8_t length; + uint8_t frame_control1; + uint8_t frame_control2; + //uint16_t frame_control; + uint8_t seq_num; +}ACK; + +/*****************************************************/ +/* COMMAND FRAME Structures */ +/*****************************************************/ + +typedef struct cmd_association_request +{ + uint8_t command_frame_identifier; + uint8_t capability_information; +}cmd_association_request; + +typedef struct cmd_association_response +{ + uint8_t command_frame_identifier; + uint8_t short_address1; + uint8_t short_address2; + //uint16_t short_address; + uint8_t association_status; +}cmd_association_response; + +//disassociacion notification command structure pag. 126 +typedef struct cmd_disassociation_notification +{ + uint16_t destination_PAN_identifier; + uint32_t destination_address0; + uint32_t destination_address1; + uint16_t source_PAN_identifier; + uint32_t source_address0; + uint32_t source_address1; + uint8_t command_frame_identifier; + uint8_t disassociation_reason; +}cmd_disassociation_notification; + +//pag 130 +typedef struct cmd_beacon_request +{ + uint16_t destination_PAN_identifier; + uint16_t destination_address; + uint8_t command_frame_identifier; +}cmd_beacon_request; + + +//pag 132 +typedef struct cmd_gts_request +{ + uint16_t source_PAN_identifier; + uint16_t source_address; + uint8_t command_frame_identifier; + uint8_t gts_characteristics; +}cmd_gts_request; + +typedef struct cmd_default +{ + uint8_t command_frame_identifier; +}cmd_default; + + +//131 +typedef struct cmd_coord_realignment +{ + uint8_t command_frame_identifier; + uint8_t PAN_identifier0; + uint8_t PAN_identifier1; + uint8_t coordinator_short_address0; + uint8_t coordinator_short_address1; + + /* + uint16_t PAN_identifier; + uint16_t coordinator_short_address; + */ + uint8_t logical_channel; + uint16_t short_address; +}cmd_coord_realignment; + + + +/*******************************************************/ +/* ADDRESSING FIELDS ONLY */ +/*******************************************************/ +#define DEST_SHORT_LEN 4 +#define DEST_LONG_LEN 10 +#define INTRA_PAN_SOURCE_SHORT_LEN 2 +#define INTRA_PAN_SOURCE_LONG_LEN 8 +#define SOURCE_SHORT_LEN 4 +#define SOURCE_LONG_LEN 10 + + +//DESTINATION +typedef struct dest_short +{ + uint16_t destination_PAN_identifier; + uint16_t destination_address; +}dest_short; + +typedef struct dest_long +{ + uint16_t destination_PAN_identifier; + uint32_t destination_address0; + uint32_t destination_address1; +}dest_long; + +//SOURCE +typedef struct intra_pan_source_short +{ + uint16_t source_address; +}intra_pan_source_short; + +typedef struct intra_pan_source_long +{ + uint32_t source_address0; + uint32_t source_address1; +}intra_pan_source_long; + + +typedef struct source_short +{ + uint16_t source_PAN_identifier; + uint16_t source_address; +}source_short; + + +typedef struct source_long +{ + uint16_t source_PAN_identifier; + uint32_t source_address0; + uint32_t source_address1; +}source_long; + +#endif + diff --git a/tos/lib/net/zigbee/ieee802154/includes/mac_func.h b/tos/lib/net/zigbee/ieee802154/includes/mac_func.h new file mode 100644 index 00000000..a4f14341 --- /dev/null +++ b/tos/lib/net/zigbee/ieee802154/includes/mac_func.h @@ -0,0 +1,384 @@ +/* + * @author IPP HURRAY http://www.hurray.isep.ipp.pt/art-wise + * @author open-zb http://www.open-zb.net + * @author Andre Cunha + */ + + +#ifndef __MAC_FUNC__ +#define __MAC_FUNC__ + +/*******************************************************************************************************************/ + +uint8_t set_capability_information(uint8_t alternate_PAN_coordinator, uint8_t device_type, uint8_t power_source, uint8_t receiver_on_when_idle, uint8_t security, uint8_t allocate_address) +{ + + return ((allocate_address << 7 ) | (security << 6 ) | (receiver_on_when_idle << 3 ) | (power_source << 2 ) | ( device_type << 1 ) | (alternate_PAN_coordinator << 0) ); +} + +uint8_t get_alternate_PAN_coordinator(uint8_t capability_information) +{ + +if ( (capability_information & 0x01) == 0x01) + return 1; +else + return 0; + +} + + +/*******************************************************************************************************************/ +/********************************FRAME CONTROL FUNCTIONS************************************************************/ +/*******************************************************************************************************************/ + + //build MPDU frame control field +uint16_t set_frame_control(uint8_t frame_type,uint8_t security,uint8_t frame_pending,uint8_t ack_request,uint8_t intra_pan,uint8_t dest_addr_mode,uint8_t source_addr_mode) +{ + uint8_t fc_b1=0; + uint8_t fc_b2=0; + fc_b1 = ( (intra_pan << 6) | (ack_request << 5) | (frame_pending << 4) | + (security << 3) | (frame_type << 0) ); + fc_b2 = ( (source_addr_mode << 6) | (dest_addr_mode << 2)); + return ( (fc_b2 << 8 ) | (fc_b1 << 0) ); + +} + + +//return the type of destination address specified in the frame control + +uint8_t get_fc2_dest_addr(uint8_t frame_control) +{ + switch( frame_control & 0xC ) + { + case 0x4: return RESERVED_ADDRESS; + break; + case 0x8: return SHORT_ADDRESS; + break; + case 0xC: return LONG_ADDRESS; + break; + default: + return 0; + break; + } +} + + +//return the type of source address specified in the frame control + +uint8_t get_fc2_source_addr(uint8_t frame_control) +{ + switch(frame_control & 0xC0 ) + { + case 0x40: return RESERVED_ADDRESS; + break; + case 0x80: return SHORT_ADDRESS; + break; + case 0xC0: return LONG_ADDRESS; + break; + default: + return 0; + break; + } +} + + + +bool get_fc1_security(uint8_t frame_control) +{ + +if ( (frame_control & 0x8) == 0x8) + return 1; +else + return 0; + +} + +bool get_fc1_frame_pending(uint8_t frame_control) +{ + +if ( (frame_control & 0x10) == 0x10) + return 1; +else + return 0; + +} + +bool get_fc1_ack_request(uint8_t frame_control) +{ + +if ( (frame_control & 0x20) == 0x20) + return 1; +else + return 0; + +} + +bool get_fc1_intra_pan(uint8_t frame_control) +{ + +if ( (frame_control & 0x40) == 0x40) + return 1; +else + return 0; + +} + + +/*******************************************************************************************************************/ +/********************************SUPERFRAME SPECIFICATION FUNCTIONS*************************************************/ +/*******************************************************************************************************************/ + +//build beacon superframe specification +uint16_t set_superframe_specification(uint8_t beacon_order,uint8_t superframe_order,uint8_t final_cap_slot,uint8_t battery_life_extension,uint8_t pan_coordinator,uint8_t association_permit) +{ + uint8_t sf_b1=0; + uint8_t sf_b2=0; + sf_b1 = ( (superframe_order << 4) | (beacon_order <<0)); + sf_b2 = ( (association_permit << 7) | (pan_coordinator << 6) | + (battery_life_extension << 4) | (final_cap_slot << 0) ); + return ( (sf_b2 <<8 ) | (sf_b1 << 0) ); + +} + +uint8_t get_beacon_order(uint16_t superframe) +{ + return ((uint8_t)superframe & 0xF); +} + +uint8_t get_superframe_order(uint16_t superframe) +{ + return (((uint8_t)superframe >> 4) & 0xF); +} + + + +bool get_pan_coordinator(uint16_t superframe) +{ +if ( ((uint8_t)superframe & 0x40) == 0x40) + return 1; +else + return 0; + +} + +bool get_association_permit(uint16_t superframe) +{ +if ( ((uint8_t)superframe & 0x80) == 0x80) + return 1; +else + return 0; +} + +bool get_battery_life_extention(uint16_t superframe) +{ +if ( ((uint8_t)superframe & 0x10) == 0x10) + return 1; +else + return 0; +} + +uint8_t get_final_cap_slot(uint16_t superframe) +{ +return (((uint8_t)superframe >> 4) & 0xF); +} + + +/*******************************************************************************************************************/ +/******************************** DATA TX OPTIONS ************************************************************/ +/*******************************************************************************************************************/ + + +uint8_t set_txoptions(uint8_t ack, uint8_t gts, uint8_t indirect_transmission,uint8_t security) +{ +return ( (ack << 0) | (gts << 1) | (indirect_transmission << 2) | (security << 3 ) ); +} + +bool get_txoptions_ack(uint8_t txoptions) +{ + +if ( (txoptions & 0x1) == 0x1) + return 1; +else + return 0; + +} + +bool get_txoptions_gts(uint8_t txoptions) +{ + +if ( (txoptions & 0x2) == 0x2) + return 1; +else + return 0; + +} + +bool get_txoptions_indirect_transmission(uint8_t txoptions) +{ + +if ( (txoptions & 0x4) == 0x4) + return 1; +else + return 0; + +} + +bool get_txoptions_security(uint8_t txoptions) +{ + +if ( (txoptions & 0x8) == 0x8) + return 1; +else + return 0; +} + + +//BEACON SCHEDULING IMPLEMENTATION +bool get_txoptions_upstream_buffer(uint8_t txoptions) +{ + +if ( (txoptions & 0x10) == 0x10) + return 1; +else + return 0; +} + +uint8_t set_txoptions_upstream(uint8_t ack, uint8_t gts, uint8_t indirect_transmission,uint8_t security,uint8_t upstream) +{ +return ( (ack << 0) | (gts << 1) | (indirect_transmission << 2) | (security << 3 ) | (upstream << 4) ); +} + + +/*******************************************************************************************************************/ +/********************************PENDING ADDRESSES FUNCTIONS********************************************************/ +/*******************************************************************************************************************/ +uint8_t set_pending_address_specification(uint8_t number_short, uint8_t number_extended) +{ + return ( (number_extended << 4) | (number_short << 0) ); +} + +uint8_t get_number_short(uint8_t pending_specification) +{ + return (pending_specification & 0x07); +} + +uint8_t get_number_extended(uint8_t pending_specification) +{ + return ( (pending_specification >> 4) & 0x07); +} + + +/*******************************************************************************************************************/ +/********************************GTS FIELDS FUNCTIONS***************************************************************/ +/*******************************************************************************************************************/ +uint8_t set_gts_specification(uint8_t gts_descriptor_count, uint8_t gts_permit) +{ + return ( ( gts_descriptor_count << 0) | (gts_permit << 7) ); +} + +uint8_t get_gts_permit(uint8_t gts_specification) +{ +return ( (gts_specification >> 7) & 0x01); +} + + +///UNUSED +uint8_t set_gts_directions(uint8_t gts1,uint8_t gts2,uint8_t gts3,uint8_t gts4,uint8_t gts5,uint8_t gts6,uint8_t gts7) +{ + return ((gts1 << 0) | (0 << 7)); +} + + +uint8_t set_gts_descriptor(uint8_t GTS_starting_slot, uint8_t GTS_length) +{ +//part of the descriptor list + return ( (GTS_starting_slot << 0) | (GTS_length << 4) ); +} + +uint8_t get_gts_descriptor_len(uint8_t gts_des_part) +{ + return ( (gts_des_part & 0xf0) >> 4); +} + +uint8_t get_gts_descriptor_ss(uint8_t gts_des_part) +{ + return (gts_des_part & 0x0f); +} + + + +/************************************************************************************************/ +/********************************GTS CHARACTERISTICS*************************************************/ +/************************************************************************************************/ +uint8_t set_gts_characteristics(uint8_t gts_length, uint8_t gts_direction, uint8_t characteristic_type) +{ + return ( (gts_length << 0) | (gts_direction << 4) | (characteristic_type << 5)); +} + + +uint8_t get_gts_length(uint8_t gts_characteristics) +{ + return (gts_characteristics & 0xF); +} + +bool get_gts_direction(uint8_t gts_characteristics) +{ + if ( (gts_characteristics & 0x10) == 0x10) + return 1; + else + return 0; +} + +uint8_t get_characteristic_type(uint8_t gts_characteristics) +{ + if ( (gts_characteristics & 0x20) == 0x20) + return 1; + else + return 0; +} + + +/************************************************************************************************/ +/********************************OTHER FUNCTIONS*************************************************/ +/************************************************************************************************/ + /* A Task to calculate CRC for message transmission */ + /* + task void CRCCalc() { + uint16_t length = txLength; + uint16_t crc = calcrc(sendPtr, length - 2); + + sendPtr[length - 2] = crc & 0xff; + sendPtr[length - 1] = (crc >> 8) & 0xff; + + } + */ + +uint16_t get_crcByte(uint16_t crc, uint8_t b) +{ + uint8_t i; + + crc = crc ^ b << 8; + i = 8; + do + if (crc & 0x8000) + crc = crc << 1 ^ 0x1021; + else + crc = crc << 1; + while (--i); + + return crc; +} + /* Internal function to calculate 16 bit CRC */ + uint16_t calcrc(uint8_t *ptr, uint8_t count) { + uint16_t crc; + //uint8_t i; + + crc = 0; + while (count-- > 0) + crc = get_crcByte(crc, *ptr++); + + return crc; + } + +#endif + diff --git a/tos/lib/net/zigbee/ieee802154/includes/nwk_func.h b/tos/lib/net/zigbee/ieee802154/includes/nwk_func.h new file mode 100644 index 00000000..dbd3975f --- /dev/null +++ b/tos/lib/net/zigbee/ieee802154/includes/nwk_func.h @@ -0,0 +1,141 @@ +/* + * @author IPP HURRAY http://www.hurray.isep.ipp.pt/art-wise + * @author IPP HURRAY http://www.open-zb.net + * @author Andre Cunha + */ + +#ifndef __NWK_FUNC__ +#define __NWK_FUNC__ + +//TEST +typedef struct associated_device +{ + +uint32_t address0; +uint32_t address1; + +uint16_t pan_address; + +}associated_device; +//END TEST + +typedef struct routing_fields +{ + +//uint8_t frame_control1; +//uint8_t frame_control2; +uint16_t frame_control; +uint16_t destination_address; +uint16_t source_address; +uint8_t radius; +uint8_t sequence_number; + +}routing_fields; + +/*******************************************************************************************************************/ +/********************************NETWORK LAYER FRAME CONTROL FUNCTIONS************************************************************/ +/*******************************************************************************************************************/ + + //build NPDU frame control field +uint16_t set_route_frame_control(uint8_t Frame_type,uint8_t Protocol_version,uint8_t Discover_route,uint8_t Security) +{ + uint8_t fc_byte1=0; + uint8_t fc_byte2=0; + fc_byte1 = ( (Discover_route << 6) | (Protocol_version << 2) | (Frame_type << 0) ); + fc_byte2 = ((Security<< 2)); + return ( (fc_byte2 <<8 ) | (fc_byte1 << 0) ); + +} + + +uint8_t route_fc1(uint8_t Security) +{ + uint8_t fc; + fc = ((Security << 2)); + return fc; +} + +uint8_t route_fc2(uint8_t Frame_type,uint8_t Protocol_version,uint8_t Discover_route) +{ + uint8_t fc; + fc = ( (Discover_route << 6) | (Protocol_version << 2) | (Frame_type << 0) ); + return fc; +} + +uint8_t get_route_frame_type(uint16_t frame_control) +{ + return (frame_control & 0x3); +} + +uint8_t get_route_protocol_version(uint16_t frame_control) +{ + return ( (frame_control >> 2) & 0xf); +} + +uint8_t get_route_discover_route(uint16_t frame_control) +{ + return ( (frame_control >> 6) & 0x3); +} + +uint8_t get_route_security(uint16_t frame_control) +{ + if( ((frame_control >> 8) & 0x2) == 0x2) + return 1; + else + return 0; +} + +/*******************************************************************************************************************/ +/********************************NETWORK LAYER BEACON PAYLOAD INFORMATION FUNCTIONS*********************************/ +/*******************************************************************************************************************/ + +uint8_t nwk_payload_profile_protocolversion(uint8_t stackprofile,uint8_t nwkcprotocolversion) +{ + +return ((stackprofile << 0) | ( nwkcprotocolversion << 4)); +} + +uint8_t nwk_payload_capacity(uint8_t routercapacity,uint8_t devicedepth,uint8_t enddevicecapacity) +{ + +return ((enddevicecapacity << 7) | ( devicedepth << 3 ) | (routercapacity << 2 ) ); +} + + +uint8_t get_protocolid(uint32_t nwk_information) +{ + return (uint8_t)((nwk_information & 0xFF000000) >> 24); +} + +uint8_t get_stackprofile(uint32_t nwk_information) +{ + return (uint8_t)((nwk_information & 0x00F00000)>>20); +} + +uint8_t get_nwkcprotocolversion(uint32_t nwk_information) +{ + return (uint8_t)((nwk_information & 0x000F0000)>>16); +} + +uint8_t get_routercapacity(uint32_t nwk_information) +{ + if ( ( nwk_information & 0x00002000) == 0x00002000) + return 1; + else + return 0; +} + +uint8_t get_devicedepth(uint32_t nwk_information) +{ + return (uint8_t)((nwk_information & 0x00001F00) >> 8); +} + +uint8_t get_enddevicecapacity(uint32_t nwk_information) +{ + if ( ( nwk_information & 0x00000001) == 0x00000001) + return 1; + else + return 0; +} + +#endif diff --git a/tos/lib/net/zigbee/ieee802154/interfaces/mac/MCPS_DATA.nc b/tos/lib/net/zigbee/ieee802154/interfaces/mac/MCPS_DATA.nc new file mode 100644 index 00000000..d7757798 --- /dev/null +++ b/tos/lib/net/zigbee/ieee802154/interfaces/mac/MCPS_DATA.nc @@ -0,0 +1,18 @@ +/** + * MCPS-DATA-Service Access Point + * @author IPP HURRAY http://www.hurray.isep.ipp.pt/art-wise + * @author http://www.open-zb.net + * @author Andre Cunha + * + *pag 56 + */ + +interface MCPS_DATA +{ + command error_t request(uint8_t SrcAddrMode, uint16_t SrcPANId, uint32_t SrcAddr[], uint8_t DstAddrMode, uint16_t DestPANId, uint32_t DstAddr[], uint8_t msduLength, uint8_t msdu[],uint8_t msduHandle, uint8_t TxOptions); + + event error_t confirm(uint8_t msduHandle, uint8_t status); + + event error_t indication(uint16_t SrcAddrMode, uint16_t SrcPANId, uint32_t SrcAddr[2], uint16_t DstAddrMode, uint16_t DestPANId, uint32_t DstAddr[2], uint16_t msduLength,uint8_t msdu[100],uint16_t mpduLinkQuality, uint16_t SecurityUse, uint16_t ACLEntry); + +} diff --git a/tos/lib/net/zigbee/ieee802154/interfaces/mac/MCPS_PURGE.nc b/tos/lib/net/zigbee/ieee802154/interfaces/mac/MCPS_PURGE.nc new file mode 100644 index 00000000..cad4cd2f --- /dev/null +++ b/tos/lib/net/zigbee/ieee802154/interfaces/mac/MCPS_PURGE.nc @@ -0,0 +1,16 @@ +/** + * MCPS-PURGE-Service Access Point + * @author IPP HURRAY http://www.hurray.isep.ipp.pt/art-wise + * @author IPP HURRAY http://www.open-zb.net + * @author Andre Cunha + * + * + */ + +interface MCPS_PURGE +{ + command error_t request(uint8_t msduHandle); + + event error_t confirm(uint8_t msduHandle, uint8_t status); + +} diff --git a/tos/lib/net/zigbee/ieee802154/interfaces/mac/MLME_ASSOCIATE.nc b/tos/lib/net/zigbee/ieee802154/interfaces/mac/MLME_ASSOCIATE.nc new file mode 100644 index 00000000..74e9027f --- /dev/null +++ b/tos/lib/net/zigbee/ieee802154/interfaces/mac/MLME_ASSOCIATE.nc @@ -0,0 +1,19 @@ +/** + * MLME-ASSOCIATE-Service Access Point + * std pag 65 + * @author IPP HURRAY http://www.hurray.isep.ipp.pt/art-wise + * @author IPP HURRAY http://www.open-zb.net + * @author Andre Cunha + */ + +interface MLME_ASSOCIATE +{ + command error_t request(uint8_t LogicalChannel,uint8_t CoordAddrMode,uint16_t CoordPANId,uint32_t CoordAddress[],uint8_t CapabilityInformation,bool SecurityEnable); + + event error_t indication(uint32_t DeviceAddress[], uint8_t CapabilityInformation, bool SecurityUse, uint8_t ACLEntry); + + command error_t response(uint32_t DeviceAddress[], uint16_t AssocShortAddress, uint8_t status, bool SecurityEnable); + + event error_t confirm(uint16_t AssocShortAddress, uint8_t status); + +} diff --git a/tos/lib/net/zigbee/ieee802154/interfaces/mac/MLME_BEACON_NOTIFY.nc b/tos/lib/net/zigbee/ieee802154/interfaces/mac/MLME_BEACON_NOTIFY.nc new file mode 100644 index 00000000..97ff2c03 --- /dev/null +++ b/tos/lib/net/zigbee/ieee802154/interfaces/mac/MLME_BEACON_NOTIFY.nc @@ -0,0 +1,14 @@ +/* + * MLME-BEACON-NOTIFY-Service Access Point + * std pag 75 + * @author IPP HURRAY http://www.hurray.isep.ipp.pt/art-wise + * @author IPP HURRAY http://www.open-zb.net + * @author Andre Cunha + */ +includes mac_const; + +interface MLME_BEACON_NOTIFY +{ + event error_t indication(uint8_t BSN,PANDescriptor pan_descriptor, uint8_t PenAddrSpec, uint8_t AddrList, uint8_t sduLength, uint8_t sdu[]); + +} diff --git a/tos/lib/net/zigbee/ieee802154/interfaces/mac/MLME_COMM_STATUS.nc b/tos/lib/net/zigbee/ieee802154/interfaces/mac/MLME_COMM_STATUS.nc new file mode 100644 index 00000000..0c734f17 --- /dev/null +++ b/tos/lib/net/zigbee/ieee802154/interfaces/mac/MLME_COMM_STATUS.nc @@ -0,0 +1,16 @@ +/* + * MLME-COMM-STATUS-Service Access Point + * std pag 96 + * @author IPP HURRAY http://www.hurray.isep.ipp.pt/art-wise + * @author IPP HURRAY http://www.open-zb.net + * @author Andre Cunha + * + * + */ + +interface MLME_COMM_STATUS +{ + + event result_t indication(uint16_t PANId,uint8_t SrcAddrMode, uint32_t SrcAddr[], uint8_t DstAddrMode, uint32_t DstAddr[], uint8_t status); + +} diff --git a/tos/lib/net/zigbee/ieee802154/interfaces/mac/MLME_DISASSOCIATE.nc b/tos/lib/net/zigbee/ieee802154/interfaces/mac/MLME_DISASSOCIATE.nc new file mode 100644 index 00000000..224112ba --- /dev/null +++ b/tos/lib/net/zigbee/ieee802154/interfaces/mac/MLME_DISASSOCIATE.nc @@ -0,0 +1,18 @@ +/** + * MLME-DISASSOCIATE-Service Access Point + * @author IPP HURRAY http://www.hurray.isep.ipp.pt/art-wise + * @author IPP HURRAY http://www.open-zb.net + * @author Andre Cunha + * pag 73 + * + */ + +interface MLME_DISASSOCIATE +{ + command error_t request(uint32_t DeviceAddress[], uint8_t DisassociateReason, uint8_t SecurityEnable); + + event error_t indication(uint32_t DeviceAddress[], uint8_t DisassociateReason, uint8_t SecurityUse, uint8_t ACLEntry); + + event error_t confirm(uint8_t status); + +} diff --git a/tos/lib/net/zigbee/ieee802154/interfaces/mac/MLME_GET.nc b/tos/lib/net/zigbee/ieee802154/interfaces/mac/MLME_GET.nc new file mode 100644 index 00000000..3f6b35fe --- /dev/null +++ b/tos/lib/net/zigbee/ieee802154/interfaces/mac/MLME_GET.nc @@ -0,0 +1,14 @@ +/** + * MLME-GET-Service Access Point + * @author IPP HURRAY http://www.hurray.isep.ipp.pt/art-wise + * @author Andre Cunha + *pag 78 + */ + +interface MLME_GET +{ + command error_t request(uint8_t PIBAttribute); + + event error_t confirm(uint8_t status,uint8_t PIBAttribute, uint8_t PIBAttributeValue[]); + +} diff --git a/tos/lib/net/zigbee/ieee802154/interfaces/mac/MLME_GTS.nc b/tos/lib/net/zigbee/ieee802154/interfaces/mac/MLME_GTS.nc new file mode 100644 index 00000000..04e80d80 --- /dev/null +++ b/tos/lib/net/zigbee/ieee802154/interfaces/mac/MLME_GTS.nc @@ -0,0 +1,17 @@ +/** + * MLME-GTS-Service Access Point + * + * @author IPP HURRAY http://www.hurray.isep.ipp.pt/art-wise + * @author IPP HURRAY http://www.open-zb.net + * @author Andre Cunha + * pag 79 + */ + +interface MLME_GTS +{ + command error_t request(uint8_t GTSCharacteristics, uint8_t SecurityEnable); + + event error_t confirm(uint8_t GTSCharacteristics, uint8_t status); + + event error_t indication(uint16_t DevAddress, uint8_t GTSCharacteristics, uint8_t SecurityUse, uint8_t ACLEntry); +} diff --git a/tos/lib/net/zigbee/ieee802154/interfaces/mac/MLME_ORPHAN.nc b/tos/lib/net/zigbee/ieee802154/interfaces/mac/MLME_ORPHAN.nc new file mode 100644 index 00000000..358fdf90 --- /dev/null +++ b/tos/lib/net/zigbee/ieee802154/interfaces/mac/MLME_ORPHAN.nc @@ -0,0 +1,17 @@ +/** + * MLME-ORPHAN-Service Access Point + * + * @author IPP HURRAY http://www.hurray.isep.ipp.pt/art-wise + * @author IPP HURRAY http://www.open-zb.net + * @author Andre Cunha + * + */ + +interface MLME_ORPHAN +{ + + event error_t indication(uint32_t OrphanAddress[1], uint8_t SecurityUse, uint8_t ACLEntry); + + command error_t response(uint32_t OrphanAddress[1],uint16_t ShortAddress,uint8_t AssociatedMember, uint8_t security_enabled); + +} diff --git a/tos/lib/net/zigbee/ieee802154/interfaces/mac/MLME_POLL.nc b/tos/lib/net/zigbee/ieee802154/interfaces/mac/MLME_POLL.nc new file mode 100644 index 00000000..b8684129 --- /dev/null +++ b/tos/lib/net/zigbee/ieee802154/interfaces/mac/MLME_POLL.nc @@ -0,0 +1,15 @@ +/** + * MLME-POOL-Service Access Point + * @author IPP HURRAY http://www.hurray.isep.ipp.pt/art-wise + * @author IPP HURRAY http://www.open-zb.net + * @author Andre Cunha + * pag 107 + */ + +interface MLME_POLL +{ + command result_t request(uint8_t CoordAddrMode, uint16_t CoorPANId, uint32_t CoorAddress[], uint8_t Security); + + event result_t confirm(uint8_t status); + +} diff --git a/tos/lib/net/zigbee/ieee802154/interfaces/mac/MLME_RESET.nc b/tos/lib/net/zigbee/ieee802154/interfaces/mac/MLME_RESET.nc new file mode 100644 index 00000000..ac1a36aa --- /dev/null +++ b/tos/lib/net/zigbee/ieee802154/interfaces/mac/MLME_RESET.nc @@ -0,0 +1,19 @@ +/** + * MLME-RESET-Service Access Point + * @author IPP HURRAY http://www.hurray.isep.ipp.pt/art-wise + * @author IPP HURRAY http://www.open-zb.net + * @author Andre Cunha + * + * + */ + +interface MLME_RESET +{ + + command error_t request(uint8_t set_default_PIB); + + event error_t confirm(uint8_t status); + + + +} diff --git a/tos/lib/net/zigbee/ieee802154/interfaces/mac/MLME_RX_ENABLE.nc b/tos/lib/net/zigbee/ieee802154/interfaces/mac/MLME_RX_ENABLE.nc new file mode 100644 index 00000000..833ff4e5 --- /dev/null +++ b/tos/lib/net/zigbee/ieee802154/interfaces/mac/MLME_RX_ENABLE.nc @@ -0,0 +1,19 @@ +/** + * MLME-RX-ENABLE-Service Access Point + * @author IPP HURRAY http://www.hurray.isep.ipp.pt/art-wise + * @author IPP HURRAY http://www.open-zb.net + * @author Andre Cunha + * + * + */ + +interface MLME_RX_ENABLE +{ + + command result_t request(uint8_tDeferPermit, uint32_t RxOnTime, uint32_t RxOnDuration); + + event result_t confirm(uint8_t status); + + + +} diff --git a/tos/lib/net/zigbee/ieee802154/interfaces/mac/MLME_SCAN.nc b/tos/lib/net/zigbee/ieee802154/interfaces/mac/MLME_SCAN.nc new file mode 100644 index 00000000..ba4bd966 --- /dev/null +++ b/tos/lib/net/zigbee/ieee802154/interfaces/mac/MLME_SCAN.nc @@ -0,0 +1,18 @@ +/** + * MLME-SCAN-Service Access Point + * @author IPP HURRAY http://www.hurray.isep.ipp.pt/art-wise + * @author IPP HURRAY http://www.open-zb.net + * @author Andre Cunha + * pag 93 + * + */ + +interface MLME_SCAN +{ + + command error_t request(uint8_t ScanType, uint32_t ScanChannels, uint8_t ScanDuration); + + event error_t confirm(uint8_t status,uint8_t ScanType, uint32_t UnscannedChannels, uint8_t ResultListSize, uint8_t EnergyDetectList[], SCAN_PANDescriptor PANDescriptorList[]); + //NEED to explain the implementation + //Eache value in sequencial to the scanned channels + } diff --git a/tos/lib/net/zigbee/ieee802154/interfaces/mac/MLME_SET.nc b/tos/lib/net/zigbee/ieee802154/interfaces/mac/MLME_SET.nc new file mode 100644 index 00000000..6c97e885 --- /dev/null +++ b/tos/lib/net/zigbee/ieee802154/interfaces/mac/MLME_SET.nc @@ -0,0 +1,15 @@ +/** + * MLME-SET-Service Access Point + * @author IPP HURRAY http://www.hurray.isep.ipp.pt/art-wise + * @author IPP HURRAY http://www.open-zb.net + * @author Andre Cunha + * pag 98 + */ + +interface MLME_SET +{ + command error_t request(uint8_t PIBAttribute,uint8_t PIBAttributeValue[]); + + event error_t confirm(uint8_t status,uint8_t PIBAttribute); + +} diff --git a/tos/lib/net/zigbee/ieee802154/interfaces/mac/MLME_START.nc b/tos/lib/net/zigbee/ieee802154/interfaces/mac/MLME_START.nc new file mode 100644 index 00000000..b6630c99 --- /dev/null +++ b/tos/lib/net/zigbee/ieee802154/interfaces/mac/MLME_START.nc @@ -0,0 +1,17 @@ +/** + * MLME-START-Service Access Point + * @author IPP HURRAY http://www.hurray.isep.ipp.pt/art-wise + * @author Andre Cunha + *pag 100 + * + */ + +interface MLME_START +{ + + //request for the device to start using new superframe configuration + command error_t request(uint32_t PANId, uint8_t LogicalChannel, uint8_t BeaconOrder, uint8_t SuperframeOrder,uint8_t PANCoordinator,uint8_t BatteryLifeExtension,uint8_t CoordRealignment,uint8_t SecurityEnable,uint32_t StartTime); + + event error_t confirm(uint8_t status); + +} diff --git a/tos/lib/net/zigbee/ieee802154/interfaces/mac/MLME_SYNC.nc b/tos/lib/net/zigbee/ieee802154/interfaces/mac/MLME_SYNC.nc new file mode 100644 index 00000000..d4fd5f12 --- /dev/null +++ b/tos/lib/net/zigbee/ieee802154/interfaces/mac/MLME_SYNC.nc @@ -0,0 +1,16 @@ +/** + * MLME-SYNC-Service Access Point + * + * @author IPP HURRAY http://www.hurray.isep.ipp.pt/art-wise + * @author IPP HURRAY http://www.open-zb.net + * @author Andre Cunha + * + * + */ + +interface MLME_SYNC +{ +//sd pag 105 + command error_t request(uint8_t logical_channel,uint8_t track_beacon); + +} diff --git a/tos/lib/net/zigbee/ieee802154/interfaces/mac/MLME_SYNC_LOSS.nc b/tos/lib/net/zigbee/ieee802154/interfaces/mac/MLME_SYNC_LOSS.nc new file mode 100644 index 00000000..66a56844 --- /dev/null +++ b/tos/lib/net/zigbee/ieee802154/interfaces/mac/MLME_SYNC_LOSS.nc @@ -0,0 +1,15 @@ +/** + * MLME-SYNC-LOSS-Service Access Point + * + * @author IPP HURRAY http://www.hurray.isep.ipp.pt/art-wise + * @author IPP HURRAY http://www.open-zb.net + * @author Andre Cunha + * + * + */ + +interface MLME_SYNC_LOSS +{ +//pag 105 + event error_t indication(uint8_t LossReason); +} diff --git a/tos/lib/net/zigbee/ieee802154/interfaces/mac/MLME_iGAME.nc b/tos/lib/net/zigbee/ieee802154/interfaces/mac/MLME_iGAME.nc new file mode 100644 index 00000000..e36438c7 --- /dev/null +++ b/tos/lib/net/zigbee/ieee802154/interfaces/mac/MLME_iGAME.nc @@ -0,0 +1,21 @@ +/** + * MLME-iGAME-Service Access Point + * + * @author IPP HURRAY http://www.hurray.isep.ipp.pt/art-wise + * @author IPP HURRAY http://www.open-zb.net + * @author Andre Cunha + * + * A. Koubâa, M. Alves, E. Tovar " i-GAME: An Implicit GTS Allocation Mechanism in IEEE 802.15.4" + * Proceedings of the Euromicro Conference on Real-Time Systems (ECRTS 2006), July 2006. + */ + +interface MLME_iGAME +{ + command result_t request(uint8_t GTSCharacteristics,uint16_t Flow_Specification, uint8_t SecurityEnable); + + command result_t response(Flow Flow_Description,uint8_t shared_time_slots, uint8_t status); + + event result_t confirm(uint8_t GTSCharacteristics,uint16_t Flow_Specification, uint8_t status); + + event result_t indication(uint16_t DevAddress, uint8_t GTSCharacteristics,uint16_t Flow_Specification, uint8_t SecurityUse, uint8_t ACLEntry); +} diff --git a/tos/lib/net/zigbee/ieee802154/interfaces/nwk/NLDE_DATA.nc b/tos/lib/net/zigbee/ieee802154/interfaces/nwk/NLDE_DATA.nc new file mode 100644 index 00000000..85b2ee17 --- /dev/null +++ b/tos/lib/net/zigbee/ieee802154/interfaces/nwk/NLDE_DATA.nc @@ -0,0 +1,19 @@ +/** + * NLDE-DATA + * @author IPP HURRAY http://www.hurray.isep.ipp.pt/art-wise + * @author open-zb http://www.open-zb.net + * @author Andre Cunha + * + */ +//page 159-163 + +interface NLDE_DATA +{ + + command error_t request(uint16_t DstAddr, uint16_t NsduLength, uint8_t Nsdu[100], uint8_t NsduHandle, uint8_t Radius, uint8_t DiscoverRoute, uint8_t SecurityEnable); + + event error_t indication(uint16_t SrcAddress, uint16_t NsduLength,uint8_t Nsdu[100], uint16_t LinkQuality); + + event error_t confirm(uint8_t NsduHandle, uint8_t Status); + +} diff --git a/tos/lib/net/zigbee/ieee802154/interfaces/nwk/NLME_DIRECT_JOIN.nc b/tos/lib/net/zigbee/ieee802154/interfaces/nwk/NLME_DIRECT_JOIN.nc new file mode 100644 index 00000000..06e4f418 --- /dev/null +++ b/tos/lib/net/zigbee/ieee802154/interfaces/nwk/NLME_DIRECT_JOIN.nc @@ -0,0 +1,17 @@ +/** + * NLME-DIRECT-JOIN + * @author IPP HURRAY http://www.hurray.isep.ipp.pt/art-wise + * @author http://www.open-zb.net + * @author Andre Cunha + */ +//page 179-181 + +interface NLME_DIRECT_JOIN +{ + + + command error_t request(uint32_t DeviceAddress0, uint32_t DeviceAddress1, CapabilityInformation); + + event error_t confirm(uint32_t DeviceAddress0,uint32_t DeviceAddress1, uint8_t Status); + +} diff --git a/tos/lib/net/zigbee/ieee802154/interfaces/nwk/NLME_GET.nc b/tos/lib/net/zigbee/ieee802154/interfaces/nwk/NLME_GET.nc new file mode 100644 index 00000000..0dca53e4 --- /dev/null +++ b/tos/lib/net/zigbee/ieee802154/interfaces/nwk/NLME_GET.nc @@ -0,0 +1,18 @@ +/** + * NLME-GET + * @author IPP HURRAY http://www.hurray.isep.ipp.pt/art-wise + * @author http://www.open-zb.net + * @author Andre Cunha + * + * + */ +//page 190-191 + +interface NLME_GET +{ + + command error_t request(uint8_t NIBAttribute); + + event error_t confirm(uint8_t Status, uint8_t NIBAttribute, uint16_t NIBAttributeLength, uint16_t NIBAttributeValue); + +} diff --git a/tos/lib/net/zigbee/ieee802154/interfaces/nwk/NLME_JOIN.nc b/tos/lib/net/zigbee/ieee802154/interfaces/nwk/NLME_JOIN.nc new file mode 100644 index 00000000..18b5a600 --- /dev/null +++ b/tos/lib/net/zigbee/ieee802154/interfaces/nwk/NLME_JOIN.nc @@ -0,0 +1,21 @@ +/** + * NLME-JOIN + * @author IPP HURRAY http://www.hurray.isep.ipp.pt/art-wise + * @author http://www.open-zb.net + * @author Andre Cunha + * + * + */ +//page 173-179 + +interface NLME_JOIN +{ + + + command error_t request(uint16_t PANId, bool JoinAsRouter, bool RejoinNetwork, uint32_t ScanChannels, uint8_t ScanDuration, uint8_t PowerSource, uint8_t RxOnWhenIdle, uint8_t MACSecurity); + + event error_t indication(uint16_t ShortAddress, uint32_t ExtendedAddress[], uint8_t CapabilityInformation, bool SecureJoin); + + event error_t confirm(uint16_t PANId, uint8_t Status); + +} diff --git a/tos/lib/net/zigbee/ieee802154/interfaces/nwk/NLME_LEAVE.nc b/tos/lib/net/zigbee/ieee802154/interfaces/nwk/NLME_LEAVE.nc new file mode 100644 index 00000000..e160607b --- /dev/null +++ b/tos/lib/net/zigbee/ieee802154/interfaces/nwk/NLME_LEAVE.nc @@ -0,0 +1,21 @@ +/** + * NLME-LEAVE + * @author IPP HURRAY http://www.hurray.isep.ipp.pt/art-wise + * @author http://www.open-zb.net + * @author Andre Cunha + * + * + */ +//page 181-184 + +interface NLME_LEAVE +{ + + + command error_t request(uint32_t DeviceAddress[],uint8_t RemoveChildren, uint8_t MACSecurityEnable); + + event error_t indication(uint32_t DeviceAddress[]); + + event error_t confirm(uint32_t DeviceAddress[], uint8_t Status); + +} diff --git a/tos/lib/net/zigbee/ieee802154/interfaces/nwk/NLME_NETWORK_DISCOVERY.nc b/tos/lib/net/zigbee/ieee802154/interfaces/nwk/NLME_NETWORK_DISCOVERY.nc new file mode 100644 index 00000000..b66ea88f --- /dev/null +++ b/tos/lib/net/zigbee/ieee802154/interfaces/nwk/NLME_NETWORK_DISCOVERY.nc @@ -0,0 +1,18 @@ +/* + * NLME-Network-Discovery + * @author IPP HURRAY http://www.hurray.isep.ipp.pt/art-wise + * @author http://www.open-zb.net + * @author Andre Cunha + * + * + */ +//page 164-167 + +interface NLME_NETWORK_DISCOVERY +{ + + command error_t request(uint32_t ScanChannels, uint8_t ScanDuration); + + event error_t confirm(uint8_t NetworkCount,networkdescriptor networkdescriptorlist[], uint8_t Status); + +} diff --git a/tos/lib/net/zigbee/ieee802154/interfaces/nwk/NLME_NETWORK_FORMATION.nc b/tos/lib/net/zigbee/ieee802154/interfaces/nwk/NLME_NETWORK_FORMATION.nc new file mode 100644 index 00000000..161e5099 --- /dev/null +++ b/tos/lib/net/zigbee/ieee802154/interfaces/nwk/NLME_NETWORK_FORMATION.nc @@ -0,0 +1,19 @@ +/* + * NLME-NETWORK-FORMATION + * @author IPP HURRAY http://www.hurray.isep.ipp.pt/art-wise + * @author http://www.open-zb.net + * @author Andre Cunha + * + * + */ +//page 167-169 + +interface NLME_NETWORK_FORMATION +{ + + + command error_t request(uint32_t ScanChannels, uint8_t ScanDuration, uint8_t BeaconOrder, uint8_t SuperframeOrder, uint16_t PANId, uint8_t BatteryLifeExtension); + + event error_t confirm(uint8_t Status); + +} diff --git a/tos/lib/net/zigbee/ieee802154/interfaces/nwk/NLME_PERMIT_JOINING.nc b/tos/lib/net/zigbee/ieee802154/interfaces/nwk/NLME_PERMIT_JOINING.nc new file mode 100644 index 00000000..6f811e2d --- /dev/null +++ b/tos/lib/net/zigbee/ieee802154/interfaces/nwk/NLME_PERMIT_JOINING.nc @@ -0,0 +1,18 @@ +/** + * NLME-PERMIT_JOINING + * @author IPP HURRAY http://www.hurray.isep.ipp.pt/art-wise + * @author http://www.open-zb.net + * @author Andre Cunha + * + * + */ +//page 170-171 + +interface NLME_PERMIT_JOINING +{ + + command error_t request(uint8_t PermitDuration); + + event error_t confirm(uint8_t Status); + +} diff --git a/tos/lib/net/zigbee/ieee802154/interfaces/nwk/NLME_RESET.nc b/tos/lib/net/zigbee/ieee802154/interfaces/nwk/NLME_RESET.nc new file mode 100644 index 00000000..f3b9c051 --- /dev/null +++ b/tos/lib/net/zigbee/ieee802154/interfaces/nwk/NLME_RESET.nc @@ -0,0 +1,19 @@ +/** + * NLME-RESET + * @author IPP HURRAY http://www.hurray.isep.ipp.pt/art-wise + * @author http://www.open-zb.net + * @author Andre Cunha + * + * + */ +//page 185-186 + +interface NLME_RESET +{ + + + command error_t request(); + + event error_t confirm(uint8_t Status); + +} diff --git a/tos/lib/net/zigbee/ieee802154/interfaces/nwk/NLME_SET.nc b/tos/lib/net/zigbee/ieee802154/interfaces/nwk/NLME_SET.nc new file mode 100644 index 00000000..6d9d831b --- /dev/null +++ b/tos/lib/net/zigbee/ieee802154/interfaces/nwk/NLME_SET.nc @@ -0,0 +1,18 @@ +/** + * NLME-SET + * @author IPP HURRAY http://www.hurray.isep.ipp.pt/art-wise + * @author http://www.open-zb.net + * @author Andre Cunha + * + * + */ +//page 191-192 + +interface NLME_SET +{ + + command error_t request(uint8_t NIBAttribute, uint16_t NIBAttributeLength, uint16_t NIBAttributeValue); + + event error_t confirm(uint8_t Status, uint8_t NIBAttribute); + +} diff --git a/tos/lib/net/zigbee/ieee802154/interfaces/nwk/NLME_START_ROUTER.nc b/tos/lib/net/zigbee/ieee802154/interfaces/nwk/NLME_START_ROUTER.nc new file mode 100644 index 00000000..68b5d253 --- /dev/null +++ b/tos/lib/net/zigbee/ieee802154/interfaces/nwk/NLME_START_ROUTER.nc @@ -0,0 +1,17 @@ +/** + * NLME-Start-Router + * @author IPP HURRAY http://www.hurray.isep.ipp.pt/art-wise + * @author http://www.open-zb.net + * @author Andre Cunha + * + */ +//page 171-173 + +interface NLME_START_ROUTER +{ + + command error_t request(uint8_t BeaconOrder, uint8_t SuperframeOrder, uint8_t BatteryLifeExtension,uint32_t StartTime); + + event error_t confirm(uint8_t Status); + +} diff --git a/tos/lib/net/zigbee/ieee802154/interfaces/nwk/NLME_SYNC.nc b/tos/lib/net/zigbee/ieee802154/interfaces/nwk/NLME_SYNC.nc new file mode 100644 index 00000000..22a84195 --- /dev/null +++ b/tos/lib/net/zigbee/ieee802154/interfaces/nwk/NLME_SYNC.nc @@ -0,0 +1,21 @@ +/** + * NLME-SYNC + * @author IPP HURRAY http://www.hurray.isep.ipp.pt/art-wise + * @author http://www.open-zb.net + * @author Andre Cunha + * + * + */ +//page 186-189 + +interface NLME_SYNC +{ + + + command error_t request(uint8_t Track); + + event error_t indication(); + + event error_t confirm(uint8_t Status); + +} diff --git a/tos/lib/net/zigbee/ieee802154/interfaces/phy/PD_DATA.nc b/tos/lib/net/zigbee/ieee802154/interfaces/phy/PD_DATA.nc new file mode 100644 index 00000000..6df0efe5 --- /dev/null +++ b/tos/lib/net/zigbee/ieee802154/interfaces/phy/PD_DATA.nc @@ -0,0 +1,19 @@ +/** + * PD-Service Access Point + * @author IPP HURRAY http://www.hurray.isep.ipp.pt/art-wise + * @author http://www.open-zb.net + * @author Andre Cunha + * + * + */ +//#include + +interface PD_DATA +{ + async command error_t request(uint8_t psduLenght, uint8_t* psdu); + + async event error_t confirm(uint8_t status); + + async event error_t indication(uint8_t psduLenght,uint8_t* psdu, int8_t ppduLinkQuality); + +} diff --git a/tos/lib/net/zigbee/ieee802154/interfaces/phy/PLME_CCA.nc b/tos/lib/net/zigbee/ieee802154/interfaces/phy/PLME_CCA.nc new file mode 100644 index 00000000..6878241b --- /dev/null +++ b/tos/lib/net/zigbee/ieee802154/interfaces/phy/PLME_CCA.nc @@ -0,0 +1,17 @@ +/** + * Physical Layer Management Entity-Service Access Point + * PLME-SAP - PLME-CCA + * @author IPP HURRAY http://www.hurray.isep.ipp.pt/art-wise + * @author Andre Cunha + * + */ + +interface PLME_CCA +{ +/*PLME_CCA*/ + + command error_t request(); + + event error_t confirm(uint8_t status); + +} diff --git a/tos/lib/net/zigbee/ieee802154/interfaces/phy/PLME_ED.nc b/tos/lib/net/zigbee/ieee802154/interfaces/phy/PLME_ED.nc new file mode 100644 index 00000000..fe237cb4 --- /dev/null +++ b/tos/lib/net/zigbee/ieee802154/interfaces/phy/PLME_ED.nc @@ -0,0 +1,16 @@ +/** + * Physical Layer Management Entity-Service Access Point + * PLME-SAP - PLME-ED + * @author IPP HURRAY http://www.hurray.isep.ipp.pt/art-wise + * @author Andre Cunha + */ + +interface PLME_ED +{ +/*PLME_ED*/ + + command error_t request(); + + event error_t confirm(uint8_t status,int8_t EnergyLevel); + +} diff --git a/tos/lib/net/zigbee/ieee802154/interfaces/phy/PLME_GET.nc b/tos/lib/net/zigbee/ieee802154/interfaces/phy/PLME_GET.nc new file mode 100644 index 00000000..d352eb31 --- /dev/null +++ b/tos/lib/net/zigbee/ieee802154/interfaces/phy/PLME_GET.nc @@ -0,0 +1,18 @@ +/** + * Physical Layer Management Entity-Service Access Point + * PLME-SAP - PLME-GET + * @author IPP HURRAY http://www.hurray.isep.ipp.pt/art-wise + * @author Andre Cunha + * + * + */ + +interface PLME_GET +{ +/*PLME_GET*/ + + command error_t request(uint8_t PIBAttribute); + + event error_t confirm(uint8_t status, uint8_t PIBAttribute, uint8_t PIBAttributeValue); + +} diff --git a/tos/lib/net/zigbee/ieee802154/interfaces/phy/PLME_SET.nc b/tos/lib/net/zigbee/ieee802154/interfaces/phy/PLME_SET.nc new file mode 100644 index 00000000..2393a53d --- /dev/null +++ b/tos/lib/net/zigbee/ieee802154/interfaces/phy/PLME_SET.nc @@ -0,0 +1,18 @@ +/** + * Physical Layer Management Entity-Service Access Point + * PLME-SAP - PLME-SET + * @author IPP HURRAY http://www.hurray.isep.ipp.pt/art-wise + * @author Andre Cunha + * + * + */ + +interface PLME_SET +{ +/*PLME_SET*/ + + command error_t request(uint8_t PIBAttribute, uint8_t PIBAttributeValue); + + event error_t confirm(uint8_t status, uint8_t PIBAttribute); + +} diff --git a/tos/lib/net/zigbee/ieee802154/interfaces/phy/PLME_SET_TRX_STATE.nc b/tos/lib/net/zigbee/ieee802154/interfaces/phy/PLME_SET_TRX_STATE.nc new file mode 100644 index 00000000..03dd8bbf --- /dev/null +++ b/tos/lib/net/zigbee/ieee802154/interfaces/phy/PLME_SET_TRX_STATE.nc @@ -0,0 +1,18 @@ +/** + * Physical Layer Management Entity-Service Access Point + * PLME-SAP - PLME-SET_TRX_STATE + * + * @author IPP HURRAY http://www.hurray.isep.ipp.pt/art-wise + * @author Andre Cunha + * + */ + +interface PLME_SET_TRX_STATE +{ +/*PLME_SET_TRX_STATE*/ + + async command error_t request(uint8_t state); + + async event error_t confirm(uint8_t status); + +} diff --git a/tos/lib/net/zigbee/ieee802154/interfaces/readme.txt b/tos/lib/net/zigbee/ieee802154/interfaces/readme.txt new file mode 100644 index 00000000..8e6858c3 --- /dev/null +++ b/tos/lib/net/zigbee/ieee802154/interfaces/readme.txt @@ -0,0 +1,16 @@ +Title: ZigBee +Author: André Cunha - IPP-HURRAY! http://www.open-zb.net +---------------------------------------------- + + +Notes: +------ +This folder contains the IEEE 802.15.4 and ZigBee network layer interfaces. + +Each interface represents a Service access point as specified in the standards. + +The interface files are organized as follows: + +nwk - includes the interfaces NLDE and NLME used to wire the NWL and the Upper application Layer +mac - includes the interfaces MCPS and MLME used to wire the Mac and the NWL +phy - includes the interfaces PD_DATA and PLME used to wire the Phy and the Mac \ No newline at end of file diff --git a/tos/lib/net/zigbee/ieee802154/mac/Mac.nc b/tos/lib/net/zigbee/ieee802154/mac/Mac.nc new file mode 100644 index 00000000..28da2de3 --- /dev/null +++ b/tos/lib/net/zigbee/ieee802154/mac/Mac.nc @@ -0,0 +1,114 @@ +/* + * @author IPP HURRAY http://www.hurray.isep.ipp.pt/art-wise + * @author Andre Cunha + * + */ + +#include + +configuration Mac { + + + //MLME + provides interface MLME_START; + provides interface MLME_SET; + provides interface MLME_GET; + + provides interface MLME_ASSOCIATE; + provides interface MLME_DISASSOCIATE; + + provides interface MLME_BEACON_NOTIFY; + provides interface MLME_GTS; + + provides interface MLME_ORPHAN; + + provides interface MLME_SYNC; + provides interface MLME_SYNC_LOSS; + + provides interface MLME_RESET; + + provides interface MLME_SCAN; + + //MCPS + provides interface MCPS_DATA; + provides interface MCPS_PURGE; + +} +implementation { + + components MainC; + MainC.SoftwareInit -> MacM; + + components LedsC; + components MacM; + + components Phy; + + components TimerAsyncC; + + MacM.TimerAsync ->TimerAsyncC; + + MacM.Leds -> LedsC; + + + MacM.AMControl ->Phy.SplitControl; + + components HplCC2420PinsC as Pins; + MacM.CCA -> Pins.CCA; + + components RandomC; + MacM.Random -> RandomC; + + components new TimerMilliC() as T_ackwait; + MacM.T_ackwait -> T_ackwait; + + components new TimerMilliC() as T_ResponseWaitTime; + MacM.T_ResponseWaitTime -> T_ResponseWaitTime; + + components new TimerMilliC() as T_ScanDuration; + MacM.T_ScanDuration -> T_ScanDuration; + + components CC2420ReceiveC; + MacM.AddressFilter -> CC2420ReceiveC; + + /*****************************************************/ + /* INTERFACES */ + /*****************************************************/ + MacM.PD_DATA -> Phy.PD_DATA; + MacM.PLME_ED ->Phy.PLME_ED; + MacM.PLME_CCA -> Phy.PLME_CCA; + MacM.PLME_SET -> Phy.PLME_SET; + MacM.PLME_GET -> Phy.PLME_GET; + MacM.PLME_SET_TRX_STATE -> Phy.PLME_SET_TRX_STATE; + + + //MLME interfaces + MLME_START=MacM; + + MLME_SET=MacM; + MLME_GET=MacM; + + MLME_ASSOCIATE=MacM; + MLME_DISASSOCIATE=MacM; + + MLME_BEACON_NOTIFY = MacM; + MLME_GTS=MacM; + + MLME_ORPHAN=MacM; + + MLME_SYNC=MacM; + MLME_SYNC_LOSS=MacM; + + MLME_RESET=MacM; + + MLME_SCAN=MacM; + + MCPS_DATA=MacM; + MCPS_PURGE=MacM; + + + + + +} + diff --git a/tos/lib/net/zigbee/ieee802154/mac/MacM.nc b/tos/lib/net/zigbee/ieee802154/mac/MacM.nc new file mode 100644 index 00000000..dc25d0f3 --- /dev/null +++ b/tos/lib/net/zigbee/ieee802154/mac/MacM.nc @@ -0,0 +1,5379 @@ +/* + * @author IPP HURRAY http://www.hurray.isep.ipp.pt/art-wise + * @author Andre Cunha + * + */ + +#include + +#include "printfUART.h" + +#include "frame_format.h" +#include "phy_const.h" + +#include "mac_const.h" +#include "mac_enumerations.h" + +#include "mac_func.h" + +module MacM { + + provides interface Init; + + provides interface MLME_START; + provides interface MLME_SET; + provides interface MLME_GET; + + provides interface MLME_ASSOCIATE; + provides interface MLME_DISASSOCIATE; + + provides interface MLME_BEACON_NOTIFY; + provides interface MLME_GTS; + + provides interface MLME_ORPHAN; + + provides interface MLME_SYNC; + provides interface MLME_SYNC_LOSS; + + provides interface MLME_RESET; + + provides interface MLME_SCAN; + + //MCPS + provides interface MCPS_DATA; + provides interface MCPS_PURGE; + + + uses interface Timer as T_ackwait; + + uses interface Timer as T_ResponseWaitTime; + + uses interface Timer as T_ScanDuration; + + uses interface Leds; + + uses interface SplitControl as AMControl; + + uses interface Random; + + uses interface GeneralIO as CCA; + + //uses interface Test_send; + + uses interface TimerAsync; + + uses interface PD_DATA; + + uses interface PLME_ED; + uses interface PLME_CCA; + uses interface PLME_SET; + uses interface PLME_GET; + uses interface PLME_SET_TRX_STATE; + + + uses interface AddressFilter; + + +} +implementation { + +/*****************************************************/ +/* GENERAL */ +/*****************************************************/ + /***************Variables*************************/ + //local extended address + uint32_t aExtendedAddress0; + uint32_t aExtendedAddress1; + + macPIB mac_PIB; + +//If the the MLME receives a start request the node becomes a pan coordinator + //and start transmiting beacons + bool PANCoordinator = 0; + //(0 NO beacon transmission; 1 beacon transmission); + bool Beacon_enabled_PAN = 0; + + //(RESET) when the reset command arrives it checks whether or not to reset the PIB + bool SetDefaultPIB=0; + + //use security + bool SecurityEnable=0; + + //others + bool pending_reset=0; + + //transceiver status -every time the transceiver changes state this variable is updated + uint8_t trx_status; + + //defines the transmission + bool beacon_enabled=0; + + /***************Functions Definition***************/ + + void init_MacPIB(); + + uint8_t min(uint8_t val1, uint8_t val2); + + void init_MacCon(); + + + task void signal_loss(); + + + void create_data_request_cmd(); + void create_beacon_request_cmd(); + void create_gts_request_cmd(uint8_t gts_characteristics); + + void build_ack(uint8_t sequence,uint8_t frame_pending); + + void create_data_frame(uint8_t SrcAddrMode, uint16_t SrcPANId, uint32_t SrcAddr[], uint8_t DstAddrMode, uint16_t DestPANId, uint32_t DstAddr[], uint8_t msduLength, uint8_t msdu[],uint8_t msduHandle, uint8_t TxOptions,uint8_t on_gts_slot,uint8_t pan); + + + + +/*****************************************************/ +/* Association */ +/*****************************************************/ + /***************Variables*************************/ + uint8_t associating = 0; + uint8_t association_cmd_seq_num =0; + + /*association parameters*/ + + uint8_t a_LogicalChannel; + uint8_t a_CoordAddrMode; + uint16_t a_CoordPANId; + uint32_t a_CoordAddress[2]; + uint8_t a_CapabilityInformation; + bool a_securityenable; + + /***************Functions Definition***************/ + + void create_association_request_cmd(uint8_t CoordAddrMode,uint16_t CoordPANId,uint32_t CoordAddress[],uint8_t CapabilityInformation); + + error_t create_association_response_cmd(uint32_t DeviceAddress[],uint16_t shortaddress, uint8_t status); + + void create_disassociation_notification_cmd(uint32_t DeviceAddress[],uint8_t disassociation_reason); + + void process_dissassociation_notification(MPDU *pdu); + +/*****************************************************/ +/* Synchronization */ +/*****************************************************/ + /***************Variables*************************/ + //(SYNC)the device will try to track the beacon ie enable its receiver just before the espected time of each beacon + bool TrackBeacon=0; + bool beacon_processed=0; + //beacon loss indication + uint8_t beacon_loss_reason; + + //(SYNC)the device will try to locate one beacon + bool findabeacon=0; + //(SYNC)number of beacons lost before sending a Beacon-Lost indication comparing to aMaxLostBeacons + uint8_t missed_beacons=0; + //boolean variable stating if the device is synchonized with the beacon or not + uint8_t on_sync=0; + + uint32_t parent_offset=0x00000000; + + +/*****************************************************/ +/* GTS Variables */ +/*****************************************************/ + /***************Variables*************************/ + + uint8_t gts_request=0; + uint8_t gts_request_seq_num=0; + + bool gts_confirm; + + uint8_t GTS_specification; + bool GTSCapability=1; + + uint8_t final_CAP_slot=15; + + //GTS descriptor variables, coordinator usage only + GTSinfoEntryType GTS_db[7]; + uint8_t GTS_descriptor_count=0; + uint8_t GTS_startslot=16; + uint8_t GTS_id=0x01; + + + //null gts descriptors + GTSinfoEntryType_null GTS_null_db[7]; + + uint8_t GTS_null_descriptor_count=0; + //uint8_t GTS_null_id=0x01; + + //node GTS variables + // 1 GTS for transmit + uint8_t s_GTSss=0; //send gts start slot + uint8_t s_GTS_length=0; //send gts length + //1 GTS for receive + uint8_t r_GTSss=0; //receive gts start slot + uint8_t r_GTS_length=0; //receive gts lenght + + //used to state that the device is on its transmit slot + uint8_t on_s_GTS=0; + //used to state that the device is on its receive slot + uint8_t on_r_GTS=0; + + //used to determine if the next time slot is used for transmission + uint8_t next_on_s_GTS=0; + //used to determine if the next time slot is used for reception + uint8_t next_on_r_GTS=0; + + //variable stating if the coordinator allow GTS allocations + uint8_t allow_gts=1; + + //COORDINATOR GTS BUFFER + gts_slot_element gts_slot_list[7]; + uint8_t available_gts_index[GTS_SEND_BUFFER_SIZE]; + uint8_t available_gts_index_count; + + uint8_t coordinator_gts_send_pending_data=0; + uint8_t coordinator_gts_send_time_slot=0; + + //gts buffer used to store the gts messages both in COORDINATOR and NON COORDINATOR + norace MPDU gts_send_buffer[GTS_SEND_BUFFER_SIZE]; + + //NON PAN COORDINATOR BUFFER + //buffering for sending + uint8_t gts_send_buffer_count=0; + uint8_t gts_send_buffer_msg_in=0; + uint8_t gts_send_buffer_msg_out=0; + uint8_t gts_send_pending_data=0; + + + /***************Functions Definition***************/ + + void process_gts_request(MPDU *pdu); + void init_available_gts_index(); + task void start_coordinator_gts_send(); + + + //GTS FUNCTIONS + error_t remove_gts_entry(uint16_t DevAddressType); + error_t add_gts_entry(uint8_t gts_length,bool direction,uint16_t DevAddressType); + error_t add_gts_null_entry(uint8_t gts_length,bool direction,uint16_t DevAddressType); + + //increment the idle GTS for GTS deallocation purposes, not fully implemented yet + task void increment_gts_null(); + + task void start_gts_send(); + + + + //initialization functions + void init_gts_slot_list(); + void init_GTS_null_db(); + + void init_GTS_db(); + + + uint32_t calculate_gts_expiration(); + task void check_gts_expiration(); + + +/*****************************************************/ +/* CHANNEL SCAN Variables */ +/*****************************************************/ + //current_channel + uint8_t current_channel=0; + + /***************Variables*************************/ + //ED-SCAN variables + + bool scanning_channels; + + uint32_t channels_to_scan; + uint8_t current_scanning=0; + //uint8_t scan_count=0; + uint8_t scanned_values[16]; + uint8_t scan_type; + + SCAN_PANDescriptor scan_pans[16]; + + uint16_t scan_duration; + + task void data_channel_scan_indication(); + +/*****************************************************/ +/* TIMER VARIABLES */ +/*****************************************************/ + /***************Variables*************************/ + uint32_t response_wait_time; + + //Beacon Interval + uint32_t BI; + //Superframe duration + uint32_t SD; + + //timer variables + uint32_t time_slot; //backoff boundary timer + uint32_t backoff; //backoff timer + + //current number of backoffs in the active period + uint8_t number_backoff=1; + uint8_t number_time_slot=0; + + bool csma_slotted=0; +/*****************************************************/ +/* CSMA VARIABLES */ +/*****************************************************/ + /***************Variables*************************/ + + //DEFERENCE CHANGE + uint8_t cca_deference = 0; + uint8_t backoff_deference = 0; + uint8_t check_csma_ca_backoff_send_conditions(uint32_t delay_backoffs); + + //STEP 2 + uint8_t delay_backoff_period; + bool csma_delay=0; + + bool csma_locate_backoff_boundary=0; + + bool csma_cca_backoff_boundary=0; + + //Although the receiver of the device is enabled during the channel assessment portion of this algorithm, the + //device shall discard any frames received during this time. + bool performing_csma_ca=0; + + //CSMA-CA variables + uint8_t BE; //backoff exponent + uint8_t CW; //contention window (number of backoffs to clear the channel) + uint8_t NB; //number of backoffs + + /***************Functions Definition***************/ + + void init_csma_ca(bool slotted); + void perform_csma_ca(); + task void perform_csma_ca_unslotted(); + task void perform_csma_ca_slotted(); + //task void start_csma_ca_slotted(); + +/*****************************************************/ +/* Indirect Transmission buffers */ +/*****************************************************/ + /***************Variables*************************/ + //indirect transmission buffer + norace indirect_transmission_element indirect_trans_queue[INDIRECT_BUFFER_SIZE]; + //indirect transmission message counter + uint8_t indirect_trans_count=0; + + /***************Functions Definition***************/ + + //function used to initialize the indirect transmission buffer + void init_indirect_trans_buffer(); + //function used to search and send an existing indirect transmission message + void send_ind_trans_addr(uint32_t DeviceAddress[]); + //function used to remove an existing indirect transmission message + error_t remove_indirect_trans(uint8_t handler); + //function used to increment the transaction persistent time on each message + //if the transaction time expires the messages are discarded + void increment_indirect_trans(); + +/*****************************************************/ +/* RECEIVE buffers */ +/*****************************************************/ + /***************Variables*************************/ + + //buffering variables + norace MPDU buffer_msg[RECEIVE_BUFFER_SIZE]; + int current_msg_in=0; + int current_msg_out=0; + int buffer_count=0; + + /***************Functions Definition***************/ + + task void data_indication(); + + void indication_cmd(MPDU *pdu, int8_t ppduLinkQuality); + void indication_ack(MPDU *pdu, int8_t ppduLinkQuality); + void indication_data(MPDU *pdu, int8_t ppduLinkQuality); +/*****************************************************/ +/* RECEPTION AND TRANSMISSION */ +/*****************************************************/ + + /***************Variables*************************/ + + //buffering for sending + norace MPDUBuffer send_buffer[SEND_BUFFER_SIZE]; + uint8_t send_buffer_count=0; + uint8_t send_buffer_msg_in=0; + uint8_t send_buffer_msg_out=0; + + //retransmission information + uint8_t send_ack_check;//ack requested in the transmitted frame + uint8_t retransmit_count;//retransmission count + uint8_t ack_sequence_number_check;//transmission sequence number + uint8_t send_retransmission; + uint8_t send_indirect_transmission; + + uint8_t pending_request_data=0; + + uint8_t ackwait_period; + + uint8_t link_quality; + + norace ACK mac_ack; + ACK *mac_ack_ptr; + + uint32_t gts_expiration; + + uint8_t I_AM_IN_CAP=0; + uint8_t I_AM_IN_CFP=0; + uint8_t I_AM_IN_IP=0; + + /***************Functions Definition***************/ + + task void send_frame_csma(); + + uint8_t check_csma_ca_send_conditions(uint8_t frame_length,uint8_t frame_control1); + + uint8_t check_gts_send_conditions(uint8_t frame_length); + + uint8_t calculate_ifs(uint8_t pk_length); + + + +/*****************************************************/ +/* BEACON MANAGEMENT */ +/*****************************************************/ + /***************Variables*************************/ + norace MPDU mac_beacon_txmpdu; + MPDU *mac_beacon_txmpdu_ptr; + + uint8_t *send_beacon_frame_ptr; + uint8_t send_beacon_length; + + /***************Functions Definition***************/ + /*function to create the beacon*/ + task void create_beacon(); + /*function to process the beacon information*/ + void process_beacon(MPDU *packet,uint8_t ppduLinkQuality); + + +/*****************************************************/ +/* Fault tolerance functions */ +/*****************************************************/ + + void create_coordinator_realignment_cmd(uint32_t device_extended0, uint32_t device_extended1, uint16_t device_short_address); + + void create_orphan_notification(); + + + + void process_coordinator_realignment(MPDU *pdu); + +/***************************DEBUG FUNCTIONS******************************/ +/* This function are list functions with the purpose of debug, to use then uncomment the declatarion +on top of this file*/ +/* + void list_mac_pib(); + + void list_gts(); + + void list_my_gts(); + void list_gts_null(); + */ + //list all the handles in the indirect transmission buffer, debug purposes + void list_indirect_trans_buffer(); + +/***************************END DEBUG FUNCTIONS******************************/ + + +/***************** Init Commands ****************/ + command error_t Init.init() { + + call AMControl.start(); + + + //initialization of the beacon structure + mac_beacon_txmpdu_ptr = &mac_beacon_txmpdu; + + + + atomic{ + //inicialize the mac PIB + init_MacPIB(); + + init_GTS_db(); + + init_GTS_null_db(); + + init_gts_slot_list(); + + init_available_gts_index(); + + aExtendedAddress0=TOS_NODE_ID; + aExtendedAddress1=TOS_NODE_ID; + + + call AddressFilter.set_address(mac_PIB.macShortAddress, aExtendedAddress0, aExtendedAddress1); + + call AddressFilter.set_coord_address(mac_PIB.macCoordShortAddress, mac_PIB.macPANId); + + + + + init_indirect_trans_buffer(); + + + } + + //beacon + mac_beacon_txmpdu_ptr = &mac_beacon_txmpdu; + + //ack + mac_ack_ptr = &mac_ack; + + //Other timers, sync timers units expressed in miliseconds + ackwait_period = ((mac_PIB.macAckWaitDuration * 4.0 ) / 250.0) * 3; + + response_wait_time = ((aResponseWaitTime * 4.0) / 250.0) * 2; + + atomic{ + + + BI = aBaseSuperframeDuration * powf(2,mac_PIB.macBeaconOrder); + SD = aBaseSuperframeDuration * powf(2,mac_PIB.macSuperframeOrder); + + + //backoff_period + backoff = aUnitBackoffPeriod; + //backoff_period_boundary + + time_slot = SD / NUMBER_TIME_SLOTS; + + call TimerAsync.set_enable_backoffs(1); + call TimerAsync.set_backoff_symbols(backoff); + + call TimerAsync.set_bi_sd(BI,SD); + + call TimerAsync.start(); + } + + +printfUART_init(); + + return SUCCESS; + } + + event void AMControl.startDone(error_t err) { + if (err == SUCCESS) { + + call TimerAsync.start(); + + } + else { + call AMControl.start(); + } + } + + event void AMControl.stopDone(error_t err) { + } + + +/*****************************************************/ +/* TIMERS FIRED */ +/*****************************************************/ + +async event error_t TimerAsync.before_bi_fired() +{ + ////printfUART("bbi %i\n",call TimerAsync.get_current_ticks()); + + if (mac_PIB.macBeaconOrder != mac_PIB.macSuperframeOrder ) + { + if ( Beacon_enabled_PAN == 1 ) + { + // + //post set_trx(); + trx_status = PHY_TX_ON; + call PLME_SET_TRX_STATE.request(PHY_TX_ON); + } + else + { + // + //post set_trx(); + trx_status = PHY_RX_ON; + call PLME_SET_TRX_STATE.request(PHY_RX_ON); + } + } + + //I_AM_IN_CAP = 1; + findabeacon = 1; + + return SUCCESS; +} + +/*******************Timer BEACON INTERVAL******************/ +async event error_t TimerAsync.bi_fired() +{ + call Leds.led2On(); + //call Test_send.send(); + + I_AM_IN_CAP = 1; + I_AM_IN_IP = 0; + + ////printfUART("bi\n",""); + + + if ( Beacon_enabled_PAN == 1 ) + { + //the beacon is send directly without CSMA/CA + call PD_DATA.request(send_beacon_length,send_beacon_frame_ptr); + } + + number_backoff =0; + number_time_slot=0; + + + //CHECK there is the need to wait a small amount of time before checking if the beacon as been processed or not + //possible solition, if it receives a packet stand by for confirmation it its a beacon + //The device must always receive the beacon + if (TrackBeacon == 1) + { + if (beacon_processed==1) + { + beacon_processed=0; + } + else + { + //dealocate all GTS + //beacon loss + + on_sync =0; + beacon_loss_reason = MAC_BEACON_LOSS; + + //TODO + //post signal_loss(); + } + } + + post send_frame_csma(); + + return SUCCESS; +} + +/*******************Timer SUPERFRAME DURATION******************/ +async event error_t TimerAsync.sd_fired() +{ + call Leds.led2Off(); + + ////printfUART("sd\n",""); + + I_AM_IN_CFP = 0; + I_AM_IN_IP = 1; + + + number_backoff=0; + number_time_slot=0; + + + if (PANCoordinator == 0 && TYPE_DEVICE == ROUTER) + { + trx_status = PHY_RX_ON; + + call PLME_SET_TRX_STATE.request(PHY_RX_ON); + } + else + { + trx_status = PHY_RX_ON; + + call PLME_SET_TRX_STATE.request(PHY_RX_ON); + + } + + if (mac_PIB.macShortAddress==0xffff && TYPE_DEVICE == END_DEVICE) + { + trx_status = PHY_RX_ON; + + call PLME_SET_TRX_STATE.request(PHY_RX_ON); + } + + //trx_status = PHY_RX_ON; + //post set_trx(); + /* + //turn the transceiver off + if (mac_PIB.macBeaconOrder != mac_PIB.macSuperframeOrder ) + { + if ( mac_PIB.macRxOnWhenIdle == 0 && findabeacon == 0) + { + trx_status = PHY_TRX_OFF; + post set_trx(); + } + else + { + trx_status = PHY_RX_ON; + post set_trx(); + } + } + //if the node is trying to synchronize + if (on_sync == 0 || mac_PIB.macPromiscuousMode == 1) + { + atomic{ + trx_status = PHY_RX_ON; + post set_trx(); + } + } + */ + if (PANCoordinator == 1) + { + //increment the gts_null descriptors + atomic{ + + //if (GTS_null_descriptor_count > 0) post increment_gts_null(); + + //if (GTS_descriptor_count >0 ) post check_gts_expiration(); + + //if (indirect_trans_count > 0) increment_indirect_trans(); + + //creation of the beacon + post create_beacon(); + } + //trx_status = PHY_TRX_OFF; + //post set_trx(); + } + else + { + //temporariamente aqui //atenção quando for para o cluster-tree é preciso mudar para fora + //e necessario destinguir ZC de ZR (que tem que manter a sync com o respectivo pai) + if (on_sync == 0) + { + //sync not ok + + //findabeacon=1; + if (missed_beacons == aMaxLostBeacons) + { + + //printfUART("sync_loss %i\n",missed_beacons); + //out of sync + post signal_loss(); + } + ////printfUART("out_sync %i\n",missed_beacons); + missed_beacons++; + call Leds.led1Off(); + + } + else + { + //sync ok + missed_beacons=0; + + on_sync=0; + } + + } + + //trx_status = PHY_TRX_OFF; + //call PLME_SET_TRX_STATE.request(PHY_TRX_OFF); + + return SUCCESS; +} + +/*******************Timer BEFORE TIME SLOT FIRED******************/ +async event error_t TimerAsync.before_time_slot_fired() +{ + on_s_GTS=0; + on_r_GTS=0; + + if (next_on_s_GTS == 1) + { + on_s_GTS=1; + next_on_s_GTS =0; + trx_status = PHY_TX_ON; + call PLME_SET_TRX_STATE.request(PHY_TX_ON); + //post set_trx(); + } + + if(next_on_r_GTS == 1) + { + on_r_GTS=1; + next_on_r_GTS=0; + trx_status = PHY_RX_ON; + call PLME_SET_TRX_STATE.request(PHY_RX_ON); + //post set_trx(); + } + +return SUCCESS; +} +/*******************Timer TIME SLOT FIRED******************/ +async event error_t TimerAsync.time_slot_fired() +{ + //reset the backoff counter and increment the slot boundary + number_backoff=0; + number_time_slot++; + + //verify is there is data to send in the GTS, and try to send it + if(PANCoordinator == 1 && GTS_db[15-number_time_slot].direction == 1 && GTS_db[15-number_time_slot].gts_id != 0) + { + //COORDINATOR SEND DATA + ////////////printfUART("bbck%i:%i:%i\n", (15-number_time_slot),GTS_db[15-number_time_slot].direction,gts_slot_list[15-number_time_slot].element_count); + + post start_coordinator_gts_send(); + + } + else + { + //DEVICE SEND DATA + if (number_time_slot == s_GTSss && gts_send_buffer_count > 0 && on_sync == 1)//(send_s_GTSss-send_s_GTS_len) + { + //current_time = call TimerAsync.get_total_tick_counter(); + post start_gts_send(); + } + } + + next_on_r_GTS =0; + next_on_s_GTS=0; + + + ////printfUART("ts%i %i %i\n", number_time_slot,s_GTSss,r_GTSss); + + + //verification if the time slot is entering the CAP + //GTS FIELDS PROCESSING + + if ((number_time_slot + 1) >= final_CAP_slot && (number_time_slot + 1) < 16) + { + I_AM_IN_CAP = 0; + I_AM_IN_CFP = 1; + + ////printfUART("bts %i\n",I_AM_IN_CAP, number_time_slot); + + atomic{ + + //verification of the next time slot + if(PANCoordinator == 1 && number_time_slot < 15) + { + //COORDINATOR verification of the next time slot + if(GTS_db[14-number_time_slot].gts_id != 0x00 && GTS_db[14-number_time_slot].DevAddressType != 0x0000) + { + if(GTS_db[14-number_time_slot].direction == 1 ) // device wants to receive + { + next_on_s_GTS =1; //PAN coord mode + } + else + { + next_on_r_GTS=1; //PAN coord mode + } + } + } + else + { + //device verification of the next time slot + if( (number_time_slot +1) == s_GTSss || (number_time_slot +1) == r_GTSss ) + { + ////printfUART("s_GTSss: %i r_GTSss: %i\n", s_GTSss,r_GTSss); + if((number_time_slot + 1) == s_GTSss) + { + ////printfUART("MY SEND SLOT \n", ""); + next_on_s_GTS =1; + s_GTS_length --; + if (s_GTS_length != 0 ) + { + s_GTSss++; + } + } + else + { + //////////////printfUART("MY RECEIVE SLOT \n", ""); + next_on_r_GTS =1; + r_GTS_length --; + if (r_GTS_length != 0 ) + { + r_GTSss++; + } + } + } + else + { + //idle + next_on_s_GTS=0; + next_on_r_GTS=0; + } + } + } + } + +return SUCCESS; +} +async event error_t TimerAsync.sfd_fired() +{ + +return SUCCESS; +} + +/*******************Timer BACKOFF PERIOD******************/ +async event error_t TimerAsync.backoff_fired() +{ + //slotted CSMA/CA function + atomic{ + + if( csma_locate_backoff_boundary == 1 ) + { + csma_locate_backoff_boundary=0; + + //post start_csma_ca_slotted(); + + //DEFERENCE CHANGE + if (backoff_deference == 0) + { + //normal situation + delay_backoff_period = (call Random.rand16() & ((uint8_t)(powf(2,BE)) - 1)); + + if (check_csma_ca_backoff_send_conditions((uint32_t) delay_backoff_period) == 1) + { + backoff_deference = 1; + } + + } + else + { + backoff_deference = 0; + } + + csma_delay=1; + } + if( csma_cca_backoff_boundary == 1 ) + post perform_csma_ca_slotted(); + } + //CSMA/CA + atomic{ + if(csma_delay == 1 ) + { + if (delay_backoff_period == 0) + { + if(csma_slotted == 0) + { + post perform_csma_ca_unslotted(); + } + else + { + //CSMA/CA SLOTTED + csma_delay=0; + csma_cca_backoff_boundary=1; + } + } + delay_backoff_period--; + } + } + number_backoff++; +return SUCCESS; +} + +/*******************T_ackwait**************************/ + event void T_ackwait.fired() { + + //////////printfUART("Tfd \n", ""); + + //call Leds.redToggle(); + + if (send_ack_check == 1) + { + retransmit_count++; + + if (retransmit_count == aMaxFrameRetries || send_indirect_transmission > 0) + { + //check the type of data being send + /* + if (associating == 1) + { + //printfUART("af ack\n", ""); + associating=0; + signal MLME_ASSOCIATE.confirm(0x0000,MAC_NO_ACK); + } + */ + + atomic{ + ////////////printfUART("TRANSMISSION FAIL\n",""); + //stardard procedure, if fail discard the packet + atomic send_buffer_count --; + send_buffer_msg_out++; + + //failsafe + if(send_buffer_count > SEND_BUFFER_SIZE) + { + + atomic send_buffer_count =0; + send_buffer_msg_out=0; + send_buffer_msg_in=0; + + } + + + if (send_buffer_msg_out == SEND_BUFFER_SIZE) + send_buffer_msg_out=0; + + if (send_buffer_count > 0) + post send_frame_csma(); + + send_ack_check=0; + retransmit_count=0; + ack_sequence_number_check=0; + + } + } + + ////////////printfUART("RETRY\n",""); + //retransmissions + post send_frame_csma(); + } + + } + +/*******************T_ResponseWaitTime**************************/ + event void T_ResponseWaitTime.fired() { + //command response wait time + ////////////printfUART("T_ResponseWaitTime.fired\n", ""); + + if (associating == 1) + { + //printfUART("af rwt\n", ""); + associating=0; + signal MLME_ASSOCIATE.confirm(0x0000,MAC_NO_DATA); + + } + + } + +/***************************************************** +****************PD_DATA EVENTS*********************** +******************************************************/ + async event error_t PD_DATA.confirm(uint8_t status) { + + + return SUCCESS; + } + +/***************************************************** +**************** PD_DATA ******************** +******************************************************/ + +async event error_t PD_DATA.indication(uint8_t psduLenght,uint8_t* psdu, int8_t ppduLinkQuality){ + + //if(I_AM_IN_CAP == 1 || I_AM_IN_CFP == 1 || mac_PIB.macShortAddress==0xffff || scanning_channels ==1 || findabeacon == 1) + //{ + if (buffer_count > RECEIVE_BUFFER_SIZE) + { + //call Leds.redToggle(); + //printfUART("full\n",""); + } + else + { + + memcpy(&buffer_msg[current_msg_in],psdu,sizeof(MPDU)); + + atomic{ + current_msg_in++; + + if ( current_msg_in == RECEIVE_BUFFER_SIZE ) + current_msg_in = 0; + + buffer_count ++; + } + + link_quality = ppduLinkQuality; + + if (scanning_channels ==1) + { + //channel scan operation, accepts beacons only + post data_channel_scan_indication(); + + } + else + { + //normal operation + post data_indication(); + } + } + //} + //else + //{ + // //printfUART("drop\n",""); + //} + +return SUCCESS; +} + + + +task void data_indication() +{ + //check all the conditions for a receiver packet + //pag 155 + + uint8_t link_qual; + + atomic link_qual = link_quality; + + ////printfUART("data_indication\n",""); + //////////printfUART("buf %i %i\n",buffer_count,indirect_trans_count); + + //Although the receiver of the device is enabled during the channel assessment portion of this algorithm, the + //device shall discard any frames received during this time. + //////////////printfUART("performing_csma_ca: %i\n",performing_csma_ca); + if (performing_csma_ca == 1) + { + //////////////printfUART("REJ CSMA\n",""); + atomic{ + buffer_count--; + + current_msg_out++; + if ( current_msg_out == RECEIVE_BUFFER_SIZE ) + current_msg_out = 0; + } + + return; + } + + //while performing channel scan disable the packet reception + if ( scanning_channels == 1) + { + atomic{ + buffer_count--; + + current_msg_out++; + if ( current_msg_out == RECEIVE_BUFFER_SIZE ) + current_msg_out = 0; + } + return; + } +atomic{ + + //////printfUART("data ind %x %x %i\n",buffer_msg[current_msg_out].frame_control1,buffer_msg[current_msg_out].frame_control2,(buffer_msg[current_msg_out].frame_control2 & 0x7)); + + //check the frame type of the received packet + switch( (buffer_msg[current_msg_out].frame_control1 & 0x7) ) + { + + case TYPE_DATA: ////printfUART("rd %i\n",buffer_msg[current_msg_out].seq_num); + indication_data(&buffer_msg[current_msg_out],link_qual); + break; + + case TYPE_ACK: ////printfUART("ra\n",""); + //ack_received = 1; + indication_ack(&buffer_msg[current_msg_out],link_qual); + + break; + + case TYPE_CMD: ////printfUART("rc\n",""); + indication_cmd(&buffer_msg[current_msg_out],link_qual); + break; + + case TYPE_BEACON: + + ////printfUART("rb %i\n",buffer_msg[current_msg_out].seq_num); + if (mac_PIB.macShortAddress == 0x0000) + { + buffer_count--; + } + else + { + process_beacon(&buffer_msg[current_msg_out],link_qual); + + } + + break; + default: + atomic buffer_count--; + //////printfUART("Invalid frame type\n",""); + + break; + } + atomic{ + current_msg_out++; + if ( current_msg_out == RECEIVE_BUFFER_SIZE ) + current_msg_out = 0; + } + } + return; +} + + + +/***************************************************** +****************PLME_ED EVENTS*********************** +******************************************************/ +event error_t PLME_CCA.confirm(uint8_t status){ +return SUCCESS; +} + + +event error_t PLME_SET.confirm(uint8_t status, uint8_t PIBAttribute){ +return SUCCESS; +} + +async event error_t PLME_SET_TRX_STATE.confirm(uint8_t status){ + +return SUCCESS; +} + +event error_t PLME_GET.confirm(uint8_t status,uint8_t PIBAttribute, uint8_t PIBAttributeValue){ + +return SUCCESS; +} + +event error_t PLME_ED.confirm(uint8_t status,int8_t EnergyLevel){ + +return SUCCESS; +} + +/*******************************************************************************************************/ +/*******************************************************************************************************/ +/*******************************************************************************************************/ +/****************************************PACKET PROCESSING FUNCTIONS************************************/ +/*******************************************************************************************************/ +/*******************************************************************************************************/ +/*******************************************************************************************************/ + +void process_beacon(MPDU *packet,uint8_t ppduLinkQuality) +{ + + /* + ORGANIZE THE PROCESS BEACON FUNCION AS FOLLOWS. + 1- GET THE BEACON ORDER + 2- GET THE SUPERFRAME ORDER + 3- GET THE FINAL CAP SLOT + 4 - COMPUTE SD, BI, TS, BACKOFF PERIOD IN MILLISECONDS + + 4- SYNCHRONIZE THE NODE BY DOING THE FOLLOWING + - SET A TIMER IN MS FOR THE FINAL TIME SLOT (SUPERFRAME DURATION) : IT EXPRIES AFTER SD - TX TIME - PROCESS TIME + - SET A TIMER IN MS FOR THE GTS IF ANY EXIST IT EXPRIES AFTER GTS_NBR * TIME_SLOT - TX TIME - PROCESS TIME + */ + uint32_t SO_EXPONENT; + uint32_t BO_EXPONENT; + int i=0; + uint16_t gts_descriptor_addr; + uint8_t data_count; + + uint8_t gts_directions; + uint8_t gts_des_count; + + uint8_t gts_ss; + uint8_t gts_l; + uint8_t dir; + uint8_t dir_mask; + + //end gts variables + + //function that processes the received beacon + beacon_addr_short *beacon_ptr; + + PANDescriptor pan_descriptor; + + // beacon_trans_delay = (((packet->length(bytes) * 8.0) / 250.00(bits/s) ) / 0.34(s) (timer_granularity) ) (symbols) + + //pending frames + uint8_t short_addr_pending=0; + uint8_t long_addr_pending=0; + + //used in the synchronization + //uint32_t process_tick_counter; //symbols + + //uint32_t becon_trans_delay; //symbols + //uint32_t start_reset_ct; //number of clock ticks since the start of the beacon interval + + //used in the track beacon + beacon_processed = 1; + missed_beacons=0; + + //initializing pointer to data structure + beacon_ptr = (beacon_addr_short*) (packet->data); + + + //decrement buffer count + atomic buffer_count --; + + ////printfUART("Received Beacon\n",""); + ////printfUART("rb panid: %x %x \n",beacon_ptr->source_address,mac_PIB.macCoordShortAddress); + ////////printfUART("My macPANID: %x\n",mac_PIB.macPANId); + + if( beacon_ptr->source_address != mac_PIB.macCoordShortAddress) + { + // + return; + } + ////printfUART("bea %i\n",call TimerAsync.get_current_ticks()); + + /**********************************************************************************/ + /* PROCESSING THE SUPERFRAME STRUCTURE */ + /**********************************************************************************/ + + if (PANCoordinator == 0) + { + mac_PIB.macBeaconOrder = get_beacon_order(beacon_ptr->superframe_specification); + mac_PIB.macSuperframeOrder = get_superframe_order(beacon_ptr->superframe_specification); + + //mac_PIB.macCoordShortAddress = beacon_ptr->source_address; + + ////printfUART("BO,SO:%i %i\n",mac_PIB.macBeaconOrder,mac_PIB.macSuperframeOrder); + + //mac_PIB.macPANId = beacon_ptr->source_PAN_identifier; + + //beacon order check if it changed + if (mac_PIB.macSuperframeOrder == 0) + { + SO_EXPONENT = 1; + } + else + { + SO_EXPONENT = powf(2,mac_PIB.macSuperframeOrder); + } + + if ( mac_PIB.macBeaconOrder ==0) + { + BO_EXPONENT =1; + } + else + { + BO_EXPONENT = powf(2,mac_PIB.macBeaconOrder); + } + BI = aBaseSuperframeDuration * BO_EXPONENT; + SD = aBaseSuperframeDuration * SO_EXPONENT; + + //backoff_period + backoff = aUnitBackoffPeriod; + time_slot = SD / NUMBER_TIME_SLOTS; + + call TimerAsync.set_bi_sd(BI,SD); + } + + /**********************************************************************************/ + /* PROCESS GTS CHARACTERISTICS */ + /**********************************************************************************/ + allow_gts =1; + + //initializing the gts variables + s_GTSss=0; + s_GTS_length=0; + + r_GTSss=0; + r_GTS_length=0; + + /* + send_s_GTSss=0; + send_r_GTSss=0; + send_s_GTS_len=0; + send_r_GTS_len=0; + */ + final_CAP_slot = 15; + + + gts_des_count = (packet->data[8] & 0x0f); + + data_count = 9; + + final_CAP_slot = 15 - gts_des_count; + + if (gts_des_count > 0 ) + { + data_count = 10; //position of the current data count + //process descriptors + + gts_directions = packet->data[9]; + + ////printfUART("gts_directions:%x\n",gts_directions); + + for(i=0; i< gts_des_count; i++) + { + gts_descriptor_addr = (uint16_t) packet->data[data_count]; + + ////printfUART("gts_des_addr:%x mac short:%x\n",gts_descriptor_addr,mac_PIB.macShortAddress); + + data_count = data_count+2; + //check if it concerns me + if (gts_descriptor_addr == mac_PIB.macShortAddress) + { + //confirm the gts request + //////////////printfUART("packet->data[data_count]: %x\n",packet->data[data_count]); + //gts_ss = 15 - get_gts_descriptor_ss(packet->data[data_count]); + gts_ss = get_gts_descriptor_ss(packet->data[data_count]); + gts_l = get_gts_descriptor_len(packet->data[data_count]); + + if ( i == 0 ) + { + dir_mask=1; + } + else + { + + dir_mask = powf(2,i); + } + //////////////printfUART("dir_mask: %x i: %x gts_directions: %x \n",dir_mask,i,gts_directions); + dir = ( gts_directions & dir_mask); + if (dir == 0) + { + s_GTSss=gts_ss; + s_GTS_length=gts_l; + } + else + { + + r_GTSss=gts_ss; + r_GTS_length=gts_l; + } + + ////printfUART("PB gts_ss: %i gts_l: %i dir: %i \n",gts_ss,gts_l,dir); + //////////////printfUART("PB send_s_GTSss: %i send_s_GTS_len: %i\n",send_s_GTSss,send_s_GTS_len); + + if ( gts_l == 0 ) + { + allow_gts=0; + } + + if (gts_confirm == 1 && gts_l != 0) + { + //signal ok + ////printfUART("gts confirm \n",""); + gts_confirm =0; + signal MLME_GTS.confirm(GTS_specification,MAC_SUCCESS); + } + else + { + //signal not ok + //////////////printfUART("gts not confirm \n",""); + gts_confirm =0; + signal MLME_GTS.confirm(GTS_specification,MAC_DENIED); + } + + } + data_count++; + } + } + + /**********************************************************************************/ + /* PROCESS PENDING ADDRESSES INFORMATION */ + /**********************************************************************************/ + //this should pass to the network layer + + + short_addr_pending=get_number_short(packet->data[data_count]); + long_addr_pending=get_number_extended(packet->data[data_count]); + + ////////////printfUART("ADD COUNT %i %i\n",short_addr_pending,long_addr_pending); + + data_count++; + + if(short_addr_pending > 0) + { + for(i=0;i < short_addr_pending;i++) + { + ////////////printfUART("PB %i %i\n",(uint16_t)packet->data[data_count],short_addr_pending); + + //if(packet->data[data_count] == (uint8_t)mac_PIB.macShortAddress && packet->data[data_count+1] == (uint8_t)(mac_PIB.macShortAddress >> 8) ) + if((uint16_t)packet->data[data_count] == mac_PIB.macShortAddress) + { + + create_data_request_cmd(); + } + data_count = data_count + 2; + } + } + if(long_addr_pending > 0) + { + for(i=0; i < long_addr_pending;i++) + { + if((uint32_t)packet->data[data_count] == aExtendedAddress0 && (uint32_t)packet->data[data_count + 4] == aExtendedAddress1) + { + + data_count = data_count + 8; + + } + + } + } + + /**********************************************************************************/ + /* BUILD the PAN descriptor of the COORDINATOR */ + /**********************************************************************************/ + + + //Beacon NOTIFICATION + //BUILD the PAN descriptor of the COORDINATOR + //assuming that the adress is short + pan_descriptor.CoordAddrMode = SHORT_ADDRESS; + pan_descriptor.CoordPANId = 0x0000;//beacon_ptr->source_PAN_identifier; + pan_descriptor.CoordAddress0=0x00000000; + pan_descriptor.CoordAddress1=mac_PIB.macCoordShortAddress; + pan_descriptor.LogicalChannel=current_channel; + //superframe specification field + pan_descriptor.SuperframeSpec = beacon_ptr->superframe_specification; + + pan_descriptor.GTSPermit=mac_PIB.macGTSPermit; + pan_descriptor.LinkQuality=0x00; + pan_descriptor.TimeStamp=0x000000; + pan_descriptor.SecurityUse=0; + pan_descriptor.ACLEntry=0x00; + pan_descriptor.SecurityFailure=0x00; + + //I_AM_IN_CAP = 1; + + /**********************************************************************************/ + /* SYNCHRONIZING */ + /**********************************************************************************/ + + //processing time + beacon transmission delay + + //removed not used + //process_tick_counter = call TimerAsync.get_process_frame_tick_counter(); + //removed not used + //start_reset_ct = ((1000 * (packet->length * 8.0) / 250)) / 69.54; //(process_tick_counter - receive_tick_counter); + + if(PANCoordinator == 0) + { + I_AM_IN_CAP = 1; + I_AM_IN_IP = 0; + + //call Leds.yellowOn(); + call Leds.led2On(); + + call Leds.led1On(); + + if(findabeacon == 1) + { + ////printfUART("findabeacon\n", ""); + call TimerAsync.set_timers_enable(1); + findabeacon =0; + } + + //#ifdef PLATFORM_MICAZ + //number_time_slot = call TimerAsync.reset_start(start_reset_ct+process_tick_counter+52);// //SOBI=3 52 //SOBI=0 15 + //#else + + //call TimerAsync.reset(); + + number_time_slot = call TimerAsync.reset_start(75); //95 old val sem print + + // +process_tick_counter+52 //SOBI=3 52 //SOBI=0 + //#endif + on_sync=1; + + ////printfUART("sED\n", ""); + } + signal MLME_BEACON_NOTIFY.indication((uint8_t)packet->seq_num,pan_descriptor,0, 0, mac_PIB.macBeaconPayloadLenght, packet->data); + +return; +} + + +void process_gts_request(MPDU *pdu) +{ + error_t status; + cmd_gts_request *mac_gts_request; + + mac_gts_request= (cmd_gts_request*) &pdu->data; + +atomic{ + if ( get_characteristic_type(mac_gts_request->gts_characteristics) == 1) + { + //allocation + + //process the gts request + status = add_gts_entry(get_gts_length(mac_gts_request->gts_characteristics),get_gts_direction(mac_gts_request->gts_characteristics),mac_gts_request->source_address); + + } + else + { + //dealocation + + status = remove_gts_entry(mac_gts_request->source_address); + } + + signal MLME_GTS.indication(mac_gts_request->source_address, mac_gts_request->gts_characteristics, 0, 0); + + } + +return; +} +/****************DATA indication functions******************/ + +void indication_data(MPDU *pdu, int8_t ppduLinkQuality) +{ + uint8_t data_len; + + uint8_t payload[80]; + uint8_t msdu_length=0; + + //int i; + + uint32_t SrcAddr[2]; + uint32_t DstAddr[2]; + + + //frame control variables + uint8_t source_address=0; + uint8_t destination_address=0; + + + dest_short *dest_short_ptr; + dest_long *dest_long_ptr; + + source_short *source_short_ptr; + source_long *source_long_ptr; + + //implement the intra PAN data messages + //intra_pan_source_short *intra_pan_source_short_ptr; + //intra_pan_source_long *intra_pan_source_long_ptr; + + + source_address=get_fc2_source_addr(pdu->frame_control2); + destination_address=get_fc2_dest_addr(pdu->frame_control2); + + //decrement buffer count + atomic buffer_count --; + + SrcAddr[0]=0x00000000; + SrcAddr[1]=0x00000000; + DstAddr[0]=0x00000000; + DstAddr[1]=0x00000000; + + + ////printfUART("id %i %i \n",source_address,destination_address); + + + if ( get_fc1_intra_pan(pdu->frame_control1)== 0 ) + { + //INTRA PAN + if (destination_address > 1 && source_address > 1) + { + // Destination LONG - Source LONG + if (destination_address == LONG_ADDRESS && source_address == LONG_ADDRESS) + { + dest_long_ptr = (dest_long *) &pdu->data[0]; + source_long_ptr = (source_long *) &pdu->data[DEST_LONG_LEN]; + + //If a short destination address is included in the frame, it shall match either macShortAddress or the + //broadcast address (0 x ffff). Otherwise, if an extended destination address is included in the frame, it + //shall match aExtendedAddress. + if ( dest_long_ptr->destination_address0 !=aExtendedAddress0 && dest_long_ptr->destination_address1 !=aExtendedAddress1 ) + { + ////////////printfUART("data rejected, ext destination not for me\n", ""); + return; + } + //If a destination PAN identifier is included in the frame, it shall match macPANId or shall be the + //broadcast PAN identifier (0 x ffff). + if(dest_long_ptr->destination_PAN_identifier != 0xffff && dest_long_ptr->destination_PAN_identifier != mac_PIB.macPANId ) + { + ////////////printfUART("data rejected, wrong destination PAN\n", ""); + return; + } + data_len = 20; + + + DstAddr[1] = dest_long_ptr->destination_address0; + DstAddr[0] =dest_long_ptr->destination_address1; + + SrcAddr[1] =source_long_ptr->source_address0; + SrcAddr[0] =source_long_ptr->source_address1; + + msdu_length = pdu->length - data_len; + + memcpy(&payload,&pdu->data[data_len],msdu_length * sizeof(uint8_t)); + + signal MCPS_DATA.indication((uint16_t)source_address, (uint16_t)source_long_ptr->source_PAN_identifier, SrcAddr,(uint16_t)destination_address, (uint16_t)dest_long_ptr->destination_PAN_identifier, DstAddr, (uint16_t)msdu_length, payload, (uint16_t)ppduLinkQuality, 0x0000,0x0000); + + } + + // Destination SHORT - Source LONG + if ( destination_address == SHORT_ADDRESS && source_address == LONG_ADDRESS ) + { + dest_short_ptr = (dest_short *) &pdu->data[0]; + source_long_ptr = (source_long *) &pdu->data[DEST_SHORT_LEN]; + + //If a short destination address is included in the frame, it shall match either macShortAddress or the + //broadcast address (0 x ffff). Otherwise, if an extended destination address is included in the frame, it + //shall match aExtendedAddress. + if ( dest_short_ptr->destination_address != 0xffff && dest_short_ptr->destination_address != mac_PIB.macShortAddress) + { + ////////////printfUART("data rejected, short destination not for me\n", ""); + return; + } + //If a destination PAN identifier is included in the frame, it shall match macPANId or shall be the + //broadcast PAN identifier (0 x ffff). + if(dest_short_ptr->destination_PAN_identifier != 0xffff && dest_short_ptr->destination_PAN_identifier != mac_PIB.macPANId ) + { + ////////////printfUART("data rejected, wrong destination PAN\n", ""); + return; + } + + data_len = 14; + + DstAddr[0] =dest_short_ptr->destination_address; + + SrcAddr[1] =source_long_ptr->source_address0; + SrcAddr[0] =source_long_ptr->source_address1; + + msdu_length = pdu->length - data_len; + + memcpy(&payload,&pdu->data[data_len],msdu_length * sizeof(uint8_t)); + + signal MCPS_DATA.indication((uint16_t)source_address, (uint16_t)source_long_ptr->source_PAN_identifier, SrcAddr,(uint16_t)destination_address, (uint16_t)dest_short_ptr->destination_PAN_identifier, DstAddr, (uint16_t)msdu_length, payload, (uint16_t)ppduLinkQuality, 0x0000,0x0000); + + } + // Destination LONG - Source SHORT + if ( destination_address == LONG_ADDRESS && source_address == SHORT_ADDRESS ) + { + dest_long_ptr = (dest_long *) &pdu->data[0]; + source_short_ptr = (source_short *) &pdu->data[DEST_LONG_LEN]; + + //If a short destination address is included in the frame, it shall match either macShortAddress or the + //broadcast address (0 x ffff). Otherwise, if an extended destination address is included in the frame, it + //shall match aExtendedAddress. + if ( dest_long_ptr->destination_address0 !=aExtendedAddress0 && dest_long_ptr->destination_address1 !=aExtendedAddress1 ) + { + ////////////printfUART("data rejected, ext destination not for me\n", ""); + return; + } + //If a destination PAN identifier is included in the frame, it shall match macPANId or shall be the + //broadcast PAN identifier (0 x ffff). + if(dest_long_ptr->destination_PAN_identifier != 0xffff && dest_long_ptr->destination_PAN_identifier != mac_PIB.macPANId ) + { + ////////////printfUART("data rejected, wrong destination PAN\n", ""); + return; + } + + data_len = 14; + + DstAddr[1] = dest_long_ptr->destination_address0; + DstAddr[0] =dest_long_ptr->destination_address1; + + + SrcAddr[0] =source_short_ptr->source_address; + + msdu_length = pdu->length - data_len; + + memcpy(&payload,&pdu->data[data_len],msdu_length * sizeof(uint8_t)); + + signal MCPS_DATA.indication((uint16_t)source_address, (uint16_t)source_short_ptr->source_PAN_identifier, SrcAddr,(uint16_t)destination_address, (uint16_t)dest_long_ptr->destination_PAN_identifier, DstAddr, (uint16_t)msdu_length, payload, (uint16_t)ppduLinkQuality, 0x0000,0x0000); + + } + + + //Destination SHORT - Source SHORT + if ( destination_address == SHORT_ADDRESS && source_address == SHORT_ADDRESS ) + { + dest_short_ptr = (dest_short *) &pdu->data[0]; + source_short_ptr = (source_short *) &pdu->data[DEST_SHORT_LEN]; + + //If a short destination address is included in the frame, it shall match either macShortAddress or the + //broadcast address (0 x ffff). Otherwise, if an extended destination address is included in the frame, it + //shall match aExtendedAddress. + if ( dest_short_ptr->destination_address != 0xffff && dest_short_ptr->destination_address != mac_PIB.macShortAddress) + { + ////printfUART("data rejected, short destination not for me\n", ""); + return; + } + //If a destination PAN identifier is included in the frame, it shall match macPANId or shall be the + //broadcast PAN identifier (0 x ffff). + if(dest_short_ptr->destination_PAN_identifier != 0xffff && dest_short_ptr->destination_PAN_identifier != mac_PIB.macPANId ) + { + ////printfUART("SH SH data rejected, wrong destination PAN %x\n",mac_PIB.macPANId ); + return; + } + + data_len = 8; + + if ( get_fc1_ack_request(pdu->frame_control1) == 1 ) + { + build_ack(pdu->seq_num,0); + } + + DstAddr[0] =dest_short_ptr->destination_address; + + SrcAddr[0] =source_short_ptr->source_address; + + msdu_length = (pdu->length - 5) - data_len; + + + memcpy(&payload,&pdu->data[data_len],msdu_length * sizeof(uint8_t)); + + signal MCPS_DATA.indication((uint16_t)source_address, (uint16_t)source_short_ptr->source_PAN_identifier, SrcAddr,(uint16_t)destination_address, (uint16_t)dest_short_ptr->destination_PAN_identifier, DstAddr, (uint16_t)msdu_length,payload, (uint16_t)ppduLinkQuality, 0x0000,0x0000); + + } + } + + /*********NO DESTINATION ADDRESS PRESENT ****************/ + + if ( destination_address == 0 && source_address > 1 ) + { + + if (source_address == LONG_ADDRESS) + {//Source LONG + source_long_ptr = (source_long *) &pdu->data[0]; + + //If only source addressing fields are included in a data or MAC command frame, the frame shall be + //accepted only if the device is a PAN coordinator and the source PAN identifier matches macPANId. + if ( PANCoordinator==0 || source_long_ptr->source_PAN_identifier != mac_PIB.macPANId ) + { + ////////////printfUART("data rejected, im not pan\n", ""); + return; + } + + data_len = 10; + + SrcAddr[1] =source_long_ptr->source_address0; + SrcAddr[0] =source_long_ptr->source_address1; + + msdu_length = pdu->length - data_len; + + memcpy(&payload,&pdu->data[data_len],msdu_length * sizeof(uint8_t)); + + signal MCPS_DATA.indication((uint16_t)source_address,(uint16_t)source_long_ptr->source_PAN_identifier, SrcAddr,(uint16_t)destination_address, 0x0000, DstAddr, (uint16_t)msdu_length, payload, (uint16_t)ppduLinkQuality, 0x0000,0x0000); + + } + else + {//Source SHORT + + source_short_ptr = (source_short *) &pdu->data[0]; + //If only source addressing fields are included in a data or MAC command frame, the frame shall be + //accepted only if the device is a PAN coordinator and the source PAN identifier matches macPANId. + if ( PANCoordinator==0 || source_short_ptr->source_PAN_identifier != mac_PIB.macPANId ) + { + ////////////printfUART("data rejected, im not pan\n", ""); + return; + } + + data_len = 4; + + + SrcAddr[0] =source_short_ptr->source_address; + + msdu_length = pdu->length - data_len; + + memcpy(&payload,&pdu->data[data_len],msdu_length * sizeof(uint8_t)); + + signal MCPS_DATA.indication((uint16_t)source_address, (uint16_t)source_short_ptr->source_PAN_identifier, SrcAddr,(uint16_t)destination_address, 0x0000, DstAddr, (uint16_t)msdu_length, payload, (uint16_t)ppduLinkQuality, 0x0000,0x0000); + + } + } + /*********NO SOURCE ADDRESS PRESENT ****************/ + + if ( destination_address > 1 && source_address == 0 ) + { + if (destination_address == LONG_ADDRESS) + {//Destination LONG + dest_long_ptr = (dest_long *) &pdu->data[0]; + + //If a short destination address is included in the frame, it shall match either macShortAddress or the + //broadcast address (0 x ffff). Otherwise, if an extended destination address is included in the frame, it + //shall match aExtendedAddress. + if ( dest_long_ptr->destination_address0 !=aExtendedAddress0 && dest_long_ptr->destination_address1 !=aExtendedAddress1 ) + { + ////////////printfUART("data rejected, ext destination not for me\n", ""); + return; + } + //If a destination PAN identifier is included in the frame, it shall match macPANId or shall be the + //broadcast PAN identifier (0 x ffff). + if(dest_long_ptr->destination_PAN_identifier != 0xffff && dest_long_ptr->destination_PAN_identifier != mac_PIB.macPANId ) + { + ////////////printfUART("data rejected, wrong destination PAN\n", ""); + return; + } + + data_len = 10; + + DstAddr[1] = dest_long_ptr->destination_address0; + DstAddr[0] =dest_long_ptr->destination_address1; + + msdu_length = pdu->length - data_len; + + memcpy(&payload,&pdu->data[data_len],msdu_length * sizeof(uint8_t)); + + signal MCPS_DATA.indication((uint16_t)source_address,0x0000, SrcAddr,(uint16_t)destination_address, (uint16_t)dest_long_ptr->destination_PAN_identifier, DstAddr, (uint16_t)msdu_length, payload, (uint16_t)ppduLinkQuality, 0x0000,0x0000); + + } + else + {//Destination SHORT + dest_short_ptr = (dest_short *) &pdu->data[0]; + + //If a short destination address is included in the frame, it shall match either macShortAddress or the + //broadcast address (0 x ffff). Otherwise, if an extended destination address is included in the frame, it + //shall match aExtendedAddress. + if ( dest_short_ptr->destination_address != 0xffff && dest_short_ptr->destination_address != mac_PIB.macShortAddress) + { + ////////////printfUART("data rejected, short destination not for me\n", ""); + return; + } + //If a destination PAN identifier is included in the frame, it shall match macPANId or shall be the + //broadcast PAN identifier (0 x ffff). + if(dest_short_ptr->destination_PAN_identifier != 0xffff && dest_short_ptr->destination_PAN_identifier != mac_PIB.macPANId ) + { + ////////////printfUART("data rejected, wrong destination PAN\n", ""); + return; + } + + data_len = 4; + + DstAddr[0] =dest_short_ptr->destination_address; + + msdu_length = pdu->length - data_len; + + memcpy(&payload,&pdu->data[data_len],msdu_length * sizeof(uint8_t)); + + + signal MCPS_DATA.indication((uint16_t)source_address,0x0000, SrcAddr,(uint16_t)destination_address, (uint16_t)dest_short_ptr->destination_PAN_identifier, DstAddr, (uint16_t)msdu_length, payload, (uint16_t)ppduLinkQuality, 0x0000,0x0000); + + data_len = 4; + } + } + + } + else + { + //intra_pan == 1 + + + + } + + +return; +} + +void indication_cmd(MPDU *pdu, int8_t ppduLinkQuality) +{ + uint8_t cmd_type; + //uint8_t pk_ptr; + uint8_t addressing_fields_length=0; + + uint32_t SrcAddr[2]; + //uint32_t DstAddr[2];//NOT USED SO FAR + + //frame control variables + uint8_t source_address=0; + uint8_t destination_address=0; + + //NOT USED SO FAR + //dest_short *dest_short_ptr; + //dest_long *dest_long_ptr; + //NOT USED SO FAR + //source_short *source_short_ptr; + source_long *source_long_ptr; + + dest_short *dest_short_ptr; + dest_long *dest_long_ptr; + + //CHECK IMPLEMENT + //intra_pan_source_short *intra_pan_source_short_ptr; + //intra_pan_source_long *intra_pan_source_long_ptr; + + destination_address=get_fc2_dest_addr(pdu->frame_control2); + source_address=get_fc2_source_addr(pdu->frame_control2); + + //decrement buffer count + atomic buffer_count --; + + switch(destination_address) + { + case LONG_ADDRESS: addressing_fields_length = DEST_LONG_LEN; + dest_long_ptr = (dest_long *) &pdu->data[0]; + if(dest_long_ptr->destination_address0 !=aExtendedAddress0 && dest_long_ptr->destination_address1 !=aExtendedAddress1) + { + //printfUART("NOT FOR ME",""); + return; + } + + break; + case SHORT_ADDRESS: addressing_fields_length = DEST_SHORT_LEN; + dest_short_ptr= (dest_short *) &pdu->data[0]; + //destination command not for me + if (dest_short_ptr->destination_address != mac_PIB.macShortAddress && dest_short_ptr->destination_address !=0xffff) + { + //printfUART("NOT FOR ME",""); + ////////////printfUART("NOT FOR ME %x me %e\n", dest_short_ptr->destination_address,mac_PIB.macShortAddress); + return; + } + break; + } + switch(source_address) + { + case LONG_ADDRESS: addressing_fields_length = addressing_fields_length + SOURCE_LONG_LEN; + break; + case SHORT_ADDRESS: addressing_fields_length = addressing_fields_length + SOURCE_SHORT_LEN; + break; + } + + cmd_type = pdu->data[addressing_fields_length]; + + + switch(cmd_type) + { + + case CMD_ASSOCIATION_REQUEST: + //check if association is allowed, if not discard the frame + + ////////printfUART("CMD_ASSOCIATION_REQUEST \n", ""); + + + if (mac_PIB.macAssociationPermit == 0 ) + { + ////////////printfUART("Association not alowed\n", ""); + if ( get_fc1_ack_request(pdu->frame_control1) == 1 ) + { + build_ack(pdu->seq_num,0); + } + return; + } + + if ( PANCoordinator==0 ) + { + ////////////printfUART("i´m not a pan\n", ""); + return; + } + atomic{ + source_long_ptr = (source_long *) &pdu->data[DEST_SHORT_LEN]; + + SrcAddr[1] =source_long_ptr->source_address0; + SrcAddr[0] =source_long_ptr->source_address1; + + + signal MLME_ASSOCIATE.indication(SrcAddr, pdu->data[addressing_fields_length+1] , 0, 0); + + } + + if ( get_fc1_ack_request(pdu->frame_control1) == 1 ) + { + build_ack(pdu->seq_num,1); + } + + + break; + + case CMD_ASSOCIATION_RESPONSE: atomic{ + //printfUART("CMD_ASSOCIATION_RESPONSE\n", ""); + + associating =0; + call T_ResponseWaitTime.stop(); + + if ( get_fc1_ack_request(pdu->frame_control1) == 1 ) + { + build_ack(pdu->seq_num,0); + } + + signal MLME_ASSOCIATE.confirm((uint16_t)(pdu->data[addressing_fields_length+1] + (pdu->data[addressing_fields_length+2] << 8)), pdu->data[addressing_fields_length+3]); + } + break; + + case CMD_DISASSOCIATION_NOTIFICATION: ////////////printfUART("Received CMD_DISASSOCIATION_NOTIFICATION\n", ""); + + if ( get_fc1_ack_request(pdu->frame_control1) == 1 ) + { + build_ack(pdu->seq_num,0); + } + + process_dissassociation_notification(pdu); + break; + case CMD_DATA_REQUEST: + ////printfUART("CMD_DATA_REQUEST\n", ""); + ////////printfUART("DR\n", ""); + if ( get_fc1_ack_request(pdu->frame_control1) == 1 ) + { + //TODO + //Problems with consecutive reception of messages + + //build_ack(pdu->seq_num,0); + } + + //cmd_data_request_0_3_reception = (cmd_data_request_0_3 *) pdu->data; + + source_long_ptr = (source_long *) &pdu->data[0]; + + SrcAddr[1] =source_long_ptr->source_address0; + SrcAddr[0] =source_long_ptr->source_address1; + + send_ind_trans_addr(SrcAddr); + + break; + case CMD_PANID_CONFLICT: + break; + + case CMD_ORPHAN_NOTIFICATION: + ////printfUART("CMD_ORPHAN_NOTIFICATION\n", ""); + + source_long_ptr = (source_long *) &pdu->data[DEST_SHORT_LEN]; + + SrcAddr[1] =source_long_ptr->source_address0; + SrcAddr[0] =source_long_ptr->source_address1; + + signal MLME_ORPHAN.indication(SrcAddr, 0x00,0x00); + + + break; + case CMD_BEACON_REQUEST: + break; + case CMD_COORDINATOR_REALIGNMENT: + //printfUART("CMD_COORDINATOR_REALIGNMENT\n", ""); + + process_coordinator_realignment(pdu); + + break; + case CMD_GTS_REQUEST: + //////////////printfUART("Received CMD_GTS_REQUEST\n", ""); + if ( get_fc1_ack_request(pdu->frame_control1) == 1 ) + { + build_ack(pdu->seq_num,0); + } + process_gts_request(pdu); + break; + default: break; + + } + +return; +} + +void indication_ack(MPDU *pdu, int8_t ppduLinkQuality) +{ + //decrement buffer count + + atomic buffer_count --; + + //////////////printfUART("ACK Received\n",""); + + atomic{ + if (send_ack_check == 1 && ack_sequence_number_check == pdu->seq_num) + { + //transmission SUCCESS + call T_ackwait.stop(); + + send_buffer_count --; + send_buffer_msg_out++; + + //failsafe + if(send_buffer_count > SEND_BUFFER_SIZE) + { + send_buffer_count =0; + send_buffer_msg_out=0; + send_buffer_msg_in=0; + } + + if (send_buffer_msg_out == SEND_BUFFER_SIZE) + send_buffer_msg_out=0; + + //received an ack for the association request + if( associating == 1 && association_cmd_seq_num == pdu->seq_num ) + { + ////////////printfUART("ASSOC ACK\n",""); + call T_ResponseWaitTime.startOneShot(response_wait_time); + //call T_ResponseWaitTime.start(TIMER_ONE_SHOT, response_wait_time); + } + + if (gts_request == 1 && gts_request_seq_num == pdu->seq_num) + { + + call T_ResponseWaitTime.startOneShot(response_wait_time); + //call T_ResponseWaitTime.start(TIMER_ONE_SHOT, response_wait_time); + } + + ////////////printfUART("TRANSMISSION SUCCESS\n",""); + + if (send_indirect_transmission > 0 ) + { //the message send was indirect + //remove the message from the indirect transmission queue + indirect_trans_queue[send_indirect_transmission-1].handler=0x00; + indirect_trans_count--; + ////////////printfUART("SU id:%i ct:%i\n", send_indirect_transmission,indirect_trans_count); + } + + send_ack_check=0; + retransmit_count=0; + ack_sequence_number_check=0; + + + if (send_buffer_count > 0) + post send_frame_csma(); + + + } + } + + //CHECK + if (get_fc1_frame_pending(pdu->frame_control1) == 1 && pending_request_data ==1)// && associating == 1 + { + ////////////printfUART("Frame_pending\n",""); + pending_request_data=0; + create_data_request_cmd(); + } + + //GTS mechanism, after the confirmation of the GTS request, must check if the beacon has the gts + /* + if (gts_ack == 1) + { + gts_ack=0; + gts_confirm=1; + call T_ResponseWaitTime.stop(); + + } + */ + if(gts_send_pending_data==1) + post start_gts_send(); + + if(coordinator_gts_send_pending_data==1 && coordinator_gts_send_time_slot == number_time_slot) + post start_coordinator_gts_send(); + +return; +} + + +void process_dissassociation_notification(MPDU *pdu) +{ +atomic{ + cmd_disassociation_notification *mac_disassociation_notification; + + //creation of a pointer to the disassociation notification structure + mac_disassociation_notification = (cmd_disassociation_notification*) pdu->data; + + signal MLME_DISASSOCIATE.indication(&mac_disassociation_notification->source_address0, mac_disassociation_notification->disassociation_reason, 0, 0); + } + +return; +} + + + + +void process_coordinator_realignment(MPDU *pdu) +{ + +atomic{ + cmd_coord_realignment *cmd_realignment = 0; + + dest_long *dest_long_ptr=0; + source_short *source_short_ptr=0; + + cmd_realignment = (cmd_coord_realignment*) &pdu->data[DEST_LONG_LEN + SOURCE_SHORT_LEN]; + + //creation of a pointer the addressing structures + dest_long_ptr = (dest_long *) &pdu->data[0]; + source_short_ptr = (source_short *) &pdu->data[DEST_LONG_LEN]; + + mac_PIB.macCoordShortAddress = ((cmd_realignment->coordinator_short_address0 << 8) | cmd_realignment->coordinator_short_address0 ); + mac_PIB.macShortAddress = cmd_realignment->short_address; + + + //printfUART("PCR %i %i\n",mac_PIB.macCoordShortAddress,mac_PIB.macShortAddress); + + } +return; +} + + +/*****************************************************************************************************/ +/*****************************************************************************************************/ +/*****************************************************************************************************/ +/************************ BUILD FRAMES FUNCTIONS **********************************/ +/*****************************************************************************************************/ +/*****************************************************************************************************/ +/*****************************************************************************************************/ + + +task void create_beacon() +{ + int i=0; + uint8_t packet_length = 25; + int data_count=0; + int pending_data_index=0; + MPDU* pkt_ptr=0; + //pending frames + uint8_t short_addr_pending=0; + uint8_t long_addr_pending=0; + + uint8_t gts_directions=0x00; + + uint16_t frame_control; + + + atomic{ + + beacon_addr_short *mac_beacon_addr_short_ptr; + //mac_beacon_addr_short_ptr = (beacon_addr_short*) &mac_txmpdu.data[0]; + mac_beacon_addr_short_ptr = (beacon_addr_short*) &mac_beacon_txmpdu.data[0]; + //call PLME_SET_TRX_STATE.request(PHY_TX_ON); + + mac_beacon_txmpdu_ptr->length = 15; + + frame_control = set_frame_control(TYPE_BEACON,0,0,0,1,SHORT_ADDRESS,SHORT_ADDRESS); + + mac_beacon_txmpdu_ptr->frame_control1 = (uint8_t)( frame_control); + + mac_beacon_txmpdu_ptr->frame_control2 = (uint8_t)( frame_control >> 8); + + //mac_beacon_txmpdu_ptr->frame_control = set_frame_control(TYPE_BEACON,0,0,0,1,SHORT_ADDRESS,SHORT_ADDRESS); + mac_beacon_txmpdu_ptr->seq_num = mac_PIB.macBSN; + mac_PIB.macBSN++; + + + //relocation error + mac_beacon_addr_short_ptr->destination_PAN_identifier= mac_PIB.macPANId; + //relocation error + mac_beacon_addr_short_ptr->destination_address = 0xffff; + //relocation error + mac_beacon_addr_short_ptr->source_address = mac_PIB.macShortAddress; + if (mac_PIB.macShortAddress == 0x0000) + { //the device is the PAN Coordinator + mac_beacon_addr_short_ptr->superframe_specification = set_superframe_specification(mac_PIB.macBeaconOrder,(uint8_t)mac_PIB.macSuperframeOrder,final_CAP_slot,0,1,mac_PIB.macAssociationPermit); + } + else + { + mac_beacon_addr_short_ptr->superframe_specification = set_superframe_specification(mac_PIB.macBeaconOrder,(uint8_t)mac_PIB.macSuperframeOrder,final_CAP_slot,0,1,mac_PIB.macAssociationPermit); + } + + mac_beacon_txmpdu_ptr->data[8] = set_gts_specification(GTS_descriptor_count,mac_PIB.macGTSPermit); + + mac_beacon_txmpdu_ptr->data[9] = set_pending_address_specification(short_addr_pending,long_addr_pending); + + data_count = 9; + packet_length = 15; + + + //BUILDING the GTS DESCRIPTORS + if( (GTS_descriptor_count + GTS_null_descriptor_count) > 0 ) + { + data_count++; + + for(i=0; i< 7 ; i++) + { + if( GTS_db[i].gts_id != 0x00 && GTS_db[i].DevAddressType != 0x0000) + { + + mac_beacon_txmpdu_ptr->data[data_count] = GTS_db[i].DevAddressType; + //////////////printfUART("B gts %i\n", (GTS_db[i].DevAddressType >> 8 ) ); + + data_count++; + mac_beacon_txmpdu_ptr->data[data_count] = (GTS_db[i].DevAddressType >> 8 ); + //////////////printfUART("B gts %i\n", GTS_db[i].DevAddressType ); + + data_count++; + + mac_beacon_txmpdu_ptr->data[data_count] = set_gts_descriptor(15-i,GTS_db[i].length); + data_count++; + //////printfUART("B gts %i\n", set_gts_descriptor(GTS_db[i].starting_slot,GTS_db[i].length) ); + + packet_length = packet_length + 3; + + if ( GTS_db[i].direction == 1 ) + { + gts_directions = gts_directions | (1 << i); + } + else + { + gts_directions = gts_directions | (0 << i); + } + //////printfUART("dir %i\n", gts_directions); + } + } + mac_beacon_txmpdu_ptr->data[9] = gts_directions; + //CHECK + packet_length++; + //BUILDING the NULL GTS DESCRIPTORS + if ( GTS_null_descriptor_count > 0 ) + { + for(i=0; i< 7 ; i++) + { + if( GTS_null_db[i].DevAddressType != 0x0000) + { + mac_beacon_txmpdu_ptr->data[data_count] = GTS_null_db[i].DevAddressType; + //////////////printfUART("B gts %i\n", (GTS_db[i].DevAddressType >> 8 ) ); + data_count++; + mac_beacon_txmpdu_ptr->data[data_count] = (GTS_null_db[i].DevAddressType >> 8 ); + //////////////printfUART("B gts %i\n", GTS_db[i].DevAddressType ); + data_count++; + mac_beacon_txmpdu_ptr->data[data_count] = 0x00; + data_count++; + //////////////printfUART("B gts %i\n", set_gts_descriptor(GTS_db[i].starting_slot,GTS_db[i].length) ); + packet_length = packet_length +3; + } + } + } + //resetting the GTS specification field + mac_beacon_txmpdu_ptr->data[8] = set_gts_specification(GTS_descriptor_count + GTS_null_descriptor_count,mac_PIB.macGTSPermit); + + + } + + pending_data_index = data_count; + data_count++; + //IMPLEMENT PENDING ADDRESSES + //temporary + //indirect_trans_count =0; + + if (indirect_trans_count > 0 ) + { + //IMPLEMENT THE PENDING ADDRESSES CONSTRUCTION + + for(i=0;i 0x00) + { + pkt_ptr = (MPDU *)&indirect_trans_queue[i].frame; + //ADD INDIRECT TRANSMISSION DESCRIPTOR + if(get_fc2_dest_addr(pkt_ptr->frame_control2) == SHORT_ADDRESS) + { + short_addr_pending++; + packet_length = packet_length + 2; + mac_beacon_txmpdu_ptr->data[data_count]=pkt_ptr->data[2]; + data_count++; + mac_beacon_txmpdu_ptr->data[data_count]=pkt_ptr->data[3]; + data_count++; + } + } + } + for(i=0;i 0x00) + { + if(get_fc2_dest_addr(pkt_ptr->frame_control2) == LONG_ADDRESS) + { + long_addr_pending++; + packet_length = packet_length + 8; + + mac_beacon_txmpdu_ptr->data[data_count]=pkt_ptr->data[0]; + data_count++; + mac_beacon_txmpdu_ptr->data[data_count]=pkt_ptr->data[1]; + data_count++; + mac_beacon_txmpdu_ptr->data[data_count]=pkt_ptr->data[2]; + data_count++; + mac_beacon_txmpdu_ptr->data[data_count]=pkt_ptr->data[3]; + data_count++; + mac_beacon_txmpdu_ptr->data[data_count]=pkt_ptr->data[4]; + data_count++; + mac_beacon_txmpdu_ptr->data[data_count]=pkt_ptr->data[5]; + data_count++; + mac_beacon_txmpdu_ptr->data[data_count]=pkt_ptr->data[6]; + data_count++; + mac_beacon_txmpdu_ptr->data[data_count]=pkt_ptr->data[7]; + data_count++; + + } + } + } + + } + mac_beacon_txmpdu_ptr->data[pending_data_index] = set_pending_address_specification(short_addr_pending,long_addr_pending); + + + //adding the beacon payload + if (mac_PIB.macBeaconPayloadLenght > 0 ) + { + for (i=0;i < mac_PIB.macBeaconPayloadLenght;i++) + { + mac_beacon_txmpdu_ptr->data[data_count] = mac_PIB.macBeaconPayload[i]; + data_count++; + packet_length++; + } + + + } + + //short_addr_pending=0; + //long_addr_pending=0; + + mac_beacon_txmpdu_ptr->length = packet_length; + + send_beacon_length = packet_length; + + send_beacon_frame_ptr = (uint8_t*)mac_beacon_txmpdu_ptr; + } +} + + +void create_data_frame(uint8_t SrcAddrMode, uint16_t SrcPANId, uint32_t SrcAddr[], uint8_t DstAddrMode, uint16_t DestPANId, uint32_t DstAddr[], uint8_t msduLength, uint8_t msdu[],uint8_t msduHandle, uint8_t TxOptions,uint8_t on_gts_slot,uint8_t pan) +{ + + int i_indirect_trans=0; + + dest_short *dest_short_ptr; + dest_long *dest_long_ptr; + + source_short *source_short_ptr; + source_long *source_long_ptr; + + //intra_pan_source_short *intra_pan_source_short_ptr; + //intra_pan_source_long *intra_pan_source_long_ptr; + + //CHECK + uint8_t intra_pan=0; + uint8_t data_len=0; + + uint8_t current_gts_element_count=0; + + MPDU *frame_pkt=0; + + uint16_t frame_control; + + ////printfUART("create df\n",""); + + //decision of the buffer where to store de packet creation + if (on_gts_slot > 0 ) + { + + if (PANCoordinator == 1) + { + //setting the coordinator gts frame pointer + + //get the number of frames in the gts_slot_list + atomic current_gts_element_count = gts_slot_list[15-on_gts_slot].element_count; + + ////////////printfUART("element count %i\n",gts_slot_list[15-on_gts_slot].element_count); + + if (current_gts_element_count == GTS_SEND_BUFFER_SIZE || available_gts_index_count == 0) + { + ////////////printfUART("FULL\n",""); + signal MCPS_DATA.confirm(0x00, MAC_TRANSACTION_OVERFLOW); + return; + } + else + { + frame_pkt = (MPDU *) >s_send_buffer[available_gts_index[available_gts_index_count]]; + } + + } + else + { + //setting the device gts frame pointer + //////////////printfUART("start creation %i %i %i \n",gts_send_buffer_count,gts_send_buffer_msg_in,gts_send_buffer_msg_out); + + if(gts_send_buffer_count == GTS_SEND_BUFFER_SIZE) + { + signal MCPS_DATA.confirm(0x00, MAC_TRANSACTION_OVERFLOW); + return; + } + if (gts_send_buffer_msg_in == GTS_SEND_BUFFER_SIZE) + gts_send_buffer_msg_in=0; + + frame_pkt = (MPDU *) >s_send_buffer[gts_send_buffer_msg_in]; + + } + } + else + { + + if ( get_txoptions_indirect_transmission(TxOptions) == 1) + { + + //CREATE THE INDIRECT TRANSMISSION PACKET POINTER + //check if the is enough space to store the indirect transaction + if (indirect_trans_count == INDIRECT_BUFFER_SIZE) + { + signal MCPS_DATA.confirm(0x00, MAC_TRANSACTION_OVERFLOW); + ////////////printfUART("buffer full %i\n", indirect_trans_count); + return; + } + + for(i_indirect_trans=0;i_indirect_trans SEND_BUFFER_SIZE) + return; + + if (send_buffer_msg_in == SEND_BUFFER_SIZE) + send_buffer_msg_in=0; + + frame_pkt = (MPDU *) &send_buffer[send_buffer_msg_in]; + } + } + } + +atomic{ + + if (intra_pan == 0 ) + { + + if ( DstAddrMode > 1 && SrcAddrMode > 1 ) + { + // Destination LONG - Source LONG + if (DstAddrMode == LONG_ADDRESS && SrcAddrMode == LONG_ADDRESS) + { + dest_long_ptr = (dest_long *) &frame_pkt->data[0]; + source_long_ptr = (source_long *) &frame_pkt->data[DEST_LONG_LEN]; + + dest_long_ptr->destination_PAN_identifier=DestPANId; + dest_long_ptr->destination_address0=DstAddr[1]; + dest_long_ptr->destination_address1=DstAddr[0]; + + source_long_ptr->source_PAN_identifier=SrcPANId; + source_long_ptr->source_address0=SrcAddr[1]; + source_long_ptr->source_address1=SrcAddr[0]; + + data_len = 20; + } + + // Destination SHORT - Source LONG + if ( DstAddrMode == SHORT_ADDRESS && SrcAddrMode == LONG_ADDRESS ) + { + dest_short_ptr = (dest_short *) &frame_pkt->data[0]; + source_long_ptr = (source_long *) &frame_pkt->data[DEST_SHORT_LEN]; + + dest_short_ptr->destination_PAN_identifier=DestPANId; + dest_short_ptr->destination_address=(uint16_t)DstAddr[1]; + + source_long_ptr->source_PAN_identifier=SrcPANId; + source_long_ptr->source_address0=SrcAddr[1]; + source_long_ptr->source_address1=SrcAddr[0]; + + data_len = 14; + } + // Destination LONG - Source SHORT + if ( DstAddrMode == LONG_ADDRESS && SrcAddrMode == SHORT_ADDRESS ) + { + dest_long_ptr = (dest_long *) &frame_pkt->data[0]; + source_short_ptr = (source_short *) &frame_pkt->data[DEST_LONG_LEN]; + + dest_long_ptr->destination_PAN_identifier=DestPANId; + dest_long_ptr->destination_address0=DstAddr[1]; + dest_long_ptr->destination_address1=DstAddr[0]; + + source_short_ptr->source_PAN_identifier=SrcPANId; + source_short_ptr->source_address=(uint16_t)SrcAddr[1]; + + data_len = 14; + } + + + //Destination SHORT - Source SHORT + if ( DstAddrMode == SHORT_ADDRESS && SrcAddrMode == SHORT_ADDRESS ) + { + dest_short_ptr = (dest_short *) &frame_pkt->data[0]; + source_short_ptr = (source_short *) &frame_pkt->data[DEST_SHORT_LEN]; + + dest_short_ptr->destination_PAN_identifier=DestPANId; + dest_short_ptr->destination_address=(uint16_t)DstAddr[1]; + + source_short_ptr->source_PAN_identifier=SrcPANId; + source_short_ptr->source_address=(uint16_t)SrcAddr[1]; + + data_len = 8; + } + } + + if ( DstAddrMode == 0 && SrcAddrMode > 1 ) + { + + if (SrcAddrMode == LONG_ADDRESS) + {//Source LONG + source_long_ptr = (source_long *) &frame_pkt->data[0]; + + source_long_ptr->source_PAN_identifier=SrcPANId; + source_long_ptr->source_address0=SrcAddr[1]; + source_long_ptr->source_address1=SrcAddr[0]; + + data_len = 10; + } + else + {//Source SHORT + + source_short_ptr = (source_short *) &frame_pkt->data[0]; + + source_short_ptr->source_PAN_identifier=SrcPANId; + source_short_ptr->source_address=(uint16_t)SrcAddr[1]; + + data_len = 4; + } + } + + if ( DstAddrMode > 1 && SrcAddrMode == 0 ) + { + if (DstAddrMode == LONG_ADDRESS) + {//Destination LONG + dest_long_ptr = (dest_long *) &frame_pkt->data[0]; + + dest_long_ptr->destination_PAN_identifier=DestPANId; + dest_long_ptr->destination_address0=DstAddr[1]; + dest_long_ptr->destination_address1=DstAddr[0]; + + data_len = 10; + } + else + {//Destination SHORT + dest_short_ptr = (dest_short *) &frame_pkt->data[0]; + + dest_short_ptr->destination_PAN_identifier=DestPANId; + dest_short_ptr->destination_address=(uint16_t)DstAddr[1]; + + data_len = 4; + } + } + } + else + { + //intra_pan == 1 + + } + + memcpy(&frame_pkt->data[data_len],&msdu[0],msduLength*sizeof(uint8_t)); + + if(on_gts_slot > 0) + { + //preparing a GTS transmission + + //////////////printfUART("GTS send slt: %i count %i %u\n",on_gts_slot,gts_slot_list[15-on_gts_slot].element_count,mac_PIB.macDSN); + frame_pkt->length = data_len + msduLength + MPDU_HEADER_LEN; + + frame_control = set_frame_control(TYPE_DATA,0,0,1,intra_pan,DstAddrMode,SrcAddrMode); + frame_pkt->frame_control1 =(uint8_t)( frame_control); + frame_pkt->frame_control2 =(uint8_t)( frame_control >> 8); + + frame_pkt->seq_num = mac_PIB.macDSN; + mac_PIB.macDSN++; + + //ADDING DATA TO THE GTS BUFFER + atomic{ + if (PANCoordinator == 1) + { + gts_slot_list[15-on_gts_slot].element_count ++; + gts_slot_list[15-on_gts_slot].gts_send_frame_index[gts_slot_list[15-on_gts_slot].element_in] = available_gts_index[available_gts_index_count]; + //gts_slot_list[15-on_gts_slot].length = frame_pkt->length; + + gts_slot_list[15-on_gts_slot].element_in ++; + + if (gts_slot_list[15-on_gts_slot].element_in == GTS_SEND_BUFFER_SIZE) + gts_slot_list[15-on_gts_slot].element_in=0; + + available_gts_index_count --; + + //current_gts_pending_frame++; + } + else + { + gts_send_buffer_count++; + gts_send_buffer_msg_in++; + //////////////printfUART("end c %i %i %i \n",gts_send_buffer_count,gts_send_buffer_msg_in,gts_send_buffer_msg_out); + } + } + } + else + { + ////////////printfUART("CSMA send %i\n", get_txoptions_ack(TxOptions)); + frame_pkt->length = data_len + msduLength + MPDU_HEADER_LEN; + //frame_pkt->frame_control = set_frame_control(TYPE_DATA,0,0,get_txoptions_ack(TxOptions),intra_pan,DstAddrMode,SrcAddrMode); + + frame_control = set_frame_control(TYPE_DATA,0,0,get_txoptions_ack(TxOptions),intra_pan,DstAddrMode,SrcAddrMode); + frame_pkt->frame_control1 =(uint8_t)( frame_control); + frame_pkt->frame_control2 =(uint8_t)( frame_control >> 8); + + frame_pkt->seq_num = mac_PIB.macDSN; + + ////////printfUART("sqn %i\n", mac_PIB.macDSN); + + mac_PIB.macDSN++; + + if ( get_txoptions_indirect_transmission(TxOptions) == 1) + { + indirect_trans_queue[i_indirect_trans].handler = indirect_trans_count + 1; + indirect_trans_queue[i_indirect_trans].transaction_persistent_time = 0x0000; + + indirect_trans_count++; + + ////////////printfUART("ADDED HDL: %i ADDR: %i\n",indirect_trans_count,DstAddr[1]); + } + else + { + //enable retransmissions + send_buffer[send_buffer_msg_in].retransmission = 1; + send_buffer[send_buffer_msg_in].indirect = 0; + + send_buffer_count++; + + send_buffer_msg_in++; + + post send_frame_csma(); + } + + } + + } +return; +} + + +error_t create_association_response_cmd(uint32_t DeviceAddress[],uint16_t shortaddress, uint8_t status) +{ + + cmd_association_response *mac_association_response; + dest_long *dest_long_ptr; + source_long *source_long_ptr; + + int i=0; + + MPDU *frame_pkt=0; + + uint16_t frame_control; + + //atomic{ + /* + if (send_buffer_msg_in == SEND_BUFFER_SIZE) + send_buffer_msg_in=0; + + frame_pkt = (MPDU *) &send_buffer[send_buffer_msg_in]; + */ + + //check if the is enough space to store the indirect transaction + if (indirect_trans_count == INDIRECT_BUFFER_SIZE) + { + //printfUART("i full",""); + return MAC_TRANSACTION_OVERFLOW; + } + + for(i=0;idata[0]; + source_long_ptr = (source_long *) &frame_pkt->data[DEST_LONG_LEN]; + + mac_association_response = (cmd_association_response *) &frame_pkt->data[DEST_LONG_LEN + SOURCE_LONG_LEN]; + + frame_pkt->length = 29; + //frame_pkt->frame_control = set_frame_control(TYPE_CMD,0,0,1,0,LONG_ADDRESS,LONG_ADDRESS); + + frame_control = set_frame_control(TYPE_CMD,0,0,1,0,LONG_ADDRESS,LONG_ADDRESS); + + frame_pkt->frame_control1 =(uint8_t)( frame_control); + frame_pkt->frame_control2 =(uint8_t)( frame_control >> 8); + + frame_pkt->seq_num = mac_PIB.macDSN; + mac_PIB.macDSN++; + + dest_long_ptr->destination_PAN_identifier = mac_PIB.macPANId; + + dest_long_ptr->destination_address0 = DeviceAddress[1]; + dest_long_ptr->destination_address1 = DeviceAddress[0]; + + source_long_ptr->source_PAN_identifier = mac_PIB.macPANId; + + source_long_ptr->source_address0 = aExtendedAddress0; + source_long_ptr->source_address1 = aExtendedAddress1; + + mac_association_response->command_frame_identifier = CMD_ASSOCIATION_RESPONSE; + + //mac_association_response->short_address = shortaddress; + mac_association_response->short_address1 = (uint8_t)(shortaddress); + mac_association_response->short_address2 = (uint8_t)(shortaddress >> 8); + + + mac_association_response->association_status = status; +/* + + //increment the send buffer variables + send_buffer_count++; + send_buffer_msg_in++; + } + post send_frame_csma(); +*/ + //printfUART("ASS RESP S: %i\n",shortaddress); + + indirect_trans_queue[i].handler = indirect_trans_count+1; + + indirect_trans_queue[i].transaction_persistent_time = 0x0000; + + indirect_trans_count++; + + //printfUART("IAD\n", ""); + +return MAC_SUCCESS; +} + + +void create_association_request_cmd(uint8_t CoordAddrMode,uint16_t CoordPANId,uint32_t CoordAddress[],uint8_t CapabilityInformation) +{ +atomic{ + + cmd_association_request *cmd_association_request_ptr; + dest_short *dest_short_ptr; + source_long *source_long_ptr; + + MPDU *frame_pkt=0; + + uint16_t frame_control; + + if (send_buffer_msg_in == SEND_BUFFER_SIZE) + send_buffer_msg_in=0; + + frame_pkt = (MPDU *) &send_buffer[send_buffer_msg_in]; + + //creation of a pointer to the association response structure + dest_short_ptr = (dest_short *) &frame_pkt->data[0]; + source_long_ptr = (source_long *) &frame_pkt->data[DEST_SHORT_LEN]; + + cmd_association_request_ptr = (cmd_association_request *) &send_buffer[send_buffer_msg_in].data[DEST_SHORT_LEN + SOURCE_LONG_LEN]; + + frame_pkt->length = 21; + //frame_pkt->frame_control = set_frame_control(TYPE_CMD,0,0,1,0,SHORT_ADDRESS,LONG_ADDRESS); + + frame_control = set_frame_control(TYPE_CMD,0,0,1,0,SHORT_ADDRESS,LONG_ADDRESS); + frame_pkt->frame_control1 =(uint8_t)( frame_control); + frame_pkt->frame_control2 =(uint8_t)( frame_control >> 8); + + frame_pkt->seq_num = mac_PIB.macDSN; + + association_cmd_seq_num = mac_PIB.macDSN; + + mac_PIB.macDSN++; + + //enable retransmissions + send_buffer[send_buffer_msg_in].retransmission =1; + send_buffer[send_buffer_msg_in].indirect = 0; + + dest_short_ptr->destination_PAN_identifier = CoordPANId; //mac_PIB.macPANId; + + if (CoordAddrMode == SHORT_ADDRESS ) + { + dest_short_ptr->destination_address = (uint16_t)(CoordAddress[1] & 0x000000ff) ; //mac_PIB.macPANId; + } + else + { + //CHECK + + //implement the long address version + + } + + source_long_ptr->source_PAN_identifier = 0xffff; + + source_long_ptr->source_address0 = aExtendedAddress0; + source_long_ptr->source_address1 = aExtendedAddress1; + + cmd_association_request_ptr->command_frame_identifier = CMD_ASSOCIATION_REQUEST; + + cmd_association_request_ptr->capability_information = CapabilityInformation; + + //increment the send buffer variables + send_buffer_count++; + send_buffer_msg_in++; + + pending_request_data=1; + + //////printfUART("Association request %i %i \n", send_buffer_count,send_buffer_msg_in); + + + post send_frame_csma(); + + } +return; +} + +void create_data_request_cmd() +{ + ////////////printfUART("create_data_request_cmd\n", ""); + +atomic{ + //dest_short *dest_short_ptr; + source_long *source_long_ptr; + + + MPDU *frame_pkt; + + uint16_t frame_control; + + if (send_buffer_msg_in == SEND_BUFFER_SIZE) + send_buffer_msg_in=0; + + frame_pkt = (MPDU *) &send_buffer[send_buffer_msg_in]; + + + source_long_ptr= (source_long *) &send_buffer[send_buffer_msg_in].data[0]; + + //creation of a pointer to the association response structure + //dest_short_ptr = (dest_short *) &frame_pkt->data[0]; + source_long_ptr = (source_long *) &frame_pkt->data[0]; + + + frame_pkt->length = 16; + //frame_pkt->frame_control = set_frame_control(TYPE_CMD,0,0,1,1,0,LONG_ADDRESS); //dest | source + + frame_control = set_frame_control(TYPE_CMD,0,0,1,1,0,LONG_ADDRESS); + frame_pkt->frame_control1 =(uint8_t)( frame_control); + frame_pkt->frame_control2 =(uint8_t)( frame_control >> 8); + + frame_pkt->seq_num = mac_PIB.macDSN; + + mac_PIB.macDSN++; + + //enable retransmissions + send_buffer[send_buffer_msg_in].retransmission =1; + send_buffer[send_buffer_msg_in].indirect = 0; + + + source_long_ptr->source_PAN_identifier = mac_PIB.macPANId; + + source_long_ptr->source_address0 = aExtendedAddress0;//aExtendedAddress0; + source_long_ptr->source_address1 = aExtendedAddress1; + + //command_frame_identifier = CMD_DATA_REQUEST; + frame_pkt->data[SOURCE_LONG_LEN]=CMD_DATA_REQUEST; + + //increment the send buffer variables + send_buffer_count++; + send_buffer_msg_in++; + + post send_frame_csma(); + + + } +return; +} + +void create_beacon_request_cmd() +{ + +atomic{ + cmd_beacon_request *mac_beacon_request; + + MPDU *frame_pkt; + + uint16_t frame_control; + + if (send_buffer_msg_in == SEND_BUFFER_SIZE) + send_buffer_msg_in=0; + + frame_pkt = (MPDU *) &send_buffer[send_buffer_msg_in]; + + mac_beacon_request= (cmd_beacon_request*) &send_buffer[send_buffer_msg_in].data; + + frame_pkt->length = 10; + //frame_pkt->frame_control = set_frame_control(TYPE_CMD,0,0,0,0,SHORT_ADDRESS,0); //dest | source + + frame_control = set_frame_control(TYPE_CMD,0,0,0,0,SHORT_ADDRESS,0); + frame_pkt->frame_control1 =(uint8_t)( frame_control); + frame_pkt->frame_control2 =(uint8_t)( frame_control >> 8); + + frame_pkt->seq_num = mac_PIB.macDSN; + + mac_PIB.macDSN++; + + //enable retransmissions + send_buffer[send_buffer_msg_in].retransmission =1; + send_buffer[send_buffer_msg_in].indirect = 0; + + mac_beacon_request->destination_PAN_identifier = 0xffff; + + mac_beacon_request->destination_address = 0xffff; + + mac_beacon_request->command_frame_identifier = CMD_BEACON_REQUEST; + + + //increment the send buffer variables + send_buffer_count++; + send_buffer_msg_in++; + + post send_frame_csma(); + + } + +return; +} + +void create_orphan_notification() +{ + + atomic{ + + cmd_default *cmd_orphan_notification=0; + + dest_short *dest_short_ptr=0; + source_long *source_long_ptr=0; + + MPDU *frame_pkt=0; + + uint16_t frame_control=0; + + if (send_buffer_msg_in == SEND_BUFFER_SIZE) + send_buffer_msg_in=0; + + frame_pkt = (MPDU *) &send_buffer[send_buffer_msg_in]; + + frame_pkt->length = 20; + + cmd_orphan_notification = (cmd_default*) &send_buffer[send_buffer_msg_in].data[DEST_SHORT_LEN + SOURCE_LONG_LEN]; + + //creation of a pointer the addressing structures + dest_short_ptr = (dest_short *) &frame_pkt->data[0]; + source_long_ptr = (source_long *) &frame_pkt->data[DEST_SHORT_LEN]; + + + frame_control = set_frame_control(TYPE_CMD,0,0,0,0,SHORT_ADDRESS,LONG_ADDRESS); + frame_pkt->frame_control1 =(uint8_t)( frame_control); + frame_pkt->frame_control2 =(uint8_t)( frame_control >> 8); + + + frame_pkt->seq_num = mac_PIB.macDSN; + + mac_PIB.macDSN++; + + + dest_short_ptr->destination_PAN_identifier = 0xffff; //mac_PIB.macPANId; + + dest_short_ptr->destination_address = 0xffff ; //mac_PIB.macPANId; + + source_long_ptr->source_PAN_identifier = 0xffff; + + source_long_ptr->source_address0 = aExtendedAddress0; + source_long_ptr->source_address1 = aExtendedAddress1; + + + cmd_orphan_notification->command_frame_identifier = CMD_ORPHAN_NOTIFICATION; + + //increment the send buffer variables + send_buffer_count++; + send_buffer_msg_in++; + + post send_frame_csma(); + } + +return; +} + + +void create_coordinator_realignment_cmd(uint32_t device_extended0, uint32_t device_extended1, uint16_t device_short_address) +{ + +atomic{ + + cmd_coord_realignment *cmd_realignment =0; + + dest_long *dest_long_ptr=0; + source_short *source_short_ptr=0; + + MPDU *frame_pkt=0; + + uint16_t frame_control=0; + + if (send_buffer_msg_in == SEND_BUFFER_SIZE) + send_buffer_msg_in=0; + + frame_pkt = (MPDU *) &send_buffer[send_buffer_msg_in]; + + frame_pkt->length = 27; + //frame_pkt->frame_control = set_frame_control(TYPE_CMD,0,0,0,0,SHORT_ADDRESS,0); //dest | source + + cmd_realignment = (cmd_coord_realignment*) &send_buffer[send_buffer_msg_in].data[DEST_LONG_LEN + SOURCE_SHORT_LEN]; + + //creation of a pointer the addressing structures + dest_long_ptr = (dest_long *) &frame_pkt->data[0]; + source_short_ptr = (source_short *) &frame_pkt->data[DEST_LONG_LEN]; + + + frame_control = set_frame_control(TYPE_CMD,0,0,0,0,LONG_ADDRESS,SHORT_ADDRESS); + frame_pkt->frame_control1 =(uint8_t)( frame_control); + frame_pkt->frame_control2 =(uint8_t)( frame_control >> 8); + + frame_pkt->seq_num = mac_PIB.macDSN; + + mac_PIB.macDSN++; + + dest_long_ptr->destination_PAN_identifier = 0xffff; + dest_long_ptr->destination_address0 = device_extended0; + dest_long_ptr->destination_address1 = device_extended1; + + source_short_ptr->source_PAN_identifier = mac_PIB.macPANId; + source_short_ptr->source_address = mac_PIB.macCoordShortAddress; + + + cmd_realignment->command_frame_identifier = CMD_COORDINATOR_REALIGNMENT; + + mac_PIB.macPANId = 0x1234; + + mac_PIB.macCoordShortAddress =0x0000; + + cmd_realignment->PAN_identifier0 = (mac_PIB.macPANId); + cmd_realignment->PAN_identifier1 = (mac_PIB.macPANId >> 8); + + cmd_realignment->coordinator_short_address0 = (mac_PIB.macCoordShortAddress); + cmd_realignment->coordinator_short_address1 = (mac_PIB.macCoordShortAddress >> 8); + + cmd_realignment->logical_channel = LOGICAL_CHANNEL; + cmd_realignment->short_address = device_short_address; + + + //increment the send buffer variables + send_buffer_count++; + send_buffer_msg_in++; + + post send_frame_csma(); + + } + +return; +} + + +void create_gts_request_cmd(uint8_t gts_characteristics) +{ +atomic{ + cmd_gts_request *mac_gts_request; + + MPDU *frame_pkt; + + uint16_t frame_control; + //////printfUART("create_gts_request_cmd\n", ""); + + + if (send_buffer_msg_in == SEND_BUFFER_SIZE) + send_buffer_msg_in=0; + + frame_pkt = (MPDU *) &send_buffer[send_buffer_msg_in]; + + mac_gts_request= (cmd_gts_request*) &send_buffer[send_buffer_msg_in].data; + + frame_pkt->length = 11; + + if ( get_characteristic_type(gts_characteristics) != 0 ) + { + //frame_pkt->frame_control = set_frame_control(TYPE_CMD,0,0,1,1,0,SHORT_ADDRESS); //dest | source + + frame_control = set_frame_control(TYPE_CMD,0,0,1,1,0,SHORT_ADDRESS); + frame_pkt->frame_control1 =(uint8_t)( frame_control); + frame_pkt->frame_control2 =(uint8_t)( frame_control >> 8); + } + else + { + //frame_pkt->frame_control = set_frame_control(TYPE_CMD,0,0,1,1,0,SHORT_ADDRESS); + + frame_control = set_frame_control(TYPE_CMD,0,0,1,1,0,SHORT_ADDRESS); + frame_pkt->frame_control1 =(uint8_t)( frame_control); + frame_pkt->frame_control2 =(uint8_t)( frame_control >> 8); + } + + frame_pkt->seq_num = mac_PIB.macDSN; + + gts_request_seq_num = frame_pkt->seq_num; + + mac_PIB.macDSN++; + + //enable retransmissions + send_buffer[send_buffer_msg_in].retransmission =1; + send_buffer[send_buffer_msg_in].indirect = 0; + + //mac_gts_request->source_PAN_identifier = 0x0001; + mac_gts_request->source_PAN_identifier = mac_PIB.macPANId; + + mac_gts_request->source_address = mac_PIB.macShortAddress; + + mac_gts_request->command_frame_identifier = CMD_GTS_REQUEST; + + //mac_gts_request->gts_characteristics = set_gts_characteristics(2,1,1); + mac_gts_request->gts_characteristics =gts_characteristics; + + //increment the send buffer variables + send_buffer_count++; + send_buffer_msg_in++; + + post send_frame_csma(); + + } + +return; +} + +void create_disassociation_notification_cmd(uint32_t DeviceAddress[],uint8_t disassociation_reason) +{ + + atomic{ + cmd_disassociation_notification *mac_disassociation_notification; + MPDU *frame_pkt; + + uint16_t frame_control; + + if (send_buffer_msg_in == SEND_BUFFER_SIZE) + send_buffer_msg_in=0; + + frame_pkt = (MPDU *) &send_buffer[send_buffer_msg_in]; + + //creation of a pointer to the disassociation notification structure + mac_disassociation_notification = (cmd_disassociation_notification*) &send_buffer[send_buffer_msg_in].data; + + + frame_pkt->length = 27; + + //frame_pkt->frame_control = set_frame_control(TYPE_CMD,0,0,1,0,LONG_ADDRESS,LONG_ADDRESS); + + frame_control = set_frame_control(TYPE_CMD,0,0,1,0,LONG_ADDRESS,LONG_ADDRESS); + frame_pkt->frame_control1 =(uint8_t)( frame_control); + frame_pkt->frame_control2 =(uint8_t)( frame_control >> 8); + + frame_pkt->seq_num = mac_PIB.macDSN; + + mac_PIB.macDSN++; + + //enable retransmissions + send_buffer[send_buffer_msg_in].retransmission =1; + send_buffer[send_buffer_msg_in].indirect = 0; + + mac_disassociation_notification->destination_PAN_identifier = mac_PIB.macPANId; + + mac_disassociation_notification->destination_address0 = DeviceAddress[0]; + mac_disassociation_notification->destination_address1 = DeviceAddress[1]; + + mac_disassociation_notification->source_PAN_identifier = mac_PIB.macPANId; + + mac_disassociation_notification->source_address0 = aExtendedAddress0; + mac_disassociation_notification->source_address1 = aExtendedAddress1; + + mac_disassociation_notification->command_frame_identifier = CMD_DISASSOCIATION_NOTIFICATION; + + mac_disassociation_notification->disassociation_reason = disassociation_reason; + + //increment the send buffer variables + send_buffer_count++; + send_buffer_msg_in++; + + post send_frame_csma(); + + } +return; +} + + + +void build_ack(uint8_t sequence,uint8_t frame_pending) +{ + uint16_t frame_control; + atomic{ + mac_ack_ptr->length = ACK_LENGTH; + //mac_ack_ptr->frame_control = set_frame_control(TYPE_ACK,0,frame_pending,0,0,0,0); + + frame_control = set_frame_control(TYPE_ACK,0,frame_pending,0,0,0,0); + mac_ack_ptr->frame_control1 =(uint8_t)( frame_control); + mac_ack_ptr->frame_control2 =(uint8_t)( frame_control >> 8); + + mac_ack_ptr->seq_num = sequence; + + call PD_DATA.request(mac_ack_ptr->length,(uint8_t*)mac_ack_ptr); + } +} + + + +/*****************************************************************************************************/ +/*****************************************************************************************************/ +/*****************************************************************************************************/ +/************************ INTERFACES PROVIDED **********************************/ +/*****************************************************************************************************/ +/*****************************************************************************************************/ +/*****************************************************************************************************/ + +/*********************************************************/ +/**************MLME_SCAN********************************/ +/*********************************************************/ + +task void data_channel_scan_indication() +{ + uint8_t link_qual; + + beacon_addr_short *beacon_ptr; + + ////printfUART("data_channel_scan_indication\n",""); + + atomic link_qual = link_quality; + + atomic buffer_count--; + + switch(scan_type) + { + case ED_SCAN: + if (scanned_values[current_scanning-1] < link_qual) + scanned_values[current_scanning-1] = link_qual; + break; + + case ACTIVE_SCAN:break; + + case PASSIVE_SCAN: + switch( (buffer_msg[current_msg_out].frame_control1 & 0x7) ) + { + case TYPE_BEACON: + printfUART("3 ps rb\n",""); + beacon_ptr = (beacon_addr_short*) (&buffer_msg[current_msg_out].data); + + //Beacon NOTIFICATION + //BUILD the PAN descriptor of the COORDINATOR + //assuming that the adress is short + scan_pans[current_scanning-1].CoordPANId = beacon_ptr->destination_PAN_identifier; + scan_pans[current_scanning-1].CoordAddress=beacon_ptr->source_address; + scan_pans[current_scanning-1].LogicalChannel=current_channel; + //superframe specification field + scan_pans[current_scanning-1].SuperframeSpec = beacon_ptr->superframe_specification; + + if (scan_pans[current_scanning-1].lqi < link_qual) + scan_pans[current_scanning-1].lqi = link_qual; + + break; + + default: break; + //atomic buffer_count--; + //////////////printfUART("Invalid frame type\n",""); + + } + break; + case ORPHAN_SCAN: + ////printfUART("osrm\n",""); + switch( (buffer_msg[current_msg_out].frame_control1 & 0x7) ) + { + case TYPE_CMD: + ////printfUART("received cmd\n",""); + if (buffer_msg[current_msg_out].data[SOURCE_SHORT_LEN+ DEST_LONG_LEN] == CMD_COORDINATOR_REALIGNMENT) + { + //printfUART("pf\n",""); + atomic scanning_channels = 0; + call T_ScanDuration.stop(); + process_coordinator_realignment(&buffer_msg[current_msg_out]); + + } + + break; + default: break; + } + break; + + } + + atomic{ + current_msg_out++; + if ( current_msg_out == RECEIVE_BUFFER_SIZE ) + current_msg_out = 0; + } +return; +} +/*******************T_ScanDuration**************************/ +event void T_ScanDuration.fired() { + + current_scanning++; + + printfUART("cs%i c%i\n",current_scanning,(0x0A + current_scanning)); + + call PLME_SET.request(PHYCURRENTCHANNEL, (0x0A + current_scanning)); + + current_channel = (0x0A + current_scanning); + + + if (current_scanning == 16 ) + { + ////printfUART("scan end\n",""); + + atomic scanning_channels = 0; + + switch(scan_type) + { + case ED_SCAN: + signal MLME_SCAN.confirm(MAC_SUCCESS,scan_type, 0x00, 16 , scanned_values,0x00); + break; + + case ACTIVE_SCAN:break; + + case PASSIVE_SCAN: + //event result_t confirm(uint8_t status,uint8_t ScanType, uint32_t UnscannedChannels, uint8_t ResultListSize, uint8_t EnergyDetectList[], SCAN_PANDescriptor PANDescriptorList[]); + signal MLME_SCAN.confirm(MAC_SUCCESS,scan_type, 0x00, 16 , 0x00, scan_pans); + break; + + case ORPHAN_SCAN: + //orphan scan + //send opphan command on every channel directed to the current PAN coordinator + //printfUART("oph s end not found\n",""); + signal MLME_SCAN.confirm(MAC_SUCCESS,scan_type, 0x00, 16 , 0x00, scan_pans); + + break; + } + } + else + { + switch(scan_type) + { + case ORPHAN_SCAN: //printfUART("con\n",""); + create_orphan_notification(); + break; + } + + call T_ScanDuration.startOneShot(scan_duration); + } + +} + + + +command error_t MLME_SCAN.request(uint8_t ScanType, uint32_t ScanChannels, uint8_t ScanDuration) +{ +//pag 93 + //printfUART("MLME_SCAN.request\n", ""); + + atomic scanning_channels = 1; + scan_type = ScanType; + channels_to_scan = ScanChannels; + + atomic current_scanning=0; + + + switch(ScanType) + { + //ED SCAN only FFD + case ED_SCAN: + call TimerAsync.set_timers_enable(0x00); + /* + + scanning_channels = 1; + scan_type = ScanType; + current_scanning=0; + scan_count=0; + channels_to_scan = ScanChannels; + scan_duration = ((aBaseSuperframeDuration * pow(2,ScanDuration)) * 4.0) / 250.0; + + ////////////printfUART("channels_to_scan %y scan_duration %y\n", channels_to_scan,scan_duration); + + call T_ed_scan.start(TIMER_REPEAT,1); + + call T_scan_duration.start(TIMER_ONE_SHOT,scan_duration); + */ + + + //calculate the scan_duration in miliseconds + //#ifdef PLATFORM_MICAZ + scan_duration = ((aBaseSuperframeDuration * (powf(2,ScanDuration)+1)) * EFFECTIVE_SYMBOL_VALUE) / 1000.0; + //#else + // scan_duration = ((aBaseSuperframeDuration * (powf(2,ScanDuration)+1)) * EFFECTIVE_SYMBOL_VALUE) / 1000.0; + //#endif + //scan_duration = 2000; + + call T_ScanDuration.startOneShot(scan_duration); + + ////printfUART("channels_to_scan %y scan_duration %y\n", channels_to_scan,scan_duration); + break; + //active scan only FFD + case ACTIVE_SCAN: + call TimerAsync.set_timers_enable(0x00); + break; + //passive scan + case PASSIVE_SCAN: + call TimerAsync.set_timers_enable(0x00); + + //calculate the scan_duration in miliseconds + //#ifdef PLATFORM_MICAZ + // scan_duration = ((aBaseSuperframeDuration * (powf(2,ScanDuration)+1)) * EFFECTIVE_SYMBOL_VALUE) / 1000.0; + //#else + // scan_duration = ((aBaseSuperframeDuration * (powf(2,ScanDuration)+1)) * EFFECTIVE_SYMBOL_VALUE) / 1000.0; + //#endif + + + //defines the time (miliseconds) that the device listen in each channel + scan_duration = 2000; + + //printfUART("channels_to_scan %y scan_duration %i\n", channels_to_scan,scan_duration); + + call T_ScanDuration.startOneShot(scan_duration); + + ////printfUART("channels_to_scan %y scan_duration %i\n", channels_to_scan,scan_duration); + + //atomic trx_status = PHY_RX_ON; + //call PLME_SET_TRX_STATE.request(PHY_RX_ON); + + + + break; + //orphan scan + case ORPHAN_SCAN: + + call TimerAsync.set_timers_enable(0x01); + + scan_duration = 4000; + + //printfUART("orphan cts %y sdur %i\n", channels_to_scan,scan_duration); + + call T_ScanDuration.startOneShot(scan_duration); + + break; + + default: + break; + } + +return SUCCESS; +} + + + +/*********************************************************/ +/**************MLME_ORPHAN********************************/ +/*********************************************************/ + +command error_t MLME_ORPHAN.response(uint32_t OrphanAddress[1],uint16_t ShortAddress,uint8_t AssociatedMember, uint8_t security_enabled) +{ + + if (AssociatedMember==0x01) + { + create_coordinator_realignment_cmd(OrphanAddress[0], OrphanAddress[1], ShortAddress); + } + +return SUCCESS; +} + +/*********************************************************/ +/**************MLME_SYNC********************************/ +/*********************************************************/ + + +command error_t MLME_SYNC.request(uint8_t logical_channel,uint8_t track_beacon) +{ + +call PLME_SET.request(PHYCURRENTCHANNEL,LOGICAL_CHANNEL); + //call PLME_SET.request(PHYCURRENTCHANNEL,logical_channel); + + call TimerAsync.set_timers_enable(0x01); + + //printfUART("sync req\n", ""); + + atomic findabeacon = 1; + +return SUCCESS; +} + +/*********************************************************/ +/**************MLME_RESET********************************/ +/*********************************************************/ + + +command error_t MLME_RESET.request(uint8_t set_default_PIB) +{ + + +return SUCCESS; +} + +/*********************************************************/ +/**************MLME_GTS***********************************/ +/*********************************************************/ + +command error_t MLME_GTS.request(uint8_t GTSCharacteristics, bool security_enable) +{ + + //uint32_t wait_time; + //if there is no short address asigned the node cannot send a GTS request + if (mac_PIB.macShortAddress == 0xffff) + signal MLME_GTS.confirm(GTSCharacteristics,MAC_NO_SHORT_ADDRESS); + + //gts_ack=1; + + gts_request =1; + + create_gts_request_cmd(GTSCharacteristics); + +return SUCCESS; +} + + +/*********************************************************/ +/**************MLME_START*********************************/ +/*********************************************************/ + +command error_t MLME_START.request(uint32_t PANId, uint8_t LogicalChannel, uint8_t beacon_order, uint8_t superframe_order,bool pan_coodinator,bool BatteryLifeExtension,bool CoordRealignment,bool securityenable,uint32_t StartTime) +{ + + uint32_t BO_EXPONENT; + uint32_t SO_EXPONENT; + + //////////printfUART("MLME_START.request\n", ""); + //pag 102 + atomic { + PANCoordinator=1; + Beacon_enabled_PAN=1; + //TEST + //atomic mac_PIB.macShortAddress = 0x0000; + + + if ( mac_PIB.macShortAddress == 0xffff) + { + + signal MLME_START.confirm(MAC_NO_SHORT_ADDRESS); + return SUCCESS; + } + else + { + atomic mac_PIB.macBeaconOrder = beacon_order; + + if (beacon_order == 15) + atomic mac_PIB.macSuperframeOrder = 15; + else + atomic mac_PIB.macSuperframeOrder = superframe_order; + + + //PANCoordinator is set to TRUE + if (pan_coodinator == 1) + { + atomic mac_PIB.macPANId = PANId; + call PLME_SET.request(PHYCURRENTCHANNEL,LogicalChannel); + } + if (CoordRealignment == 1) + { + //generates and broadcasts a coordinator realignment command containing the new PANId and LogicalChannels + } + if (securityenable == 1) + { + //security parameters + } + } + + if (mac_PIB.macSuperframeOrder == 0) + SO_EXPONENT = 1; + else + { + SO_EXPONENT = powf(2,mac_PIB.macSuperframeOrder); + + } + if ( mac_PIB.macBeaconOrder == 0) + BO_EXPONENT = 1; + else + { + BO_EXPONENT = powf(2,mac_PIB.macBeaconOrder); + + } + } + + BI = aBaseSuperframeDuration * BO_EXPONENT; + + SD = aBaseSuperframeDuration * SO_EXPONENT; + //backoff_period + backoff = aUnitBackoffPeriod; + + + atomic time_slot = SD / NUMBER_TIME_SLOTS; + + call TimerAsync.set_backoff_symbols(backoff); + + call TimerAsync.set_bi_sd(BI,SD); + + atomic{ + + call TimerAsync.set_timers_enable(0x01); + + call TimerAsync.reset(); + + } + + signal MLME_START.confirm(MAC_SUCCESS); + + return SUCCESS; +} + +/*************************************************************/ +/**************MLME_ASSOCIATE*********************************/ +/*************************************************************/ + +command error_t MLME_ASSOCIATE.request(uint8_t LogicalChannel,uint8_t CoordAddrMode,uint16_t CoordPANId,uint32_t CoordAddress[],uint8_t CapabilityInformation,bool securityenable) +{ + //update current channel + //call PLME_SET.request(PHYCURRENTCHANNEL,LogicalChannel); + + + printfUART("MLME_ASSOCIATE.request %x %x\n", mac_PIB.macPANId,mac_PIB.macCoordShortAddress); + //updates the PAN ID + atomic{ + mac_PIB.macPANId = CoordPANId; + mac_PIB.macCoordShortAddress = (uint16_t)(CoordAddress[1] & 0x000000ff); + } + + + associating=1; //boolean variable stating that the device is trying to associate + + call TimerAsync.set_timers_enable(1); + + //the channel selection is made during the SynC procedure + //call PLME_SET.request(PHYCURRENTCHANNEL, LogicalChannel); + + current_channel = LogicalChannel; + + ////printfUART("SELECTED cord id %i\n", mac_PIB.macPANId); + ////printfUART("CoordAddress %i\n", mac_PIB.macCoordShortAddress); + ////printfUART("LogicalChannel %i\n", LogicalChannel); + ////printfUART("Cordaddr %i\n",CoordAddress[0]); + ////printfUART("Cordaddr %i\n",CoordAddress[1]); + /* + + a_CoordAddrMode = CoordAddrMode; + a_CoordPANId=CoordPANId; + a_CoordAddress[0]=CoordAddress[0]; + a_CoordAddress[1]=CoordAddress[1]; + a_CapabilityInformation=CapabilityInformation; + a_securityenable=securityenable; + */ + create_association_request_cmd(CoordAddrMode,CoordPANId,CoordAddress,CapabilityInformation); + + return SUCCESS; +} + +command error_t MLME_ASSOCIATE.response(uint32_t DeviceAddress[], uint16_t AssocShortAddress, uint8_t status, bool securityenable) +{ + + error_t status_response; + + ////////printfUART("MAR\n", ""); + + status_response = create_association_response_cmd(DeviceAddress,AssocShortAddress,status); + //////////////printfUART("MLME_ASSOCIATE.response\n", ""); + + +return SUCCESS; +} + +/*************************************************************/ +/**************MLME_DISASSOCIATE*********************************/ +/*************************************************************/ + +command error_t MLME_DISASSOCIATE.request(uint32_t DeviceAddress[], uint8_t disassociate_reason, bool securityenable) +{ + create_disassociation_notification_cmd(DeviceAddress,disassociate_reason); +return SUCCESS; +} + +/*********************************************************/ +/**************MLME_GET***********************************/ +/*********************************************************/ +command error_t MLME_GET.request(uint8_t PIBAttribute) +{ + + switch(PIBAttribute) + { + case MACACKWAITDURATION : signal MLME_GET.confirm(MAC_SUCCESS,PIBAttribute,&mac_PIB.macAckWaitDuration); + break; + case MACASSOCIATIONPERMIT: signal MLME_GET.confirm(MAC_SUCCESS,PIBAttribute,&mac_PIB.macAssociationPermit); + break; + case MACAUTOREQUEST : signal MLME_GET.confirm(MAC_SUCCESS,PIBAttribute,&mac_PIB.macAutoRequest); + break; + case MACBATTLIFEEXT: signal MLME_GET.confirm(MAC_SUCCESS,PIBAttribute,&mac_PIB.macBattLifeExt); + break; + case MACBATTLIFEEXTPERIODS: signal MLME_GET.confirm(MAC_SUCCESS,PIBAttribute,&mac_PIB.macBattLifeExtPeriods); + break; + case MACBEACONPAYLOAD: signal MLME_GET.confirm(MAC_SUCCESS,PIBAttribute, mac_PIB.macBeaconPayload); + break; + case MACMAXBEACONPAYLOADLENGTH: signal MLME_GET.confirm(MAC_SUCCESS,PIBAttribute,&mac_PIB.macBeaconPayloadLenght); + break; + case MACBEACONORDER: signal MLME_GET.confirm(MAC_SUCCESS,PIBAttribute,&mac_PIB.macBeaconOrder); + break; + case MACBEACONTXTIME: signal MLME_GET.confirm(MAC_SUCCESS,PIBAttribute,(uint8_t *)&mac_PIB.macBeaconTxTime); + break; + case MACBSN: signal MLME_GET.confirm(MAC_SUCCESS,PIBAttribute,&mac_PIB.macBSN); + break; + case MACCOORDEXTENDEDADDRESS: signal MLME_GET.confirm(MAC_SUCCESS,PIBAttribute,(uint8_t *) &mac_PIB.macCoordExtendedAddress0); + break; + case MACCOORDSHORTADDRESS: signal MLME_GET.confirm(MAC_SUCCESS,PIBAttribute,(uint8_t *) &mac_PIB.macCoordShortAddress); + break; + case MACDSN: signal MLME_GET.confirm(MAC_SUCCESS,PIBAttribute,&mac_PIB.macDSN); + break; + case MACGTSPERMIT: signal MLME_GET.confirm(MAC_SUCCESS,PIBAttribute,&mac_PIB.macGTSPermit); + break; + case MACMAXCSMABACKOFFS: signal MLME_GET.confirm(MAC_SUCCESS,PIBAttribute,&mac_PIB.macMaxCSMABackoffs); + break; + case MACMINBE: signal MLME_GET.confirm(MAC_SUCCESS,PIBAttribute,&mac_PIB.macMinBE); + break; + case MACPANID: signal MLME_GET.confirm(MAC_SUCCESS,PIBAttribute,(uint8_t *) &mac_PIB.macPANId); + break; + case MACPROMISCUOUSMODE: signal MLME_GET.confirm(MAC_SUCCESS,PIBAttribute,&mac_PIB.macPromiscuousMode); + break; + case MACRXONWHENIDLE: signal MLME_GET.confirm(MAC_SUCCESS,PIBAttribute,&mac_PIB.macRxOnWhenIdle); + break; + case MACSHORTADDRESS: signal MLME_GET.confirm(MAC_SUCCESS,PIBAttribute,(uint8_t *) &mac_PIB.macShortAddress); + break; + case MACSUPERFRAMEORDER: signal MLME_GET.confirm(MAC_SUCCESS,PIBAttribute,&mac_PIB.macSuperframeOrder); + break; + case MACTRANSACTIONPERSISTENCETIME: signal MLME_GET.confirm(MAC_SUCCESS,PIBAttribute,(uint8_t *) &mac_PIB.macTransactionPersistenceTime); + break; + + default: signal MLME_GET.confirm(MAC_UNSUPPORTED_ATTRIBUTE,PIBAttribute,0x00); + break; + } + +return SUCCESS; +} + +/*********************************************************/ +/**************MLME_SET***********************************/ +/*********************************************************/ +command error_t MLME_SET.request(uint8_t PIBAttribute,uint8_t PIBAttributeValue[]) +{ + +//int i; + +////printfUART("set %i\n",PIBAttribute); + +atomic{ + + switch(PIBAttribute) + { + + + case MACACKWAITDURATION : mac_PIB.macAckWaitDuration = PIBAttributeValue[0]; + ////////////printfUART("mac_PIB.macAckWaitDuration: %x\n",mac_PIB.macAckWaitDuration); + signal MLME_SET.confirm(MAC_SUCCESS,PIBAttribute); + break; + + case MACASSOCIATIONPERMIT: if ((uint8_t)PIBAttributeValue[1] == 0x00) + { + mac_PIB.macAssociationPermit = 0x00; + } + else + { + mac_PIB.macAssociationPermit = 0x01; + } + //////////printfUART("mac_PIB.macAssociationPermit: %i %y\n",mac_PIB.macAssociationPermit,PIBAttributeValue[1]); + signal MLME_SET.confirm(MAC_SUCCESS,PIBAttribute); + break; + + case MACAUTOREQUEST : mac_PIB.macAutoRequest = PIBAttributeValue[0]; + ////////////printfUART("mac_PIB.macAutoRequest: %i\n",mac_PIB.macAutoRequest); + signal MLME_SET.confirm(MAC_SUCCESS,PIBAttribute); + break; + + case MACBATTLIFEEXT: mac_PIB.macBattLifeExt = PIBAttributeValue[0]; + ////////////printfUART("mac_PIB.macBattLifeExt %i\n",mac_PIB.macBattLifeExt); + signal MLME_SET.confirm(MAC_SUCCESS,PIBAttribute); + break; + case MACBATTLIFEEXTPERIODS: mac_PIB.macBattLifeExtPeriods = PIBAttributeValue[0]; + ////////////printfUART("mac_PIB.macBattLifeExtPeriods %i\n",mac_PIB.macBattLifeExtPeriods); + signal MLME_SET.confirm(MAC_SUCCESS,PIBAttribute); + break; + + case MACBEACONPAYLOAD: /*for(i=0;i < mac_PIB.macBeaconPayloadLenght;i++) + { + mac_PIB.macBeaconPayload[i] = PIBAttributeValue[i]; + }*/ + + memcpy(&PIBAttributeValue[0],&mac_PIB.macBeaconPayload[0],mac_PIB.macBeaconPayloadLenght * sizeof(uint8_t)); + + signal MLME_SET.confirm(MAC_SUCCESS,PIBAttribute); + break; + + case MACMAXBEACONPAYLOADLENGTH: mac_PIB.macBeaconPayloadLenght = PIBAttributeValue[0]; + ////////////printfUART("mac_PIB.macBeaconPayloadLenght %i\n",mac_PIB.macBeaconPayloadLenght); + signal MLME_SET.confirm(MAC_SUCCESS,PIBAttribute); + break; + + case MACBEACONORDER: mac_PIB.macBeaconOrder = PIBAttributeValue[0]; + ////////////printfUART("mac_PIB.macBeaconOrder %i\n",mac_PIB.macBeaconOrder); + signal MLME_SET.confirm(MAC_SUCCESS,PIBAttribute); + break; + case MACBEACONTXTIME: mac_PIB.macBeaconTxTime =PIBAttributeValue[0]; + ////////////printfUART("mac_PIB.macBeaconTxTime %i\n",mac_PIB.macBeaconTxTime); + signal MLME_SET.confirm(MAC_SUCCESS,PIBAttribute); + break; + case MACBSN: mac_PIB.macBSN = PIBAttributeValue[0]; + ////////////printfUART("mac_PIB.macBSN %i\n",mac_PIB.macBSN); + signal MLME_SET.confirm(MAC_SUCCESS,PIBAttribute); + break; + + case MACCOORDEXTENDEDADDRESS: //mac_PIB.macCoordExtendedAddress0 = ((PIBAttributeValue[0] >> 24) | (PIBAttributeValue[1] >> 16) | (PIBAttributeValue[2] >> 8) | (PIBAttributeValue[3])) ; + //mac_PIB.macCoordExtendedAddress1 = ((PIBAttributeValue[4] >> 24) | (PIBAttributeValue[5] >> 16) | (PIBAttributeValue[6] >> 8) | (PIBAttributeValue[7])); + + ////////////printfUART("mac_PIB.macCoordExtendedAddress0 %y\n",mac_PIB.macCoordExtendedAddress0); + ////////////printfUART("mac_PIB.macCoordExtendedAddress1 %y\n",mac_PIB.macCoordExtendedAddress1); + signal MLME_SET.confirm(MAC_SUCCESS,PIBAttribute); + break; + + + case MACCOORDSHORTADDRESS: mac_PIB.macCoordShortAddress= ((PIBAttributeValue[0] << 8) |PIBAttributeValue[1]); + ////printfUART("mac_PIB.macCoordShortAddress: %x\n",mac_PIB.macCoordShortAddress); + signal MLME_SET.confirm(MAC_SUCCESS,PIBAttribute); + break; + + case MACDSN: mac_PIB.macDSN = PIBAttributeValue[0]; + ////////////printfUART("mac_PIB.macDSN: %x\n",mac_PIB.macDSN); + signal MLME_SET.confirm(MAC_SUCCESS,PIBAttribute); + break; + case MACGTSPERMIT: mac_PIB.macGTSPermit = PIBAttributeValue[0]; + ////////////printfUART("mac_PIB.macGTSPermit: %x\n",mac_PIB.macGTSPermit); + signal MLME_SET.confirm(MAC_SUCCESS,PIBAttribute); + break; + case MACMAXCSMABACKOFFS: mac_PIB.macMaxCSMABackoffs = PIBAttributeValue[0]; + ////////////printfUART("mac_PIB.macMaxCSMABackoffs: %x\n",mac_PIB.macMaxCSMABackoffs); + signal MLME_SET.confirm(MAC_SUCCESS,PIBAttribute); + break; + case MACMINBE: mac_PIB.macMinBE = PIBAttributeValue[0]; + ////////////printfUART("mac_PIB.macMinBE: %x\n",mac_PIB.macMinBE); + signal MLME_SET.confirm(MAC_SUCCESS,PIBAttribute); + break; + + case MACPANID: mac_PIB.macPANId = ((PIBAttributeValue[0] << 8)| PIBAttributeValue[1]); + ////printfUART("mac_PIB.macPANId: %x\n",mac_PIB.macPANId); + + + call AddressFilter.set_coord_address(mac_PIB.macCoordShortAddress, mac_PIB.macPANId); + + + signal MLME_SET.confirm(MAC_SUCCESS,PIBAttribute); + break; + + case MACPROMISCUOUSMODE: mac_PIB.macPromiscuousMode = PIBAttributeValue[0]; + ////////////printfUART("mac_PIB.macPromiscuousMode: %x\n",mac_PIB.macPromiscuousMode); + signal MLME_SET.confirm(MAC_SUCCESS,PIBAttribute); + break; + case MACRXONWHENIDLE: mac_PIB.macRxOnWhenIdle = PIBAttributeValue[0]; + ////////////printfUART("mac_PIB.macRxOnWhenIdle: %x\n",mac_PIB.macRxOnWhenIdle); + signal MLME_SET.confirm(MAC_SUCCESS,PIBAttribute); + break; + + + case MACSHORTADDRESS: mac_PIB.macShortAddress = ((PIBAttributeValue[0] << 8) |PIBAttributeValue[1]); + ////printfUART("mac_PIB.macShortAddress: %y\n",mac_PIB.macShortAddress); + + call AddressFilter.set_address(mac_PIB.macShortAddress, aExtendedAddress0, aExtendedAddress0); + + + signal MLME_SET.confirm(MAC_SUCCESS,PIBAttribute); + break; + + case MACSUPERFRAMEORDER: mac_PIB.macSuperframeOrder = PIBAttributeValue[0]; + ////////////printfUART("mac_PIB.macSuperframeOrder: %x\n",mac_PIB.macSuperframeOrder); + signal MLME_SET.confirm(MAC_SUCCESS,PIBAttribute); + break; + + case MACTRANSACTIONPERSISTENCETIME: mac_PIB.macTransactionPersistenceTime = PIBAttributeValue[0]; + ////////////printfUART("mac_PIB.macTransactionPersistenceTime: %y\n",mac_PIB.macTransactionPersistenceTime); + signal MLME_SET.confirm(MAC_SUCCESS,PIBAttribute); + break; + + default: signal MLME_SET.confirm(MAC_UNSUPPORTED_ATTRIBUTE,PIBAttribute); + break; + + + } + +} + +return SUCCESS; +} +/*************************************************************/ +/************** MCPS - DATA *******************/ +/*************************************************************/ + +command error_t MCPS_DATA.request(uint8_t SrcAddrMode, uint16_t SrcPANId, uint32_t SrcAddr[], uint8_t DstAddrMode, uint16_t DestPANId, uint32_t DstAddr[], uint8_t msduLength, uint8_t msdu[],uint8_t msduHandle, uint8_t TxOptions) +{ + int i; + //uint8_t valid_gts=0; + uint32_t total_ticks; + + ////////printfUART("MCPS_DATA.request\n", ""); + //check conditions on page 58 + + //atomic mac_PIB.macShortAddress = TOS_LOCAL_ADDRESS; + + /* + ////printfUART("SrcAddrMode %x\n", SrcAddrMode); + ////printfUART("SrcPANId %x\n", SrcPANId); + ////printfUART("SrcAddr %x\n", SrcAddr[0]); + ////printfUART("SrcAddr %x\n", SrcAddr[1]); + ////printfUART("DstAddrMode %x\n", DstAddrMode); + ////printfUART("DestPANId %x\n", DestPANId); + ////printfUART("DstAddr %x\n", DstAddr[0]); + ////printfUART("DstAddr %x\n", DstAddr[1]); + ////printfUART("msduLength %x\n", msduLength); + ////printfUART("msduHandle %x\n", msduHandle); + ////printfUART("TxOptions %x\n", TxOptions); + */ + + atomic{ + + if (mac_PIB.macShortAddress == 0xffff) + return FAIL; + } + + if(PANCoordinator == 1) + { + //PAN COORDINATOR OPERATION + //////////////printfUART("GTS TRANS: %i TxOptions: %u dest:%u\n", get_txoptions_gts(TxOptions),TxOptions,DstAddr[1]); + + if (get_txoptions_gts(TxOptions) == 1) + { + //GTS TRANSMISSION + for (i=0 ; i < 7 ; i++) + { + //SEARCH FOR A VALID GTS + if ( GTS_db[i].DevAddressType == (uint16_t)DstAddr[1] && GTS_db[i].direction == 1 && GTS_db[i].gts_id != 0) + { + + //atomic{ + //////////////printfUART("BUFFER UNTIL GTS SLOT n: %i ss: %i\n",number_time_slot,GTS_db[valid_gts].starting_slot); + create_data_frame(SrcAddrMode, SrcPANId, SrcAddr, DstAddrMode, DestPANId, DstAddr, msduLength, msdu, msduHandle, TxOptions,GTS_db[i].starting_slot,1); + //} + return SUCCESS; + break; + } + } + signal MCPS_DATA.confirm(msduHandle, MAC_INVALID_GTS); + return FAIL; + } + else + { + //NORMAL/INDIRECT TRANSMISSION + + //////////////printfUART("IND TRANS: %i TxOptions: %u\n", get_txoptions_indirect_transmission(TxOptions),TxOptions); + //check if its an indirect transmission + //if ( get_txoptions_indirect_transmission(TxOptions) == 1) + //{ + //INDIRECT TRANSMISSION + + //////////////printfUART("CREATE INDIRECT TRANSMISSION\n",""); + + + + + //} + //else + //{ + //NORMAL TRANSMISSION + ////printfUART("SEND NO GTS NO IND\n",""); + create_data_frame(SrcAddrMode, SrcPANId, SrcAddr, DstAddrMode, DestPANId, DstAddr, msduLength, msdu, msduHandle, TxOptions,0,0); + //} + } + } + else + { + //NON PAN COORDINATOR OPERATION + atomic{ + + //////////////printfUART("sslot: %i ini %i\n",s_GTSss,init_s_GTSss); + //check if it a gts transmission + if (get_txoptions_gts(TxOptions) == 1) + { + //GTS TRANSMISSION + if (s_GTSss == 0x00) + { + //////////////printfUART("NO VALID GTS \n",""); + signal MCPS_DATA.confirm(msduHandle, MAC_INVALID_GTS); + } + else + { + total_ticks = call TimerAsync.get_total_tick_counter(); + msdu[0] =(uint8_t)(total_ticks >> 0 ); + msdu[1] =(uint8_t)(total_ticks >> 8); + msdu[2] =(uint8_t)(total_ticks >> 16); + msdu[3] =(uint8_t)(total_ticks >> 24); + + if (on_sync == 1 && s_GTSss > 0) + create_data_frame(SrcAddrMode, SrcPANId, SrcAddr, DstAddrMode, DestPANId, DstAddr, msduLength, msdu, msduHandle, TxOptions,s_GTSss,0); + } + } + else + { + //NORMAL TRANSMISSION + //printfUART("TRnsm\n",""); + create_data_frame(SrcAddrMode, SrcPANId, SrcAddr, DstAddrMode, DestPANId, DstAddr, msduLength, msdu, msduHandle, TxOptions,0,0); + } + } + } + return SUCCESS; +} + + + + +/*************************************************************/ +/************** MCPS - PURGE *******************/ +/*************************************************************/ + +command error_t MCPS_PURGE.request(uint8_t msduHandle) +{ + + + +return SUCCESS; +} + +/*****************************************************************************************************/ +/*****************************************************************************************************/ +/*****************************************************************************************************/ +/************************ OTHER FUNCTIONS **********************************/ +/*****************************************************************************************************/ +/*****************************************************************************************************/ +/*****************************************************************************************************/ + +task void signal_loss() +{ + //TODO + atomic signal MLME_SYNC_LOSS.indication(beacon_loss_reason); //MAC_BEACON_LOSS + return; +} + +//inicialization of the mac constants +void init_MacCon() +{ +/*****************************************************/ +/* Boolean Variables */ +/*****************************************************/ +PANCoordinator = 0; +//(0 NO beacon transmission; 1 beacon transmission); +Beacon_enabled_PAN = 0; +//(SYNC)the device will try to track the beacon ie enable its receiver just before the espected time of each beacon +TrackBeacon=0; +//(SYNC)the device will try to locate one beacon +findabeacon=0; +//(RESET) when the reset command arrives it checks whether or not to reset the PIB +SetDefaultPIB=0; +/*****************************************************/ +/* Integer Variables */ +/*****************************************************/ +/* +//Beacon Interval +uint32_t BI; +//Superframe duration +uint32_t SD; +*/ +//(SYNC)number of beacons lost before sending a Beacon-Lost indication comparing to aMaxLostBeacons +missed_beacons=0; +//current_channel +current_channel=0; + + +/*****************************************************/ +/* Other Variables */ +/*****************************************************/ +pending_reset=0; + +} + +//inicialization of the mac PIB +void init_MacPIB() +{ + +atomic{ + //mac PIB default values + + //mac_PIB.macAckWaitDuration = 54; OLD VALUE//Number os symbols to wait for an acknowledgment + mac_PIB.macAckWaitDuration = 65; + + mac_PIB.macAssociationPermit = 1; //1 - PAN allowing associations + mac_PIB.macAutoRequest = 1; //indication if a device automatically sends a data request command if address is listed in the beacon frame + + mac_PIB.macBattLifeExt= 0; //batery life extension CSMA-CA + + mac_PIB.macBattLifeExtPeriods=6; + //mac_PIB.macBeaconPayload; //payload of the beacon + mac_PIB.macBeaconPayloadLenght=0; //beacon payload lenght + + mac_PIB.macBeaconTxTime=(0xffffff << 24); //***** + + + mac_PIB.macBSN=call Random.rand16(); //sequence number of the beacon frame + + + mac_PIB.macCoordExtendedAddress0 = 0x00000000; //64bits address of the coordinator with witch the device is associated + mac_PIB.macCoordExtendedAddress1 = 0x00000000; + + mac_PIB.macCoordShortAddress = 0x0000; //16bits address of the coordinator with witch the device is associated + + /* + if (DEVICE_DEPTH == 0x01) + mac_PIB.macCoordShortAddress =D1_PAN_SHORT; + if (DEVICE_DEPTH == 0x02) + mac_PIB.macCoordShortAddress =D2_PAN_SHORT; + if (DEVICE_DEPTH == 0x03) + mac_PIB.macCoordShortAddress =D3_PAN_SHORT; + if (DEVICE_DEPTH == 0x04) + mac_PIB.macCoordShortAddress =D4_PAN_SHORT; + */ + + mac_PIB.macDSN=call Random.rand16(); //sequence number of the transmited data or MAC command frame + + //alowing gts requests (used in beacon) + mac_PIB.macGTSPermit=1; // + + //Number of maximum CSMA backoffs + mac_PIB.macMaxCSMABackoffs=4; + mac_PIB.macMinBE=0; + + //mac_PIB.macPANId=0xffff; //16bits identifier of the PAN on witch this device is operating + mac_PIB.macPANId = MAC_PANID; + + mac_PIB.macPromiscuousMode=0; + mac_PIB.macRxOnWhenIdle=0; + + //mac_PIB.macShortAddress=TOS_LOCAL_ADDRESS; //16bits short address + mac_PIB.macShortAddress=0xffff; + + + mac_PIB.macBeaconOrder=7; //specification of how often the coordinator transmits a beacon + mac_PIB.macSuperframeOrder=3; + + //default mac_PIB.macTransactionPersistenceTime=0x01f4; + mac_PIB.macTransactionPersistenceTime=0x0010; + + //******************************************* + + } +} + +////////////////////////////////////////////////////////////// +////////////////////////CSMA-CA functions//////////////////// +///////////////////////////////////////////////////////////// + +/*****************************************************/ +/* SEND FRAME FUNCTION */ +/*****************************************************/ + +task void send_frame_csma() +{ + atomic{ + + // + /////printfUART("I_AM_IN_IP %i %i\n",I_AM_IN_IP,send_buffer_count); + + if ((send_buffer_count > 0 && send_buffer_count <= SEND_BUFFER_SIZE && performing_csma_ca == 0) || I_AM_IN_IP != 0) + { + //////printfUART("sf %i\n",send_buffer_count); + ////////printfUART("peform\n",""); + + performing_csma_ca = 1; + + perform_csma_ca(); + } + else + { + ////printfUART("NOT SEND\n",""); + } + + + } + +} + + +task void perform_csma_ca_slotted() +{ + uint8_t random_interval; + + + + //DEFERENCE CHANGE + if (check_csma_ca_send_conditions(send_buffer[send_buffer_msg_out].length,send_buffer[send_buffer_msg_out].frame_control1) == 1 ) + { + cca_deference = 0; + } + else + { + //nao e necessario + cca_deference = 1; + return; + } + + atomic{ + ////printfUART("CCA: %i\n", call CCA.get()) ; + + if(call CCA.get() == CCA_BUSY ) + { + //////////////printfUART("CCA: 1\n", "") ; + //STEP 5 + CW--; + if (CW == 0 ) + { + //send functions + csma_cca_backoff_boundary =0; + + ////////printfUART("rts %i\n",get_ack_request(send_buffer[send_buffer_msg_out].frame_control)); + + //verify if the message must be ack + if ( get_fc1_ack_request(send_buffer[send_buffer_msg_out].frame_control1) == 1 ) + { + send_ack_check=1; + ack_sequence_number_check=send_buffer[send_buffer_msg_out].seq_num; + //verify retransmission + send_retransmission = send_buffer[send_buffer_msg_out].retransmission; + //verify if its an indirect transmission + send_indirect_transmission = send_buffer[send_buffer_msg_out].indirect; + //SEND WITH ACK_REQUEST + call PD_DATA.request(send_buffer[send_buffer_msg_out].length,(uint8_t *)&send_buffer[send_buffer_msg_out]); + + ////////printfUART("out ck\n",""); + + + call T_ackwait.startOneShot(ackwait_period); + } + else + { + + call PD_DATA.request(send_buffer[send_buffer_msg_out].length,(uint8_t *)&send_buffer[send_buffer_msg_out]); + + send_buffer_count --; + send_buffer_msg_out++; + + //failsafe + if(send_buffer_count > SEND_BUFFER_SIZE) + { + send_buffer_count =0; + send_buffer_msg_out=0; + send_buffer_msg_in=0; + } + + if (send_buffer_msg_out == SEND_BUFFER_SIZE) + send_buffer_msg_out=0; + + if (send_buffer_count > 0 && send_buffer_count <= SEND_BUFFER_SIZE) + post send_frame_csma(); + + ////printfUART("sk %i\n",send_buffer_count); + + //////////printfUART("%i %i %i\n",send_buffer_count,send_buffer_msg_in,send_buffer_msg_out); + } + + performing_csma_ca = 0; + } + } + else + { + //CHECK NOT USED + //csma_backoff_counter++; + //csma_backoff_counter_inst++; + + if (NB < mac_PIB.macMaxCSMABackoffs) + { + ////////////printfUART("NB:%i BE:%i L CW: %i\n",NB,BE,CW); + //STEP 4 + CW = 2; + NB++; + BE = min(BE+1,aMaxBE); + + //STEP 2 + //random_interval = pow(2,BE) - 1; + + //delay_backoff_period = (call Random.rand() & random_interval); + //verification of the backoff_deference + //DEFERENCE CHANGE + if (backoff_deference == 0) + { + random_interval = powf(2,BE) - 1; + delay_backoff_period = (call Random.rand16() & random_interval ); + + if (check_csma_ca_backoff_send_conditions((uint32_t) delay_backoff_period) == 1) + { + backoff_deference = 1; + } + } + else + { + backoff_deference = 0; + } + + + //delay_backoff_period=0; + + ////printfUART("delay_backoff_period:%i\n",delay_backoff_period); + csma_delay=1; + } + else + { + //CSMA/CA FAIL + csma_delay=0; + csma_cca_backoff_boundary=0; + + send_buffer_count --; + send_buffer_msg_out++; + + //failsafe + if(send_buffer_count > SEND_BUFFER_SIZE) + { + send_buffer_count =0; + send_buffer_msg_out=0; + send_buffer_msg_in=0; + } + + if (send_buffer_msg_out == SEND_BUFFER_SIZE) + send_buffer_msg_out=0; + + if (send_buffer_count > 0 && send_buffer_count <= SEND_BUFFER_SIZE) + post send_frame_csma(); + + performing_csma_ca = 0; + + ////printfUART("SLOTTED FAIL\n",""); + /* + if(associating == 1) + { + associating=0; + signal MLME_ASSOCIATE.confirm(0x0000,MAC_CHANNEL_ACCESS_FAILURE); + }*/ + } + } + } +return; +} + +task void perform_csma_ca_unslotted() +{ + uint8_t random_interval; + + atomic{ + if (NB < mac_PIB.macMaxCSMABackoffs) + { + //STEP 3 + //perform CCA + ////////////printfUART("CCA: %i\n", TOSH_READ_CC_CCA_PIN()) ; + + //if CCA is clear send message + if(call CCA.get() == CCA_BUSY) + { + //send functions + ////////////printfUART("UNSLOTTED SUCCESS\n",""); + atomic{ + csma_delay =0; + + + + if (check_csma_ca_send_conditions(send_buffer[send_buffer_msg_out].length,send_buffer[send_buffer_msg_out].frame_control1) == 1 ) + { + call PD_DATA.request(send_buffer[send_buffer_msg_out].length,(uint8_t *)&send_buffer[send_buffer_msg_out]); + + send_buffer_count --; + send_buffer_msg_out++; + + //failsafe + if(send_buffer_count > SEND_BUFFER_SIZE) + { + send_buffer_count =0; + send_buffer_msg_out=0; + send_buffer_msg_in=0; + } + + if (send_buffer_msg_out == SEND_BUFFER_SIZE) + send_buffer_msg_out=0; + } + + + performing_csma_ca =0; + + } + return; //SUCCESS + + } + + //CCA is not clear, perform new iteration of the CSMA/CA UNSLOTTED + + //STEP 4 + NB++; + BE = min(BE+1,aMaxBE); + + ////////////printfUART("NB:%i BE:%i\n",NB,BE); + + //STEP 2 + //#ifdef PLATFORM_MICAZ + random_interval = powf(2,BE) - 1; + //#else + // random_interval = powf(2,BE) - 1; + //#endif + delay_backoff_period = (call Random.rand16() & random_interval ); + //delay_backoff_period=1; + csma_delay=1; + + //////////////printfUART("delay_backoff_period:%i\n",delay_backoff_period); + } + else + { + atomic csma_delay=0; + ////////////printfUART("UNSLOTTED FAIL\n",""); + } + } +return; +} + + +void perform_csma_ca() +{ + uint8_t random_interval; + csma_slotted=1; + //STEP 1 + if (csma_slotted == 0 ) + { + atomic{ + //UNSLOTTED version + init_csma_ca(csma_slotted); + //STEP 2 + random_interval = powf(2,BE) - 1; + delay_backoff_period = (call Random.rand16() & random_interval ); + + csma_delay=1; + ////////////printfUART("delay_backoff_period:%i\n",delay_backoff_period); + } + return; + } + else + { + //SLOTTED version + atomic{ + //DEFERENCE CHANGE + if (cca_deference==0) + { + init_csma_ca(csma_slotted); + if (mac_PIB.macBattLifeExt == 1 ) + { + BE = min(2, mac_PIB.macMinBE); + } + else + { + BE = mac_PIB.macMinBE; + } + csma_locate_backoff_boundary = 1; + } + else + { + cca_deference = 0; + csma_delay=0; + csma_locate_backoff_boundary=0; + csma_cca_backoff_boundary = 1; + + } + } + return; + } +} + + +uint8_t min(uint8_t val1, uint8_t val2) +{ + if (val1 < val2) + { + return val1; + } + else + { + return val2; + } +} + +void init_csma_ca(bool slotted) +{ + +//initialization of the CSMA/CA protocol variables + //////////////printfUART("init_csma_ca\n", "") ; + + csma_delay=0; + + if (slotted == 0 ) + { + NB=0; + BE=mac_PIB.macMinBE; + } + else + { + NB=0; + CW=2; + + csma_cca_backoff_boundary=0; + csma_locate_backoff_boundary=0; + } + +return; +} + + +uint8_t calculate_ifs(uint8_t pk_length) +{ + if (pk_length > aMaxSIFSFrameSize) + return aMinLIFSPeriod; // + ( ((pk_length * 8) / 250.00) / 0.34 ); + else + return aMinSIFSPeriod; // + ( ((pk_length * 8) / 250.00) / 0.34 ); +} + +uint32_t calculate_gts_expiration() +{ + uint32_t exp_res; + if( mac_PIB.macBeaconOrder > 9 ) + exp_res= 1; + else + { + //#ifdef PLATFORM_MICAZ + exp_res= powf(2,(8-mac_PIB.macBeaconOrder)); + //#else + // exp_res= powf(2,(8-mac_PIB.macBeaconOrder)); + //#endif + } + ////////////printfUART("alculat %i\n",exp_res ) ; + return exp_res; +} + +uint8_t check_csma_ca_send_conditions(uint8_t frame_length,uint8_t frame_control1) +{ + uint8_t ifs_symbols; + uint32_t frame_tx_time; + uint32_t remaining_gts_duration; + + + ifs_symbols=calculate_ifs(frame_length); + //wait_ifs=1; + //call TimerAsync.set_ifs_symbols(ifs_symbols); + + //////////////printfUART("ifs_symbols %i\n",ifs_symbols ) ; + + if (get_fc1_ack_request(frame_control1) == 1 ) + frame_tx_time = frame_length + ACK_LENGTH + aTurnaroundTime + ifs_symbols; + else + frame_tx_time = frame_length + ifs_symbols; + + atomic remaining_gts_duration = time_slot - ( call TimerAsync.get_current_number_backoff_on_time_slot() * aUnitBackoffPeriod); + + //////////////printfUART("frame_tx %d remaing %d\n",frame_tx_time,remaining_gts_duration ) ; + + if (frame_tx_time < remaining_gts_duration) + return 1; + else + return 0; + +} + +//DEFERENCE CHANGE +uint8_t check_csma_ca_backoff_send_conditions(uint32_t delay_backoffs) +{ + + uint32_t number_of_sd_ticks=0; + uint32_t current_ticks=0; + uint32_t ticks_remaining =0; + uint32_t number_of_backoffs_remaining =0; + + number_of_sd_ticks = call TimerAsync.get_sd_ticks(); + + current_ticks = call TimerAsync.get_current_ticks(); + + ticks_remaining = number_of_sd_ticks - current_ticks; + + number_of_backoffs_remaining = ticks_remaining / 5; + + if (number_of_backoffs_remaining > delay_backoffs) + return 0; + else + return 1; + + + +} + +uint8_t check_gts_send_conditions(uint8_t frame_length) +{ + uint8_t ifs_symbols; + uint32_t frame_tx_time; + uint32_t remaining_gts_duration; + + + ifs_symbols=calculate_ifs(frame_length); + //wait_ifs=1; + //call TimerAsync.set_ifs_symbols(ifs_symbols); + + //////////////printfUART("ifs_symbols %i\n",ifs_symbols ) ; + + frame_tx_time = frame_length + ACK_LENGTH + aTurnaroundTime + ifs_symbols; + + remaining_gts_duration = time_slot - ( call TimerAsync.get_current_number_backoff_on_time_slot() * aUnitBackoffPeriod); + + //////////////printfUART("frame_tx %d remaing %d\n",frame_tx_time,remaining_gts_duration ) ; + + if (frame_tx_time < remaining_gts_duration) + return 1; + else + return 0; +} + +////////////////////////////////////////////////////////////// +////////////////////////GTS functions//////////////////////// +///////////////////////////////////////////////////////////// + +void init_GTS_db() +{ + //initialization of the GTS database + int i; +atomic{ + for (i=0 ; i < 7 ; i++) + { + GTS_db[i].gts_id=0x00; + GTS_db[i].starting_slot=0x00; + GTS_db[i].length=0x00; + GTS_db[i].direction=0x00; + GTS_db[i].DevAddressType=0x0000; + + } + } +return; +} + +error_t remove_gts_entry(uint16_t DevAddressType) +{ + uint8_t r_lenght=0; + //int r_start_slot=7; + int i; + + atomic{ + for (i=0; i < 7 ; i++) + { + if( GTS_db[i].DevAddressType == DevAddressType ) + { + + r_lenght = GTS_db[i].length; + //r_start_slot = i; + //delete the values + GTS_db[i].gts_id=0x00; + GTS_db[i].starting_slot=0x00; + GTS_db[i].length=0x00; + GTS_db[i].direction=0x00; + GTS_db[i].DevAddressType=0x0000; + GTS_db[i].expiration=0x00; + + //////////////printfUART("GTS Entry removed dev:%i len:%i pos %i\n", DevAddressType,r_lenght,i); + GTS_startslot = GTS_startslot + r_lenght; + GTS_descriptor_count--; + final_CAP_slot = final_CAP_slot + r_lenght; + } + + if ( r_lenght > 0) + { + if ( GTS_db[i].gts_id != 0x00 && GTS_db[i].DevAddressType !=0x0000) + { + GTS_db[i-r_lenght].gts_id = GTS_db[i].gts_id; + GTS_db[i-r_lenght].starting_slot = i-r_lenght; + GTS_db[i-r_lenght].length = GTS_db[i].length; + GTS_db[i-r_lenght].direction = GTS_db[i].direction; + GTS_db[i-r_lenght].DevAddressType = GTS_db[i].DevAddressType; + GTS_db[i-r_lenght].expiration = GTS_db[i].expiration; + + //delete the values + GTS_db[i].gts_id=0x00; + GTS_db[i].starting_slot=0x00; + GTS_db[i].length=0x00; + GTS_db[i].direction=0x00; + GTS_db[i].DevAddressType=0x0000; + GTS_db[i].expiration=0x00; + + //////////////printfUART("UPDATED\n","" ); + } + } + } + } +return SUCCESS; +} + +error_t add_gts_entry(uint8_t gts_length,bool direction,uint16_t DevAddressType) +{ + int i; + //////////////printfUART("ADDING gts_length: %i\n", gts_length); + //////////////printfUART("dir: %i\n", direction); + //////////////printfUART("addr: %i\n", DevAddressType); + + //check aMinCAPLength + if ( (GTS_startslot - gts_length) < 5 ) + { + //////////////printfUART("ADD FAIL%i\n", ""); + + } + + //if it has more than 7 timeslots alocated + if ( (GTS_startslot -gts_length) < 9 ) + { + return FAIL; + } + + //check if the address already exists in the GTS list + for (i=0 ; i < 7 ; i++) + { + if ( GTS_db[i].DevAddressType == DevAddressType && GTS_db[i].direction == direction && GTS_db[i].gts_id > 0) + { + //////////////printfUART("ALREADY ADDED\n", ""); + return FAIL; + } + if ( GTS_null_db[i].DevAddressType == DevAddressType && GTS_null_db[i].gts_id > 0) + { + //////////////printfUART("REJECTED\n", ""); + return FAIL; + } + + + } + +atomic{ + + //////////////printfUART("GTS_startslot: %i\n", GTS_startslot); + GTS_startslot = GTS_startslot - gts_length; + + GTS_db[15-GTS_startslot].gts_id=GTS_id; + GTS_db[15-GTS_startslot].starting_slot=GTS_startslot; + GTS_db[15-GTS_startslot].length=gts_length; + GTS_db[15-GTS_startslot].direction=direction; + GTS_db[15-GTS_startslot].DevAddressType=DevAddressType; + GTS_db[15-GTS_startslot].expiration=0x00; + + //////////////printfUART("GTS Entry added start:%i len:%i\n", GTS_startslot,gts_length); + + GTS_id++; + GTS_descriptor_count++; + + final_CAP_slot = final_CAP_slot - gts_length; + + } + return SUCCESS; +} + + +//GTS null functions +void init_GTS_null_db() +{ + //initialization of the GTS database + int i; + atomic{ + for (i=0 ; i < 7 ; i++) + { + GTS_null_db[i].gts_id=0x00; + GTS_null_db[i].starting_slot=0x00; + GTS_null_db[i].length=0x00; + //GTS_null_db[i].direction=0x00; + GTS_null_db[i].DevAddressType=0x0000; + GTS_null_db[i].persistencetime=0x00; + } + } +return; +} + + +error_t add_gts_null_entry(uint8_t gts_length,bool direction,uint16_t DevAddressType) +{ + int i; + + //check if the address already exists in the GTS list + for (i=0 ; i < 7 ; i++) + { + if ( GTS_null_db[i].DevAddressType == DevAddressType && GTS_null_db[i].gts_id > 0) + { + //////////////printfUART("ALREADY ADDED null\n", ""); + return FAIL; + } + } + + for (i=0 ; i < 7 ; i++) + { + if ( GTS_null_db[i].DevAddressType==0x0000 && GTS_null_db[i].gts_id == 0x00) + { + GTS_null_db[i].gts_id=GTS_id; + GTS_null_db[i].starting_slot=0x00; + GTS_null_db[i].length=0x00; + //GTS_null_db[i].direction=0x00; + GTS_null_db[i].DevAddressType=DevAddressType; + GTS_null_db[i].persistencetime=0x00; + + + //////////////printfUART("GTS null Entry added addr:%x\n", DevAddressType); + + GTS_id++; + GTS_null_descriptor_count++; + + return SUCCESS; + } + } + + +return FAIL; +} + +task void increment_gts_null() +{ + int i; + + //////////////printfUART("init inc\n",""); +atomic{ + for (i=0 ; i < 7 ; i++) + { + if ( GTS_null_db[i].DevAddressType != 0x0000 && GTS_null_db[i].gts_id != 0x00) + { + //////////////printfUART("increm %x\n", GTS_null_db[i].DevAddressType); + GTS_null_db[i].persistencetime++; + + } + + if ( GTS_null_db[i].persistencetime > (aGTSDescPersistenceTime -1) ) + { + GTS_null_db[i].gts_id=0x00; + GTS_null_db[i].starting_slot=0x00; + GTS_null_db[i].length=0x00; + //GTS_null_db[i].direction=0x00; + GTS_null_db[i].DevAddressType=0x0000; + GTS_null_db[i].persistencetime=0x00; + + //////////////printfUART("GTS null removed addr:%x\n", GTS_null_db[i].DevAddressType); + + atomic GTS_null_descriptor_count--; + } + + } + + } +//////////////printfUART("end inc\n",""); +return; +} + +task void check_gts_expiration() +{ + int i; +//////////////printfUART("init exp\n",""); +atomic{ + atomic gts_expiration=calculate_gts_expiration(); + //////////////printfUART("gts_expiration:%i\n", gts_expiration); + atomic gts_expiration=2; + //////////////printfUART("gts_expiration:%i\n", gts_expiration); + + for (i=0 ; i < 7 ; i++) + { + + if ( GTS_db[i].DevAddressType != 0x0000 && GTS_db[i].gts_id != 0x00) + { + if( GTS_db[i].expiration == (gts_expiration + 1) && GTS_db[i].direction ==0x00) + { + //////////////printfUART("GTS expired addr:%x\n", GTS_null_db[i].DevAddressType); + //remove gts, indicate on the gts null list + atomic{ + + add_gts_null_entry(GTS_db[i].length,GTS_db[i].direction,GTS_db[i].DevAddressType); + + remove_gts_entry(GTS_db[i].DevAddressType); + } + } + else + { + atomic GTS_db[i].expiration ++; + } + } + } + + + } + //////////////printfUART("end exp\n",""); +return; +} + +void init_available_gts_index() + { + int i=0; + atomic{ + available_gts_index_count = GTS_SEND_BUFFER_SIZE; + for(i=0;i < GTS_SEND_BUFFER_SIZE;i++) + { + available_gts_index[i]=i; + } + } + return; + } +/*****************************GTS BUFFER******************************/ +void init_gts_slot_list() +{ + int i=0; + for(i=0;i<7;i++) + { + gts_slot_list[i].element_count = 0x00; + gts_slot_list[i].element_in = 0x00; + gts_slot_list[i].element_out = 0x00; + } +} + + +task void start_coordinator_gts_send() +{ +atomic{ + + coordinator_gts_send_pending_data =0; + + if(gts_slot_list[15-number_time_slot].element_count > 0) + { + if (check_gts_send_conditions(gts_send_buffer[gts_slot_list[15-number_time_slot].gts_send_frame_index[gts_slot_list[15-number_time_slot].element_out]].length) == 1 ) + { + + gts_send_buffer[gts_slot_list[15-number_time_slot].gts_send_frame_index[gts_slot_list[15-number_time_slot].element_out]].length = gts_send_buffer[gts_slot_list[15-number_time_slot].gts_send_frame_index[gts_slot_list[15-number_time_slot].element_out]].length -2; + + call PD_DATA.request(gts_send_buffer[gts_slot_list[15-number_time_slot].gts_send_frame_index[gts_slot_list[15-number_time_slot].element_out]].length,(uint8_t *)>s_send_buffer[gts_slot_list[15-number_time_slot].gts_send_frame_index[gts_slot_list[15-number_time_slot].element_out]]); + + available_gts_index_count++; + available_gts_index[available_gts_index_count] = gts_slot_list[15-number_time_slot].gts_send_frame_index[gts_slot_list[15-number_time_slot].element_out]; + + gts_slot_list[15-number_time_slot].element_count--; + gts_slot_list[15-number_time_slot].element_out++; + + if (gts_slot_list[15-number_time_slot].element_out == GTS_SEND_BUFFER_SIZE) + gts_slot_list[15-number_time_slot].element_out=0; + + if(gts_slot_list[15-number_time_slot].element_count > 0 ) + { + coordinator_gts_send_pending_data =1; + coordinator_gts_send_time_slot = number_time_slot; + } + } + } +} +return; +} + +task void start_gts_send() +{ + + atomic{ + gts_send_pending_data = 0; + + if(gts_send_buffer_count > 0) + { + if (check_gts_send_conditions(gts_send_buffer[gts_send_buffer_msg_out].length) == 1 ) + { + + gts_send_buffer[gts_send_buffer_msg_out].length = gts_send_buffer[gts_send_buffer_msg_out].length -2; + + call PD_DATA.request(gts_send_buffer[gts_send_buffer_msg_out].length,(uint8_t *)>s_send_buffer[gts_send_buffer_msg_out]); + + gts_send_buffer_count --; + gts_send_buffer_msg_out++; + + if (gts_send_buffer_msg_out == GTS_SEND_BUFFER_SIZE) + gts_send_buffer_msg_out=0; + + //////////////printfUART("after send %i %i %i \n",gts_send_buffer_count,gts_send_buffer_msg_in,gts_send_buffer_msg_out); + + if (gts_send_buffer_count > 0) + gts_send_pending_data = 1; + } + } + +} +return; +} + +////////////////////////////////////////////////////////////// +//////////Indirect transmission functions//////////////////// +///////////////////////////////////////////////////////////// + +void init_indirect_trans_buffer() +{ + int i; + for(i=0;i 0x00) + { + frame_ptr = (MPDU *)indirect_trans_queue[i].frame; + destination_address=get_fc2_dest_addr(frame_ptr->frame_control2); + + switch(destination_address) + { + case LONG_ADDRESS: dest_long_ptr = (dest_long *) frame_ptr->data; + break; + case SHORT_ADDRESS: dest_short_ptr = (dest_short *) frame_ptr->data; + break; + } + + //check the full address + + if ( (dest_long_ptr->destination_address0 == DeviceAddress[1] && dest_long_ptr->destination_address1 == DeviceAddress[0]) || ( dest_short_ptr->destination_address == (uint16_t)DeviceAddress[0] )) + { + + if (send_buffer_msg_in == SEND_BUFFER_SIZE) + send_buffer_msg_in=0; + + memcpy(&send_buffer[send_buffer_msg_in],(MPDU *) &indirect_trans_queue[i].frame,sizeof(MPDU)); + + //enable retransmissions + send_buffer[send_buffer_msg_in].retransmission =0; + send_buffer[send_buffer_msg_in].indirect = i + 1; + + //check upon reception + indirect_trans_queue[i].handler=0x00; + //verify temporary error on the association request + + indirect_trans_count--; + if(indirect_trans_count > INDIRECT_BUFFER_SIZE ) + { + indirect_trans_count=0; + } + + atomic send_buffer_count++; + atomic send_buffer_msg_in++; + + post send_frame_csma(); + + ////printfUART("i send\n",""); + + return; + } + } + } + ////printfUART("i not found",""); + + +return; +} + +/***************************DEBUG FUNCTIONS******************************/ +/* This function are list functions with the purpose of debug, to use then uncomment the declatarion +on top of this file*/ +/* + +void list_mac_pib() +{ +////////////printfUART("mac_PIB.macAckWaitDuration: %x\n",mac_PIB.macAckWaitDuration); +////////////printfUART("mac_PIB.macAssociationPermit: %i\n",mac_PIB.macAssociationPermit); +////////////printfUART("mac_PIB.macAutoRequest: %i\n",mac_PIB.macAutoRequest); +////////////printfUART("mac_PIB.macBattLifeExt %i\n",mac_PIB.macBattLifeExt); +////////////printfUART("mac_PIB.macBattLifeExtPeriods %i\n",mac_PIB.macBattLifeExtPeriods); +//beacon payload +////////////printfUART("mac_PIB.macBeaconPayloadLenght %i\n",mac_PIB.macBeaconPayloadLenght); +////////////printfUART("mac_PIB.macBeaconOrder %i\n",mac_PIB.macBeaconOrder); +////////////printfUART("mac_PIB.macBeaconTxTime %i\n",mac_PIB.macBeaconTxTime); +////////////printfUART("mac_PIB.macBSN %i\n",mac_PIB.macBSN); +////////////printfUART("mac_PIB.macCoordExtendedAddress0 %y\n",mac_PIB.macCoordExtendedAddress0); +////////////printfUART("mac_PIB.macCoordExtendedAddress1 %y\n",mac_PIB.macCoordExtendedAddress1); +////////////printfUART("mac_PIB.macCoordShortAddress: %x\n",mac_PIB.macCoordShortAddress); +////////////printfUART("mac_PIB.macDSN: %x\n",mac_PIB.macDSN); +////////////printfUART("mac_PIB.macGTSPermit: %x\n",mac_PIB.macGTSPermit); +////////////printfUART("mac_PIB.macMaxCSMABackoffs: %x\n",mac_PIB.macMaxCSMABackoffs); +////////////printfUART("mac_PIB.macMinBE: %x\n",mac_PIB.macMinBE); +////////////printfUART("mac_PIB.macPANId: %x\n",mac_PIB.macPANId); +////////////printfUART("mac_PIB.macPromiscuousMode: %x\n",mac_PIB.macPromiscuousMode); +////////////printfUART("mac_PIB.macRxOnWhenIdle: %x\n",mac_PIB.macRxOnWhenIdle); +////////////printfUART("mac_PIB.macShortAddress: %y\n",mac_PIB.macShortAddress); +////////////printfUART("mac_PIB.macSuperframeOrder: %x\n",mac_PIB.macSuperframeOrder); +////////////printfUART("mac_PIB.macTransactionPersistenceTime: %y\n",mac_PIB.macTransactionPersistenceTime); + +return; +} + +void list_gts() +{ + int i; + ////////////printfUART("GTS list%i\n", GTS_descriptor_count); + + for (i=0; i< 7;i++) + { + ////////////printfUART("GTSID: %i",GTS_db[i].gts_id); + ////////////printfUART("start slot: %i",GTS_db[i].starting_slot); + ////////////printfUART("lenght: %i",GTS_db[i].length); + ////////////printfUART("dir: %i",GTS_db[i].direction); + ////////////printfUART("DevAddressType: %i",GTS_db[i].DevAddressType); + ////////////printfUART("expiration: %i \n",GTS_db[i].expiration); + } + +} + +void list_my_gts() +{ +atomic{ + ////////////printfUART("SEND GTS s_GTSss: %i s_GTS_length: %i\n",s_GTSss,s_GTS_length); + + ////////////printfUART("RECEIVE GTS r_GTSss: %i r_GTS_length: %i\n",r_GTSss,r_GTS_length); +} +} +*/ + +void list_indirect_trans_buffer() +{ + int i; + //printfUART("indirect_trans_count %i\n", indirect_trans_count); + + for (i=0; i< INDIRECT_BUFFER_SIZE;i++) + { + //printfUART("hand: %i \n",indirect_trans_queue[i].handler); + + ////printfUART("start slot: %i",GTS_db[i].starting_slot); + + } + +} +/* +void list_gts_null() +{ + int i; + ////////////printfUART("GTS null list%i\n", GTS_null_descriptor_count); + + for (i=0; i< GTS_null_descriptor_count;i++) + { + //////////////printfUART("GTSID: %i",GTS_null_db[i].gts_id); + ////////////printfUART("start slot: %i",GTS_null_db[i].starting_slot); + ////////////printfUART("lenght: %i",GTS_null_db[i].length); + //////////////printfUART("dir: %i",GTS_null_db[i].direction); + ////////////printfUART("DevAddressType: %i \n",GTS_null_db[i].DevAddressType); + ////////////printfUART("persistencetime: %i \n",GTS_null_db[i].persistencetime); + } + +} + +*/ + + +} + diff --git a/tos/lib/net/zigbee/ieee802154/mac/mac_const.h b/tos/lib/net/zigbee/ieee802154/mac/mac_const.h new file mode 100644 index 00000000..8c61d05a --- /dev/null +++ b/tos/lib/net/zigbee/ieee802154/mac/mac_const.h @@ -0,0 +1,225 @@ +/* + * @author IPP HURRAY http://www.hurray.isep.ipp.pt/art-wise + * @author open-zb http://www.open-zb.net + * @author Andre Cunha + */ + +// The MAC constants are defined in here. +// Notice that these makes use of the PHY constants. +//pag 134 + +#ifndef __MAC_CONST__ +#define __MAC_CONST__ + + +#define aBaseSlotDuration 60 +#define aBaseSuperframeDuration 960 //aBaseSlotDuration*aNumSuperframeSlots + +//#define aExtendedAddress // This should be defined by the device! + +#define aMaxBE 5 //CSMA-CA + +#define aMaxBeaconOverhead 75 +#define aMaxBeaconPayloadLength aMaxPHYPacketSize-aMaxBeaconOverhead +#define aGTSDescPersistenceTime 4 +#define aMaxFrameOverhead 25 +#define aMaxFrameResponseTime 1220 +#define aMaxFrameRetries 1 + +//(SYNC)number of beacons lost before sending a Beacon-Lost indication +#define aMaxLostBeacons 4 +#define aMaxMACFrameSize aMaxPHYPacketSize-aMaxFrameOverhead +#define aMaxSIFSFrameSize 18 +#define aMinCAPLength 440 +#define aMinLIFSPeriod 40 +#define aMinSIFSPeriod 12 +#define aNumSuperframeSlots 16 +#define aResponseWaitTime 32*aBaseSuperframeDuration +#define aUnitBackoffPeriod 20 + + +#define TYPE_BEACON 0 +#define TYPE_DATA 1 +#define TYPE_ACK 2 +#define TYPE_CMD 3 + +#define SHORT_ADDRESS 2 +#define LONG_ADDRESS 3 +#define RESERVED_ADDRESS 1 + +#define NUMBER_TIME_SLOTS 16 + +#define ACK_LENGTH 5 + +//buffer sizes +#define MAX_GTS_BUFFER 7 + +//#define MAX_GTS_PEND 2 +//#define MAX_GTS_IN_SLOT 1 + +#define INDIRECT_BUFFER_SIZE 2 +#define RECEIVE_BUFFER_SIZE 4 +#define SEND_BUFFER_SIZE 3 + +#define UPSTREAM_BUFFER_SIZE 3 + +#define GTS_SEND_BUFFER_SIZE 3 + +#define BACKOFF_PERIOD_MS 0.34724 +#define BACKOFF_PERIOD_US 347.24 + +//value of each symbol in us +#define EFFECTIVE_SYMBOL_VALUE 17.362 + +// MAC PIB attribute +typedef struct +{ + //pag 135 + uint8_t macAckWaitDuration; + bool macAssociationPermit;//FDD + bool macAutoRequest; + bool macBattLifeExt; + uint8_t macBattLifeExtPeriods; + + uint8_t macBeaconPayload[aMaxBeaconPayloadLength];//FDD + + uint8_t macBeaconPayloadLenght;//FDD + uint8_t macBeaconOrder;//FDD + + uint32_t macBeaconTxTime;//FDD + uint8_t macBSN;//FDD + uint32_t macCoordExtendedAddress0; + uint32_t macCoordExtendedAddress1; + uint16_t macCoordShortAddress; + uint8_t macDSN; + bool macGTSPermit;//FDD + uint8_t macMaxCSMABackoffs; + uint8_t macMinBE; + uint16_t macPANId; + bool macPromiscuousMode;//FDD + bool macRxOnWhenIdle; + uint32_t macShortAddress; + uint8_t macSuperframeOrder;//FDD + uint32_t macTransactionPersistenceTime;//FDD + +} macPIB; + +// MAC PIB security ACL entry descriptor +typedef struct +{ + uint32_t ACLExtendedAddress[2]; + uint16_t ACLShortAddress; + uint16_t ACLPANId; + uint8_t ACLSecurityMaterialLength; + //variable string + uint8_t ACLSecurityMaterial; + uint8_t ACLSecuritySuite; + +}ACLDescriptor; + +// MAC PIB security attribute +typedef struct +{ + //pag 138 + ACLDescriptor macACLEntryDescriptorSet; + uint8_t macACLEntryDescriptorSetSize; + bool macDefaultSecurity; + uint8_t macDefaultSecurityMaterialLength; + //variable string + uint8_t macDefaultSecurityMaterial; + uint8_t macDefaultSecuritySuite; + uint8_t macSecurityMode; + +}macPIBsec; + +//MAC PANDescriptor +typedef struct +{ + //pag76 + uint8_t CoordAddrMode; + uint16_t CoordPANId; + uint32_t CoordAddress0; + uint32_t CoordAddress1; + uint8_t LogicalChannel; + //superframe specification field + uint16_t SuperframeSpec; + bool GTSPermit; + uint8_t LinkQuality; + uint32_t TimeStamp; + bool SecurityUse; + uint8_t ACLEntry; + bool SecurityFailure; + +}PANDescriptor; + +//GTS entry (used in the PAN coordinator) +typedef struct +{ + uint8_t gts_id; + uint8_t starting_slot; + uint8_t length; + uint8_t direction; + uint16_t DevAddressType; + uint8_t expiration; + +}GTSinfoEntryType; + +//GTS entry (used in the PAN coordinator) +typedef struct +{ + uint8_t gts_id; + uint8_t starting_slot; + uint8_t length; + uint16_t DevAddressType; + uint8_t persistencetime; + +}GTSinfoEntryType_null; + +typedef struct +{ + uint8_t handler; + uint16_t transaction_persistent_time; + + //MPDU frame; + uint8_t frame[127]; + +}indirect_transmission_element; + +typedef struct gts_slot_element +{ + uint8_t element_count; + uint8_t element_in; + uint8_t element_out; + uint8_t gts_send_frame_index[GTS_SEND_BUFFER_SIZE]; + +}gts_slot_element; + + +typedef struct time_stamp32 +{ + +uint32_t time_stamp; + +}time_stamp32; + +typedef struct time_stamp16 +{ + +uint16_t time_stamp; + +}time_stamp16; + +//MAC ACTIVE CHANNEL SCAN REDUCED PAN DESCRIPTOR (SHOR ADDRESS ONLY) +typedef struct SCAN_PANDescriptor +{ + //pag76 + uint16_t CoordPANId; + uint16_t CoordAddress; + uint8_t LogicalChannel; + //superframe specification field + uint16_t SuperframeSpec; + uint8_t lqi; +}SCAN_PANDescriptor; + + +#endif diff --git a/tos/lib/net/zigbee/ieee802154/mac/mac_enumerations.h b/tos/lib/net/zigbee/ieee802154/mac/mac_enumerations.h new file mode 100644 index 00000000..f8004b2c --- /dev/null +++ b/tos/lib/net/zigbee/ieee802154/mac/mac_enumerations.h @@ -0,0 +1,117 @@ +/* + * @author IPP HURRAY http://www.hurray.isep.ipp.pt/art-wise + * @author open-zb http://www.open-zb.net + * @author Andre Cunha + */ + +#ifndef __MAC_ENUMERATIONS__ +#define __MAC_ENUMERATIONS__ + +//Mac enumerations standard pag 110 + +enum { + MAC_SUCCESS = 0x00, + MAC_BEACON_LOSS = 0xE0, + MAC_CHANNEL_ACCESS_FAILURE = 0xE1, + MAC_DENIED = 0xE2, + //MLME-RESET + MAC_DISABLE_TRX_FAILURE = 0xE3, + MAC_FAILED_SECURITY_CHECK = 0xE4, + MAC_FRAME_TOO_LONG = 0xE5, + MAC_INVALID_GTS = 0xE6, + MAC_INVALID_HANDLE = 0xE7, + MAC_INVALID_PARAMETER = 0xE8, + MAC_NO_ACK = 0xE9, + MAC_NO_BEACON = 0xEA, + MAC_NO_DATA = 0xEB, + MAC_NO_SHORT_ADDRESS = 0xEC, + MAC_OUT_OF_CAP = 0xED, + MAC_PAN_ID_CONFLICT = 0xEE, + MAC_REALIGNMENT = 0xEF, + MAC_TRANSACTION_EXPIRED = 0xF0, + MAC_TRANSACTION_OVERFLOW = 0xF1, + MAC_TX_ACTIVE = 0xF2, + MAC_UNAVAILABLE_KEY = 0xF3, + MAC_UNSUPPORTED_ATTRIBUTE = 0xF4 + }; + + + +//mac dissassociation enums +enum{ + MAC_PAN_COORD_LEAVE = 0x01, + MAC_PAN_DEVICE_LEAVE = 0x02, + +}; + + + +//mac commands enums +enum { + + CMD_ASSOCIATION_REQUEST = 0x01, + CMD_ASSOCIATION_RESPONSE = 0x02, + CMD_DISASSOCIATION_NOTIFICATION = 0x03, + CMD_DATA_REQUEST = 0x04, + CMD_PANID_CONFLICT = 0x05, + CMD_ORPHAN_NOTIFICATION = 0x06, + CMD_BEACON_REQUEST = 0x07, + CMD_COORDINATOR_REALIGNMENT = 0x08, + CMD_GTS_REQUEST = 0x09 +}; + + +//mac association responses +enum { + + CMD_RESP_ASSOCIATION_SUCCESSFUL = 0x00, + CMD_RESP_PAN_CAPACITY =0x01, + CMD_RESP_ACCESS_DENIED =0x02 + +}; + +//MAC PIB Enumeration +enum { + + MACACKWAITDURATION = 0x40, + MACASSOCIATIONPERMIT=0x41, + MACAUTOREQUEST = 0x42, + MACBATTLIFEEXT=0x43, + MACBATTLIFEEXTPERIODS=0x44, + MACBEACONPAYLOAD=0x45, + MACMAXBEACONPAYLOADLENGTH=0x46, + MACBEACONORDER=0x47, + MACBEACONTXTIME=0x48, + MACBSN=0x49, + MACCOORDEXTENDEDADDRESS=0x4a, + MACCOORDSHORTADDRESS=0x4b, + MACDSN=0x4c, + MACGTSPERMIT=0x4d, + MACMAXCSMABACKOFFS=0x4e, + MACMINBE=0x4f, + MACPANID=0x50, + MACPROMISCUOUSMODE=0x51, + MACRXONWHENIDLE=0x52, + MACSHORTADDRESS=0x53, + MACSUPERFRAMEORDER=0x54, + MACTRANSACTIONPERSISTENCETIME=0x55 + +}; + +//gts enumerations +enum{ + GTS_TX_ONLY = 0x00, + GTS_RX_ONLY = 0x01 +}; + +//channel scan enumerations +enum{ + ED_SCAN = 0x00, + ACTIVE_SCAN = 0x01, + PASSIVE_SCAN = 0x02, + ORPHAN_SCAN = 0x03 +}; + + +#endif + diff --git a/tos/lib/net/zigbee/ieee802154/macTDBS/Mac.nc b/tos/lib/net/zigbee/ieee802154/macTDBS/Mac.nc new file mode 100644 index 00000000..a46b6f09 --- /dev/null +++ b/tos/lib/net/zigbee/ieee802154/macTDBS/Mac.nc @@ -0,0 +1,120 @@ +/* + * @author IPP HURRAY http://www.hurray.isep.ipp.pt/art-wise + * @author Andre Cunha + * + */ + +#include + +configuration Mac { + + + //MLME + provides interface MLME_START; + provides interface MLME_SET; + provides interface MLME_GET; + + provides interface MLME_ASSOCIATE; + provides interface MLME_DISASSOCIATE; + + provides interface MLME_BEACON_NOTIFY; + provides interface MLME_GTS; + + provides interface MLME_ORPHAN; + + provides interface MLME_SYNC; + provides interface MLME_SYNC_LOSS; + + provides interface MLME_RESET; + + provides interface MLME_SCAN; + + //MCPS + provides interface MCPS_DATA; + provides interface MCPS_PURGE; + +} +implementation { + + components MainC; + MainC.SoftwareInit -> MacM; + + components LedsC; + components MacM; + + components Phy; + + components TimerAsyncC; + + MacM.TimerAsync ->TimerAsyncC; + + MacM.Leds -> LedsC; + + + MacM.AMControl ->Phy.SplitControl; + + components HplCC2420PinsC as Pins; + MacM.CCA -> Pins.CCA; + + components RandomC; + MacM.Random -> RandomC; + + components new TimerMilliC() as T_ackwait; + MacM.T_ackwait -> T_ackwait; + + components new TimerMilliC() as T_ResponseWaitTime; + MacM.T_ResponseWaitTime -> T_ResponseWaitTime; + + components new TimerMilliC() as T_ScanDuration; + MacM.T_ScanDuration -> T_ScanDuration; + + + components CC2420ReceiveC; + MacM.AddressFilter -> CC2420ReceiveC; + + // + //components CC2420ControlC; + //MacM.CC2420Config ->CC2420ControlC; + + + /*****************************************************/ + /* INTERFACES */ + /*****************************************************/ + MacM.PD_DATA -> Phy.PD_DATA; + MacM.PLME_ED ->Phy.PLME_ED; + MacM.PLME_CCA -> Phy.PLME_CCA; + MacM.PLME_SET -> Phy.PLME_SET; + MacM.PLME_GET -> Phy.PLME_GET; + MacM.PLME_SET_TRX_STATE -> Phy.PLME_SET_TRX_STATE; + + + //MLME interfaces + MLME_START=MacM; + + MLME_SET=MacM; + MLME_GET=MacM; + + MLME_ASSOCIATE=MacM; + MLME_DISASSOCIATE=MacM; + + MLME_BEACON_NOTIFY = MacM; + MLME_GTS=MacM; + + MLME_ORPHAN=MacM; + + MLME_SYNC=MacM; + MLME_SYNC_LOSS=MacM; + + MLME_RESET=MacM; + + MLME_SCAN=MacM; + + MCPS_DATA=MacM; + MCPS_PURGE=MacM; + + + + + +} + diff --git a/tos/lib/net/zigbee/ieee802154/macTDBS/MacM.nc b/tos/lib/net/zigbee/ieee802154/macTDBS/MacM.nc new file mode 100644 index 00000000..2d88c165 --- /dev/null +++ b/tos/lib/net/zigbee/ieee802154/macTDBS/MacM.nc @@ -0,0 +1,5676 @@ +/* + * @author IPP HURRAY http://www.hurray.isep.ipp.pt/art-wise + * @author Andre Cunha + * + */ + +#include + +#include "printfUART.h" + +#include "frame_format.h" +#include "phy_const.h" + +#include "mac_const.h" +#include "mac_enumerations.h" + +#include "mac_func.h" + +module MacM { + + provides interface Init; + + provides interface MLME_START; + provides interface MLME_SET; + provides interface MLME_GET; + + provides interface MLME_ASSOCIATE; + provides interface MLME_DISASSOCIATE; + + provides interface MLME_BEACON_NOTIFY; + provides interface MLME_GTS; + + provides interface MLME_ORPHAN; + + provides interface MLME_SYNC; + provides interface MLME_SYNC_LOSS; + + provides interface MLME_RESET; + + provides interface MLME_SCAN; + + //MCPS + provides interface MCPS_DATA; + provides interface MCPS_PURGE; + + + uses interface Timer as T_ackwait; + + uses interface Timer as T_ResponseWaitTime; + + uses interface Timer as T_ScanDuration; + + uses interface Leds; + + uses interface SplitControl as AMControl; + + uses interface Random; + + uses interface GeneralIO as CCA; + + + //uses interface CC2420Config; + + uses interface AddressFilter; + + //uses interface Test_send; + + uses interface TimerAsync; + + uses interface PD_DATA; + + uses interface PLME_ED; + uses interface PLME_CCA; + uses interface PLME_SET; + uses interface PLME_GET; + uses interface PLME_SET_TRX_STATE; + + + +} +implementation { + +/*****************************************************/ +/* GENERAL */ +/*****************************************************/ + /***************Variables*************************/ + //local extended address + uint32_t aExtendedAddress0; + uint32_t aExtendedAddress1; + + macPIB mac_PIB; + +//If the the MLME receives a start request the node becomes a pan coordinator + //and start transmiting beacons + bool PANCoordinator = 0; + //(0 NO beacon transmission; 1 beacon transmission); + bool Beacon_enabled_PAN = 0; + + //(RESET) when the reset command arrives it checks whether or not to reset the PIB + bool SetDefaultPIB=0; + + //use security + bool SecurityEnable=0; + + //others + bool pending_reset=0; + + //transceiver status -every time the transceiver changes state this variable is updated + uint8_t trx_status; + + //defines the transmission + bool beacon_enabled=0; + + /***************Functions Definition***************/ + + void init_MacPIB(); + + uint8_t min(uint8_t val1, uint8_t val2); + + void init_MacCon(); + + + task void signal_loss(); + + + void create_data_request_cmd(); + void create_beacon_request_cmd(); + void create_gts_request_cmd(uint8_t gts_characteristics); + + void build_ack(uint8_t sequence,uint8_t frame_pending); + + void create_data_frame(uint8_t SrcAddrMode, uint16_t SrcPANId, uint32_t SrcAddr[], uint8_t DstAddrMode, uint16_t DestPANId, uint32_t DstAddr[], uint8_t msduLength, uint8_t msdu[],uint8_t msduHandle, uint8_t TxOptions,uint8_t on_gts_slot,uint8_t pan); + + + + +/*****************************************************/ +/* Association */ +/*****************************************************/ + /***************Variables*************************/ + uint8_t associating = 0; + uint8_t association_cmd_seq_num =0; + + /*association parameters*/ + + uint8_t a_LogicalChannel; + uint8_t a_CoordAddrMode; + uint16_t a_CoordPANId; + uint32_t a_CoordAddress[2]; + uint8_t a_CapabilityInformation; + bool a_securityenable; + + /***************Functions Definition***************/ + + void create_association_request_cmd(uint8_t CoordAddrMode,uint16_t CoordPANId,uint32_t CoordAddress[],uint8_t CapabilityInformation); + + error_t create_association_response_cmd(uint32_t DeviceAddress[],uint16_t shortaddress, uint8_t status); + + void create_disassociation_notification_cmd(uint32_t DeviceAddress[],uint8_t disassociation_reason); + + void process_dissassociation_notification(MPDU *pdu); + +/*****************************************************/ +/* Synchronization */ +/*****************************************************/ + /***************Variables*************************/ + //(SYNC)the device will try to track the beacon ie enable its receiver just before the espected time of each beacon + bool TrackBeacon=0; + bool beacon_processed=0; + //beacon loss indication + uint8_t beacon_loss_reason; + + //(SYNC)the device will try to locate one beacon + bool findabeacon=0; + //(SYNC)number of beacons lost before sending a Beacon-Lost indication comparing to aMaxLostBeacons + uint8_t missed_beacons=0; + //boolean variable stating if the device is synchonized with the beacon or not + uint8_t on_sync=0; + + uint32_t parent_offset=0x00000000; + + +/*****************************************************/ +/* GTS Variables */ +/*****************************************************/ + /***************Variables*************************/ + + uint8_t gts_request=0; + uint8_t gts_request_seq_num=0; + + bool gts_confirm; + + uint8_t GTS_specification; + bool GTSCapability=1; + + uint8_t final_CAP_slot=15; + + //GTS descriptor variables, coordinator usage only + GTSinfoEntryType GTS_db[7]; + uint8_t GTS_descriptor_count=0; + uint8_t GTS_startslot=16; + uint8_t GTS_id=0x01; + + + //null gts descriptors + GTSinfoEntryType_null GTS_null_db[7]; + + uint8_t GTS_null_descriptor_count=0; + //uint8_t GTS_null_id=0x01; + + //node GTS variables + // 1 GTS for transmit + uint8_t s_GTSss=0; //send gts start slot + uint8_t s_GTS_length=0; //send gts length + //1 GTS for receive + uint8_t r_GTSss=0; //receive gts start slot + uint8_t r_GTS_length=0; //receive gts lenght + + //used to state that the device is on its transmit slot + uint8_t on_s_GTS=0; + //used to state that the device is on its receive slot + uint8_t on_r_GTS=0; + + //used to determine if the next time slot is used for transmission + uint8_t next_on_s_GTS=0; + //used to determine if the next time slot is used for reception + uint8_t next_on_r_GTS=0; + + //variable stating if the coordinator allow GTS allocations + uint8_t allow_gts=1; + + //COORDINATOR GTS BUFFER + gts_slot_element gts_slot_list[7]; + uint8_t available_gts_index[GTS_SEND_BUFFER_SIZE]; + uint8_t available_gts_index_count; + + uint8_t coordinator_gts_send_pending_data=0; + uint8_t coordinator_gts_send_time_slot=0; + + //gts buffer used to store the gts messages both in COORDINATOR and NON COORDINATOR + norace MPDU gts_send_buffer[GTS_SEND_BUFFER_SIZE]; + + //NON PAN COORDINATOR BUFFER + //buffering for sending + uint8_t gts_send_buffer_count=0; + uint8_t gts_send_buffer_msg_in=0; + uint8_t gts_send_buffer_msg_out=0; + uint8_t gts_send_pending_data=0; + + + /***************Functions Definition***************/ + + void process_gts_request(MPDU *pdu); + void init_available_gts_index(); + task void start_coordinator_gts_send(); + + + //GTS FUNCTIONS + error_t remove_gts_entry(uint16_t DevAddressType); + error_t add_gts_entry(uint8_t gts_length,bool direction,uint16_t DevAddressType); + error_t add_gts_null_entry(uint8_t gts_length,bool direction,uint16_t DevAddressType); + + //increment the idle GTS for GTS deallocation purposes, not fully implemented yet + task void increment_gts_null(); + + task void start_gts_send(); + + + + //initialization functions + void init_gts_slot_list(); + void init_GTS_null_db(); + + void init_GTS_db(); + + + uint32_t calculate_gts_expiration(); + task void check_gts_expiration(); + + +/*****************************************************/ +/* CHANNEL SCAN Variables */ +/*****************************************************/ + //current_channel + uint8_t current_channel=0; + + /***************Variables*************************/ + //ED-SCAN variables + + bool scanning_channels; + + uint32_t channels_to_scan; + uint8_t current_scanning=0; + //uint8_t scan_count=0; + uint8_t scanned_values[16]; + uint8_t scan_type; + + SCAN_PANDescriptor scan_pans[16]; + + uint16_t scan_duration; + + task void data_channel_scan_indication(); + +/*****************************************************/ +/* TIMER VARIABLES */ +/*****************************************************/ + /***************Variables*************************/ + uint32_t response_wait_time; + + //Beacon Interval + uint32_t BI; + //Superframe duration + uint32_t SD; + + //timer variables + uint32_t time_slot; //backoff boundary timer + uint32_t backoff; //backoff timer + + //current number of backoffs in the active period + uint8_t number_backoff=1; + uint8_t number_time_slot=0; + + bool csma_slotted=0; +/*****************************************************/ +/* CSMA VARIABLES */ +/*****************************************************/ + /***************Variables*************************/ + + //DEFERENCE CHANGE + uint8_t cca_deference = 0; + uint8_t backoff_deference = 0; + uint8_t check_csma_ca_backoff_send_conditions(uint32_t delay_backoffs); + + //STEP 2 + uint8_t delay_backoff_period; + bool csma_delay=0; + + bool csma_locate_backoff_boundary=0; + + bool csma_cca_backoff_boundary=0; + + //Although the receiver of the device is enabled during the channel assessment portion of this algorithm, the + //device shall discard any frames received during this time. + bool performing_csma_ca=0; + + //CSMA-CA variables + uint8_t BE; //backoff exponent + uint8_t CW; //contention window (number of backoffs to clear the channel) + uint8_t NB; //number of backoffs + + /***************Functions Definition***************/ + + void init_csma_ca(bool slotted); + void perform_csma_ca(); + task void perform_csma_ca_unslotted(); + task void perform_csma_ca_slotted(); + //task void start_csma_ca_slotted(); + +/*****************************************************/ +/* Indirect Transmission buffers */ +/*****************************************************/ + /***************Variables*************************/ + //indirect transmission buffer + norace indirect_transmission_element indirect_trans_queue[INDIRECT_BUFFER_SIZE]; + //indirect transmission message counter + uint8_t indirect_trans_count=0; + + /***************Functions Definition***************/ + + //function used to initialize the indirect transmission buffer + void init_indirect_trans_buffer(); + //function used to search and send an existing indirect transmission message + void send_ind_trans_addr(uint32_t DeviceAddress[]); + //function used to remove an existing indirect transmission message + error_t remove_indirect_trans(uint8_t handler); + //function used to increment the transaction persistent time on each message + //if the transaction time expires the messages are discarded + void increment_indirect_trans(); + +/*****************************************************/ +/* RECEIVE buffers */ +/*****************************************************/ + /***************Variables*************************/ + + //buffering variables + norace MPDU buffer_msg[RECEIVE_BUFFER_SIZE]; + int current_msg_in=0; + int current_msg_out=0; + int buffer_count=0; + + /***************Functions Definition***************/ + + task void data_indication(); + + void indication_cmd(MPDU *pdu, int8_t ppduLinkQuality); + void indication_ack(MPDU *pdu, int8_t ppduLinkQuality); + void indication_data(MPDU *pdu, int8_t ppduLinkQuality); +/*****************************************************/ +/* RECEPTION AND TRANSMISSION */ +/*****************************************************/ + + /***************Variables*************************/ + + //buffering for sending + norace MPDUBuffer send_buffer[SEND_BUFFER_SIZE]; + uint8_t send_buffer_count=0; + uint8_t send_buffer_msg_in=0; + uint8_t send_buffer_msg_out=0; + + //retransmission information + uint8_t send_ack_check;//ack requested in the transmitted frame + uint8_t retransmit_count;//retransmission count + uint8_t ack_sequence_number_check;//transmission sequence number + uint8_t send_retransmission; + uint8_t send_indirect_transmission; + + uint8_t pending_request_data=0; + + uint8_t ackwait_period; + + uint8_t link_quality; + + norace ACK mac_ack; + ACK *mac_ack_ptr; + + uint32_t gts_expiration; + + uint8_t I_AM_IN_CAP=0; + uint8_t I_AM_IN_CFP=0; + uint8_t I_AM_IN_IP=0; + + /***************Functions Definition***************/ + + task void send_frame_csma(); + + uint8_t check_csma_ca_send_conditions(uint8_t frame_length,uint8_t frame_control1); + + uint8_t check_gts_send_conditions(uint8_t frame_length); + + uint8_t calculate_ifs(uint8_t pk_length); + + + +/*****************************************************/ +/* BEACON MANAGEMENT */ +/*****************************************************/ + /***************Variables*************************/ + norace MPDU mac_beacon_txmpdu; + MPDU *mac_beacon_txmpdu_ptr; + + uint8_t *send_beacon_frame_ptr; + uint8_t send_beacon_length; + + /***************Functions Definition***************/ + /*function to create the beacon*/ + task void create_beacon(); + /*function to process the beacon information*/ + void process_beacon(MPDU *packet,uint8_t ppduLinkQuality); + + +/*****************************************************/ +/* Fault tolerance functions */ +/*****************************************************/ +//FAULT-TOLERANCE + void create_coordinator_realignment_cmd(uint32_t device_extended0, uint32_t device_extended1, uint16_t device_short_address); + + void create_orphan_notification(); + + void process_coordinator_realignment(MPDU *pdu); + + /*******************************************/ + /*******BEACON SCHEDULING IMPLEMENTATION****/ + /*******************************************/ + + //bolean that checks if the device is in the parent active period + uint8_t I_AM_IN_PARENT_CAP = 0; + + + //upstream buffer + norace MPDUBuffer upstream_buffer[UPSTREAM_BUFFER_SIZE]; + uint8_t upstream_buffer_count=0; + uint8_t upstream_buffer_msg_in=0; + uint8_t upstream_buffer_msg_out=0; + + uint8_t sending_upstream_frame=0; + + task void send_frame_csma_upstream(); + +/***************************DEBUG FUNCTIONS******************************/ +/* This function are list functions with the purpose of debug, to use then uncomment the declatarion +on top of this file*/ +/* + void list_mac_pib(); + + void list_gts(); + + void list_my_gts(); + void list_gts_null(); + */ + //list all the handles in the indirect transmission buffer, debug purposes + void list_indirect_trans_buffer(); + +/***************************END DEBUG FUNCTIONS******************************/ + + +/***************** Init Commands ****************/ + command error_t Init.init() { + + call AMControl.start(); + + + //initialization of the beacon structure + mac_beacon_txmpdu_ptr = &mac_beacon_txmpdu; + + + + atomic{ + //inicialize the mac PIB + init_MacPIB(); + + init_GTS_db(); + + init_GTS_null_db(); + + init_gts_slot_list(); + + init_available_gts_index(); + + aExtendedAddress0=TOS_NODE_ID; + aExtendedAddress1=TOS_NODE_ID; + + + + call AddressFilter.set_address(mac_PIB.macShortAddress, aExtendedAddress0, aExtendedAddress1); + + call AddressFilter.set_coord_address(mac_PIB.macCoordShortAddress, mac_PIB.macPANId); + + + + init_indirect_trans_buffer(); + + + } + + //beacon + mac_beacon_txmpdu_ptr = &mac_beacon_txmpdu; + + //ack + mac_ack_ptr = &mac_ack; + + //Other timers, sync timers units expressed in miliseconds + ackwait_period = ((mac_PIB.macAckWaitDuration * 4.0 ) / 250.0) * 3; + + response_wait_time = ((aResponseWaitTime * 4.0) / 250.0) * 2; + + atomic{ + + + BI = aBaseSuperframeDuration * powf(2,mac_PIB.macBeaconOrder); + SD = aBaseSuperframeDuration * powf(2,mac_PIB.macSuperframeOrder); + + + //backoff_period + backoff = aUnitBackoffPeriod; + //backoff_period_boundary + + time_slot = SD / NUMBER_TIME_SLOTS; + + call TimerAsync.set_enable_backoffs(1); + call TimerAsync.set_backoff_symbols(backoff); + + call TimerAsync.set_bi_sd(BI,SD); + + call TimerAsync.start(); + } + + +printfUART_init(); + + return SUCCESS; + } + + event void AMControl.startDone(error_t err) { + if (err == SUCCESS) { + + call TimerAsync.start(); + + } + else { + call AMControl.start(); + } + } + + event void AMControl.stopDone(error_t err) { + } + + +/*****************************************************/ +/* TIMERS FIRED */ +/*****************************************************/ + +async event error_t TimerAsync.before_bi_fired() +{ + //printfUART("bbi %i\n",call TimerAsync.get_current_ticks()); + + if (mac_PIB.macBeaconOrder != mac_PIB.macSuperframeOrder ) + { + if ( Beacon_enabled_PAN == 1 ) + { + // + //post set_trx(); + trx_status = PHY_TX_ON; + call PLME_SET_TRX_STATE.request(PHY_TX_ON); + } + else + { + // + //post set_trx(); + trx_status = PHY_RX_ON; + call PLME_SET_TRX_STATE.request(PHY_RX_ON); + } + } + + //I_AM_IN_CAP = 1; + findabeacon = 1; + + return SUCCESS; +} + +/*******************Timer BEACON INTERVAL******************/ +async event error_t TimerAsync.bi_fired() +{ + call Leds.led2On(); + //call Test_send.send(); + + I_AM_IN_CAP = 1; + I_AM_IN_IP = 0; + + //printfUART("bi\n",""); + + + if ( Beacon_enabled_PAN == 1 ) + { + //the beacon is send directly without CSMA/CA + call PD_DATA.request(send_beacon_length,send_beacon_frame_ptr); + } + + number_backoff =0; + number_time_slot=0; + + + //CHECK there is the need to wait a small amount of time before checking if the beacon as been processed or not + //possible solition, if it receives a packet stand by for confirmation it its a beacon + //The device must always receive the beacon + if (TrackBeacon == 1) + { + if (beacon_processed==1) + { + beacon_processed=0; + } + else + { + //dealocate all GTS + //beacon loss + + on_sync =0; + beacon_loss_reason = MAC_BEACON_LOSS; + + //TODO + //post signal_loss(); + } + } + + post send_frame_csma(); + + return SUCCESS; +} + +/*******************Timer SUPERFRAME DURATION******************/ +async event error_t TimerAsync.sd_fired() +{ + call Leds.led2Off(); + + //printfUART("sd\n",""); + + I_AM_IN_CFP = 0; + I_AM_IN_IP = 1; + + + number_backoff=0; + number_time_slot=0; + + + if (PANCoordinator == 0 && TYPE_DEVICE == ROUTER) + { + trx_status = PHY_RX_ON; + + call PLME_SET_TRX_STATE.request(PHY_RX_ON); + } + else + { + trx_status = PHY_RX_ON; + + call PLME_SET_TRX_STATE.request(PHY_RX_ON); + + } + + if (mac_PIB.macShortAddress==0xffff && TYPE_DEVICE == END_DEVICE) + { + trx_status = PHY_RX_ON; + + call PLME_SET_TRX_STATE.request(PHY_RX_ON); + } + + //trx_status = PHY_RX_ON; + //post set_trx(); + /* + //turn the transceiver off + if (mac_PIB.macBeaconOrder != mac_PIB.macSuperframeOrder ) + { + if ( mac_PIB.macRxOnWhenIdle == 0 && findabeacon == 0) + { + trx_status = PHY_TRX_OFF; + post set_trx(); + } + else + { + trx_status = PHY_RX_ON; + post set_trx(); + } + } + //if the node is trying to synchronize + if (on_sync == 0 || mac_PIB.macPromiscuousMode == 1) + { + atomic{ + trx_status = PHY_RX_ON; + post set_trx(); + } + } + */ + if (PANCoordinator == 1) + { + //increment the gts_null descriptors + atomic{ + + //if (GTS_null_descriptor_count > 0) post increment_gts_null(); + + //if (GTS_descriptor_count >0 ) post check_gts_expiration(); + + //if (indirect_trans_count > 0) increment_indirect_trans(); + + //creation of the beacon + post create_beacon(); + } + //trx_status = PHY_TRX_OFF; + //post set_trx(); + } + else + { + //temporariamente aqui //atenção quando for para o cluster-tree é preciso mudar para fora + //e necessario destinguir ZC de ZR (que tem que manter a sync com o respectivo pai) + if (on_sync == 0) + { + //sync not ok + + //findabeacon=1; + if (missed_beacons == aMaxLostBeacons) + { + + printfUART("sync_loss %i\n",missed_beacons); + //out of sync + post signal_loss(); + } + //printfUART("out_sync %i\n",missed_beacons); + missed_beacons++; + call Leds.led1Off(); + + } + else + { + //sync ok + missed_beacons=0; + + on_sync=0; + } + + } + + //trx_status = PHY_TRX_OFF; + //call PLME_SET_TRX_STATE.request(PHY_TRX_OFF); + + return SUCCESS; +} + +/*******************Timer BEFORE TIME SLOT FIRED******************/ +async event error_t TimerAsync.before_time_slot_fired() +{ + on_s_GTS=0; + on_r_GTS=0; + + if (next_on_s_GTS == 1) + { + on_s_GTS=1; + next_on_s_GTS =0; + trx_status = PHY_TX_ON; + call PLME_SET_TRX_STATE.request(PHY_TX_ON); + //post set_trx(); + } + + if(next_on_r_GTS == 1) + { + on_r_GTS=1; + next_on_r_GTS=0; + trx_status = PHY_RX_ON; + call PLME_SET_TRX_STATE.request(PHY_RX_ON); + //post set_trx(); + } + +return SUCCESS; +} +/*******************Timer TIME SLOT FIRED******************/ +async event error_t TimerAsync.time_slot_fired() +{ + //reset the backoff counter and increment the slot boundary + number_backoff=0; + number_time_slot++; + + //verify is there is data to send in the GTS, and try to send it + if(PANCoordinator == 1 && GTS_db[15-number_time_slot].direction == 1 && GTS_db[15-number_time_slot].gts_id != 0) + { + //COORDINATOR SEND DATA + //////////printfUART("bbck%i:%i:%i\n", (15-number_time_slot),GTS_db[15-number_time_slot].direction,gts_slot_list[15-number_time_slot].element_count); + + post start_coordinator_gts_send(); + + } + else + { + //DEVICE SEND DATA + if (number_time_slot == s_GTSss && gts_send_buffer_count > 0 && on_sync == 1)//(send_s_GTSss-send_s_GTS_len) + { + //current_time = call TimerAsync.get_total_tick_counter(); + post start_gts_send(); + } + } + + next_on_r_GTS =0; + next_on_s_GTS=0; + + + //printfUART("ts%i %i %i\n", number_time_slot,s_GTSss,r_GTSss); + + + //verification if the time slot is entering the CAP + //GTS FIELDS PROCESSING + + if ((number_time_slot + 1) >= final_CAP_slot && (number_time_slot + 1) < 16) + { + I_AM_IN_CAP = 0; + I_AM_IN_CFP = 1; + + //printfUART("bts %i\n",I_AM_IN_CAP, number_time_slot); + + atomic{ + + //verification of the next time slot + if(PANCoordinator == 1 && number_time_slot < 15) + { + //COORDINATOR verification of the next time slot + if(GTS_db[14-number_time_slot].gts_id != 0x00 && GTS_db[14-number_time_slot].DevAddressType != 0x0000) + { + if(GTS_db[14-number_time_slot].direction == 1 ) // device wants to receive + { + next_on_s_GTS =1; //PAN coord mode + } + else + { + next_on_r_GTS=1; //PAN coord mode + } + } + } + else + { + //device verification of the next time slot + if( (number_time_slot +1) == s_GTSss || (number_time_slot +1) == r_GTSss ) + { + //printfUART("s_GTSss: %i r_GTSss: %i\n", s_GTSss,r_GTSss); + if((number_time_slot + 1) == s_GTSss) + { + //printfUART("MY SEND SLOT \n", ""); + next_on_s_GTS =1; + s_GTS_length --; + if (s_GTS_length != 0 ) + { + s_GTSss++; + } + } + else + { + ////////////printfUART("MY RECEIVE SLOT \n", ""); + next_on_r_GTS =1; + r_GTS_length --; + if (r_GTS_length != 0 ) + { + r_GTSss++; + } + } + } + else + { + //idle + next_on_s_GTS=0; + next_on_r_GTS=0; + } + } + } + } + +return SUCCESS; +} +async event error_t TimerAsync.sfd_fired() +{ + +return SUCCESS; +} + +/*******************Timer BACKOFF PERIOD******************/ +async event error_t TimerAsync.backoff_fired() +{ + //slotted CSMA/CA function + atomic{ + + if( csma_locate_backoff_boundary == 1 ) + { + csma_locate_backoff_boundary=0; + + //post start_csma_ca_slotted(); + + //DEFERENCE CHANGE + if (backoff_deference == 0) + { + //normal situation + delay_backoff_period = (call Random.rand16() & ((uint8_t)(powf(2,BE)) - 1)); + + if (check_csma_ca_backoff_send_conditions((uint32_t) delay_backoff_period) == 1) + { + backoff_deference = 1; + } + + } + else + { + backoff_deference = 0; + } + + csma_delay=1; + } + + + + if( csma_cca_backoff_boundary == 1 ) + post perform_csma_ca_slotted(); + } + //CSMA/CA + atomic{ + if(csma_delay == 1 ) + { + if (delay_backoff_period == 0) + { + if(csma_slotted == 0) + { + post perform_csma_ca_unslotted(); + } + else + { + //CSMA/CA SLOTTED + csma_delay=0; + csma_cca_backoff_boundary=1; + } + } + delay_backoff_period--; + } + } + number_backoff++; +return SUCCESS; +} + +/*******************T_ackwait**************************/ + event void T_ackwait.fired() { + + ////////printfUART("Tfd \n", ""); + + //call Leds.redToggle(); + + if (send_ack_check == 1) + { + retransmit_count++; + + if (retransmit_count == aMaxFrameRetries || send_indirect_transmission > 0) + { + //check the type of data being send + /* + if (associating == 1) + { + printfUART("af ack\n", ""); + associating=0; + signal MLME_ASSOCIATE.confirm(0x0000,MAC_NO_ACK); + } + */ + + atomic{ + //////////printfUART("TRANSMISSION FAIL\n",""); + //stardard procedure, if fail discard the packet + atomic send_buffer_count --; + send_buffer_msg_out++; + + //failsafe + if(send_buffer_count > SEND_BUFFER_SIZE) + { + + atomic send_buffer_count =0; + send_buffer_msg_out=0; + send_buffer_msg_in=0; + + } + + + if (send_buffer_msg_out == SEND_BUFFER_SIZE) + send_buffer_msg_out=0; + + if (send_buffer_count > 0) + post send_frame_csma(); + + send_ack_check=0; + retransmit_count=0; + ack_sequence_number_check=0; + + } + } + + //////////printfUART("RETRY\n",""); + //retransmissions + post send_frame_csma(); + } + + } + +/*******************T_ResponseWaitTime**************************/ + event void T_ResponseWaitTime.fired() { + //command response wait time + //////////printfUART("T_ResponseWaitTime.fired\n", ""); + + if (associating == 1) + { + printfUART("af rwt\n", ""); + associating=0; + signal MLME_ASSOCIATE.confirm(0x0000,MAC_NO_DATA); + + } + + } + +/*******************TDBS Implementation Timers**************************/ +async event error_t TimerAsync.before_start_track_beacon_fired() +{ + I_AM_IN_PARENT_CAP = 1; + +return SUCCESS; +} + + + +//track beacon events timers +async event error_t TimerAsync.start_track_beacon_fired() +{ + I_AM_IN_PARENT_CAP = 1; + + //printfUART("fi\n",""); + + if (upstream_buffer_count > 0) + post send_frame_csma_upstream(); + + + +return SUCCESS; +} +async event error_t TimerAsync.end_track_beacon_fired() +{ + + I_AM_IN_PARENT_CAP = 0; + + //printfUART("unfi\n",""); + //call Leds.greenOff(); + +return SUCCESS; +} + + + + + +/***************************************************** +****************PD_DATA EVENTS*********************** +******************************************************/ + async event error_t PD_DATA.confirm(uint8_t status) { + + + return SUCCESS; + } + +/***************************************************** +**************** PD_DATA ******************** +******************************************************/ + +async event error_t PD_DATA.indication(uint8_t psduLenght,uint8_t* psdu, int8_t ppduLinkQuality){ +/* +MPDU *packet; + +uint8_t destination_address=0; + +dest_short *dest_short_ptr; +dest_long *dest_long_ptr; + +beacon_addr_short *beacon_addr_short_ptr; + +*/ +atomic{ + //if(I_AM_IN_CAP == 1 || I_AM_IN_CFP == 1 || mac_PIB.macShortAddress==0xffff || scanning_channels ==1 || findabeacon == 1) + //{ + if (buffer_count > RECEIVE_BUFFER_SIZE) + { + //call Leds.redToggle(); + printfUART("full\n",""); + } + else + { + + /* + packet = (MPDU*)psdu; + + + switch ((packet->frame_control1 & 0x7)) + { + case TYPE_BEACON: + beacon_addr_short_ptr = (beacon_addr_short *) &packet->data[0]; + + //avoid VERIFY static assignment of coordinator parent + if (beacon_addr_short_ptr->source_address != mac_PIB.macCoordShortAddress) + { + printfUART("pb %x %x\n", beacon_addr_short_ptr->source_address,mac_PIB.macCoordShortAddress); + return SUCCESS; + } + + /* + + if ( mac_PIB.macShortAddress != 0xffff) + { + if ( beacon_addr_short_ptr->source_address != mac_PIB.macCoordShortAddress) + { + printfUART("pb %x %x\n", beacon_addr_short_ptr->source_address,mac_PIB.macCoordShortAddress); + return SUCCESS; + } + }*/ + /* + break; + case TYPE_DATA: + case TYPE_CMD: + //VALIDATION OF DESTINATION ADDRESSES - NOT TO OVERLOAD THE PROCESSOR + destination_address=get_fc2_dest_addr(packet->frame_control2); + + if (destination_address > 1) + { + switch(destination_address) + { + case SHORT_ADDRESS: + dest_short_ptr = (dest_short *) &packet->data[0]; + + if ( dest_short_ptr->destination_address != 0xffff && dest_short_ptr->destination_address != mac_PIB.macShortAddress) + { + printfUART("nsm %x %x\n", dest_short_ptr->destination_address,mac_PIB.macShortAddress); + return SUCCESS; + } + //If a destination PAN identifier is included in the frame, it shall match macPANId or shall be the + //broadcast PAN identifier (0 x ffff). + if(dest_short_ptr->destination_PAN_identifier != 0xffff && dest_short_ptr->destination_PAN_identifier != mac_PIB.macPANId ) + { + printfUART("wsP %x %x \n", dest_short_ptr->destination_PAN_identifier,mac_PIB.macPANId); + return SUCCESS; + } + break; + + case LONG_ADDRESS: + dest_long_ptr = (dest_long *) &packet->data[0]; + + if ( dest_long_ptr->destination_address0 !=aExtendedAddress0 && dest_long_ptr->destination_address1 !=aExtendedAddress1 ) + { + printfUART("nlm %x %x \n",dest_long_ptr->destination_address0,dest_long_ptr->destination_address1); + return SUCCESS; + } + //If a destination PAN identifier is included in the frame, it shall match macPANId or shall be the + //broadcast PAN identifier (0 x ffff). + if(dest_long_ptr->destination_PAN_identifier != 0xffff && dest_long_ptr->destination_PAN_identifier != mac_PIB.macPANId ) + { + printfUART("wLP %x %x\n", dest_long_ptr->destination_PAN_identifier,mac_PIB.macPANId); + return SUCCESS; + } + + break; + } + } + + + + break; + case TYPE_ACK: + + break; + } + + */ + memcpy(&buffer_msg[current_msg_in],psdu,sizeof(MPDU)); + + atomic{ + current_msg_in++; + + if ( current_msg_in == RECEIVE_BUFFER_SIZE ) + current_msg_in = 0; + + buffer_count ++; + } + + link_quality = ppduLinkQuality; + + if (scanning_channels ==1) + { + //channel scan operation, accepts beacons only + post data_channel_scan_indication(); + + } + else + { + //normal operation + post data_indication(); + } + } + //} + //else + //{ + // printfUART("drop\n",""); + //} +} +return SUCCESS; +} + + + +task void data_indication() +{ + //check all the conditions for a receiver packet + //pag 155 + + uint8_t link_qual; + + atomic link_qual = link_quality; + + //printfUART("data_indication\n",""); + ////////printfUART("buf %i %i\n",buffer_count,indirect_trans_count); + + //Although the receiver of the device is enabled during the channel assessment portion of this algorithm, the + //device shall discard any frames received during this time. + ////////////printfUART("performing_csma_ca: %i\n",performing_csma_ca); + if (performing_csma_ca == 1) + { + ////////////printfUART("REJ CSMA\n",""); + atomic{ + buffer_count--; + + current_msg_out++; + if ( current_msg_out == RECEIVE_BUFFER_SIZE ) + current_msg_out = 0; + } + + return; + } + + //while performing channel scan disable the packet reception + if ( scanning_channels == 1) + { + atomic{ + buffer_count--; + + current_msg_out++; + if ( current_msg_out == RECEIVE_BUFFER_SIZE ) + current_msg_out = 0; + } + return; + } +atomic{ + + ////printfUART("data ind %x %x %i\n",buffer_msg[current_msg_out].frame_control1,buffer_msg[current_msg_out].frame_control2,(buffer_msg[current_msg_out].frame_control2 & 0x7)); + + //check the frame type of the received packet + switch( (buffer_msg[current_msg_out].frame_control1 & 0x7) ) + { + + case TYPE_DATA: //printfUART("rd %i\n",buffer_msg[current_msg_out].seq_num); + indication_data(&buffer_msg[current_msg_out],link_qual); + break; + + case TYPE_ACK: //printfUART("ra\n",""); + //ack_received = 1; + indication_ack(&buffer_msg[current_msg_out],link_qual); + + break; + + case TYPE_CMD: //printfUART("rc\n",""); + indication_cmd(&buffer_msg[current_msg_out],link_qual); + break; + + case TYPE_BEACON: + + //printfUART("rb %i\n",buffer_msg[current_msg_out].seq_num); + if (mac_PIB.macShortAddress == 0x0000) + { + buffer_count--; + } + else + { + process_beacon(&buffer_msg[current_msg_out],link_qual); + + } + + break; + default: + atomic buffer_count--; + ////printfUART("Invalid frame type\n",""); + + break; + } + atomic{ + current_msg_out++; + if ( current_msg_out == RECEIVE_BUFFER_SIZE ) + current_msg_out = 0; + } + } + return; +} + + + +/***************************************************** +****************PLME_ED EVENTS*********************** +******************************************************/ +event error_t PLME_CCA.confirm(uint8_t status){ +return SUCCESS; +} + + +event error_t PLME_SET.confirm(uint8_t status, uint8_t PIBAttribute){ +return SUCCESS; +} + +async event error_t PLME_SET_TRX_STATE.confirm(uint8_t status){ + +return SUCCESS; +} + +event error_t PLME_GET.confirm(uint8_t status,uint8_t PIBAttribute, uint8_t PIBAttributeValue){ + +return SUCCESS; +} + +event error_t PLME_ED.confirm(uint8_t status,int8_t EnergyLevel){ + +return SUCCESS; +} + +/*******************************************************************************************************/ +/*******************************************************************************************************/ +/*******************************************************************************************************/ +/****************************************PACKET PROCESSING FUNCTIONS************************************/ +/*******************************************************************************************************/ +/*******************************************************************************************************/ +/*******************************************************************************************************/ + +void process_beacon(MPDU *packet,uint8_t ppduLinkQuality) +{ + + /* + ORGANIZE THE PROCESS BEACON FUNCION AS FOLLOWS. + 1- GET THE BEACON ORDER + 2- GET THE SUPERFRAME ORDER + 3- GET THE FINAL CAP SLOT + 4 - COMPUTE SD, BI, TS, BACKOFF PERIOD IN MILLISECONDS + + 4- SYNCHRONIZE THE NODE BY DOING THE FOLLOWING + - SET A TIMER IN MS FOR THE FINAL TIME SLOT (SUPERFRAME DURATION) : IT EXPRIES AFTER SD - TX TIME - PROCESS TIME + - SET A TIMER IN MS FOR THE GTS IF ANY EXIST IT EXPRIES AFTER GTS_NBR * TIME_SLOT - TX TIME - PROCESS TIME + */ + uint32_t SO_EXPONENT; + uint32_t BO_EXPONENT; + int i=0; + uint16_t gts_descriptor_addr; + uint8_t data_count; + + uint8_t gts_directions; + uint8_t gts_des_count; + + uint8_t gts_ss; + uint8_t gts_l; + uint8_t dir; + uint8_t dir_mask; + + //end gts variables + + //function that processes the received beacon + beacon_addr_short *beacon_ptr; + + PANDescriptor pan_descriptor; + + // beacon_trans_delay = (((packet->length(bytes) * 8.0) / 250.00(bits/s) ) / 0.34(s) (timer_granularity) ) (symbols) + + //pending frames + uint8_t short_addr_pending=0; + uint8_t long_addr_pending=0; + + //used in the synchronization + //uint32_t process_tick_counter; //symbols + + //uint32_t becon_trans_delay; //symbols + //uint32_t start_reset_ct; //number of clock ticks since the start of the beacon interval + + //used in the track beacon + beacon_processed = 1; + missed_beacons=0; + + //initializing pointer to data structure + beacon_ptr = (beacon_addr_short*) (packet->data); + + + //decrement buffer count + atomic buffer_count --; + + //printfUART("Received Beacon\n",""); + //printfUART("rb panid: %x %x \n",beacon_ptr->source_address,mac_PIB.macCoordShortAddress); + //////printfUART("My macPANID: %x\n",mac_PIB.macPANId); + printfUART("rb %x %x\n",beacon_ptr->source_address,mac_PIB.macCoordShortAddress); + if( beacon_ptr->source_address != mac_PIB.macCoordShortAddress) + { + printfUART("nmp \n",""); + return; + } + //printfUART("bea %i\n",call TimerAsync.get_current_ticks()); + + /**********************************************************************************/ + /* PROCESSING THE SUPERFRAME STRUCTURE */ + /**********************************************************************************/ + + if (PANCoordinator == 0) + { + mac_PIB.macBeaconOrder = get_beacon_order(beacon_ptr->superframe_specification); + mac_PIB.macSuperframeOrder = get_superframe_order(beacon_ptr->superframe_specification); + + //mac_PIB.macCoordShortAddress = beacon_ptr->source_address; + + //printfUART("BO,SO:%i %i\n",mac_PIB.macBeaconOrder,mac_PIB.macSuperframeOrder); + + //mac_PIB.macPANId = beacon_ptr->source_PAN_identifier; + + //beacon order check if it changed + if (mac_PIB.macSuperframeOrder == 0) + { + SO_EXPONENT = 1; + } + else + { + SO_EXPONENT = powf(2,mac_PIB.macSuperframeOrder); + } + + if ( mac_PIB.macBeaconOrder ==0) + { + BO_EXPONENT =1; + } + else + { + BO_EXPONENT = powf(2,mac_PIB.macBeaconOrder); + } + BI = aBaseSuperframeDuration * BO_EXPONENT; + SD = aBaseSuperframeDuration * SO_EXPONENT; + + //backoff_period + backoff = aUnitBackoffPeriod; + time_slot = SD / NUMBER_TIME_SLOTS; + + call TimerAsync.set_bi_sd(BI,SD); + } + + /**********************************************************************************/ + /* PROCESS GTS CHARACTERISTICS */ + /**********************************************************************************/ + allow_gts =1; + + //initializing the gts variables + s_GTSss=0; + s_GTS_length=0; + + r_GTSss=0; + r_GTS_length=0; + + /* + send_s_GTSss=0; + send_r_GTSss=0; + send_s_GTS_len=0; + send_r_GTS_len=0; + */ + final_CAP_slot = 15; + + + gts_des_count = (packet->data[8] & 0x0f); + + data_count = 9; + + final_CAP_slot = 15 - gts_des_count; + + if (gts_des_count > 0 ) + { + data_count = 10; //position of the current data count + //process descriptors + + gts_directions = packet->data[9]; + + //printfUART("gts_directions:%x\n",gts_directions); + + for(i=0; i< gts_des_count; i++) + { + gts_descriptor_addr = (uint16_t) packet->data[data_count]; + + //printfUART("gts_des_addr:%x mac short:%x\n",gts_descriptor_addr,mac_PIB.macShortAddress); + + data_count = data_count+2; + //check if it concerns me + if (gts_descriptor_addr == mac_PIB.macShortAddress) + { + //confirm the gts request + ////////////printfUART("packet->data[data_count]: %x\n",packet->data[data_count]); + //gts_ss = 15 - get_gts_descriptor_ss(packet->data[data_count]); + gts_ss = get_gts_descriptor_ss(packet->data[data_count]); + gts_l = get_gts_descriptor_len(packet->data[data_count]); + + if ( i == 0 ) + { + dir_mask=1; + } + else + { + + dir_mask = powf(2,i); + } + ////////////printfUART("dir_mask: %x i: %x gts_directions: %x \n",dir_mask,i,gts_directions); + dir = ( gts_directions & dir_mask); + if (dir == 0) + { + s_GTSss=gts_ss; + s_GTS_length=gts_l; + } + else + { + + r_GTSss=gts_ss; + r_GTS_length=gts_l; + } + + //printfUART("PB gts_ss: %i gts_l: %i dir: %i \n",gts_ss,gts_l,dir); + ////////////printfUART("PB send_s_GTSss: %i send_s_GTS_len: %i\n",send_s_GTSss,send_s_GTS_len); + + if ( gts_l == 0 ) + { + allow_gts=0; + } + + if (gts_confirm == 1 && gts_l != 0) + { + //signal ok + //printfUART("gts confirm \n",""); + gts_confirm =0; + signal MLME_GTS.confirm(GTS_specification,MAC_SUCCESS); + } + else + { + //signal not ok + ////////////printfUART("gts not confirm \n",""); + gts_confirm =0; + signal MLME_GTS.confirm(GTS_specification,MAC_DENIED); + } + + } + data_count++; + } + } + + /**********************************************************************************/ + /* PROCESS PENDING ADDRESSES INFORMATION */ + /**********************************************************************************/ + //this should pass to the network layer + + + short_addr_pending=get_number_short(packet->data[data_count]); + long_addr_pending=get_number_extended(packet->data[data_count]); + + //////////printfUART("ADD COUNT %i %i\n",short_addr_pending,long_addr_pending); + + data_count++; + + if(short_addr_pending > 0) + { + for(i=0;i < short_addr_pending;i++) + { + //////////printfUART("PB %i %i\n",(uint16_t)packet->data[data_count],short_addr_pending); + + //if(packet->data[data_count] == (uint8_t)mac_PIB.macShortAddress && packet->data[data_count+1] == (uint8_t)(mac_PIB.macShortAddress >> 8) ) + if((uint16_t)packet->data[data_count] == mac_PIB.macShortAddress) + { + + create_data_request_cmd(); + } + data_count = data_count + 2; + } + } + if(long_addr_pending > 0) + { + for(i=0; i < long_addr_pending;i++) + { + if((uint32_t)packet->data[data_count] == aExtendedAddress0 && (uint32_t)packet->data[data_count + 4] == aExtendedAddress1) + { + + data_count = data_count + 8; + + } + + } + } + + /**********************************************************************************/ + /* BUILD the PAN descriptor of the COORDINATOR */ + /**********************************************************************************/ + + + //Beacon NOTIFICATION + //BUILD the PAN descriptor of the COORDINATOR + //assuming that the adress is short + pan_descriptor.CoordAddrMode = SHORT_ADDRESS; + pan_descriptor.CoordPANId = 0x0000;//beacon_ptr->source_PAN_identifier; + pan_descriptor.CoordAddress0=0x00000000; + pan_descriptor.CoordAddress1=mac_PIB.macCoordShortAddress; + pan_descriptor.LogicalChannel=current_channel; + //superframe specification field + pan_descriptor.SuperframeSpec = beacon_ptr->superframe_specification; + + pan_descriptor.GTSPermit=mac_PIB.macGTSPermit; + pan_descriptor.LinkQuality=0x00; + pan_descriptor.TimeStamp=0x000000; + pan_descriptor.SecurityUse=0; + pan_descriptor.ACLEntry=0x00; + pan_descriptor.SecurityFailure=0x00; + + //I_AM_IN_CAP = 1; + + /**********************************************************************************/ + /* SYNCHRONIZING */ + /**********************************************************************************/ + + //processing time + beacon transmission delay + + //removed not used + //process_tick_counter = call TimerAsync.get_process_frame_tick_counter(); + //removed not used + //start_reset_ct = ((1000 * (packet->length * 8.0) / 250)) / 69.54; //(process_tick_counter - receive_tick_counter); + + if(PANCoordinator == 0) + { + I_AM_IN_CAP = 1; + I_AM_IN_IP = 0; + + //call Leds.yellowOn(); + call Leds.led2On(); + + call Leds.led1On(); + + if(findabeacon == 1) + { + //printfUART("findabeacon\n", ""); + call TimerAsync.set_timers_enable(1); + findabeacon =0; + } + + //#ifdef PLATFORM_MICAZ + //number_time_slot = call TimerAsync.reset_start(start_reset_ct+process_tick_counter+52);// //SOBI=3 52 //SOBI=0 15 + //#else + + //call TimerAsync.reset(); + + number_time_slot = call TimerAsync.reset_start(75); //95 old val sem print + + // +process_tick_counter+52 //SOBI=3 52 //SOBI=0 + //#endif + on_sync=1; + + printfUART("sE\n", ""); + } + else + { + I_AM_IN_PARENT_CAP = 1; + + call TimerAsync.set_track_beacon(1); + + //#ifdef PLATFORM_MICAZ + // call TimerAsync.set_track_beacon_start_ticks(parent_offset,0x00001E00,(start_reset_ct+process_tick_counter+18)); + //#else + call TimerAsync.set_track_beacon_start_ticks(parent_offset,0x00001E00,4);//(start_reset_ct) + //#endif + + printfUART("sP \n", ""); + } + + call Leds.led1Toggle(); + signal MLME_BEACON_NOTIFY.indication((uint8_t)packet->seq_num,pan_descriptor,0, 0, mac_PIB.macBeaconPayloadLenght, packet->data); + +return; +} + + +void process_gts_request(MPDU *pdu) +{ + error_t status; + cmd_gts_request *mac_gts_request; + + mac_gts_request= (cmd_gts_request*) &pdu->data; + +atomic{ + if ( get_characteristic_type(mac_gts_request->gts_characteristics) == 1) + { + //allocation + + //process the gts request + status = add_gts_entry(get_gts_length(mac_gts_request->gts_characteristics),get_gts_direction(mac_gts_request->gts_characteristics),mac_gts_request->source_address); + + } + else + { + //dealocation + + status = remove_gts_entry(mac_gts_request->source_address); + } + + signal MLME_GTS.indication(mac_gts_request->source_address, mac_gts_request->gts_characteristics, 0, 0); + + } + +return; +} +/****************DATA indication functions******************/ + +void indication_data(MPDU *pdu, int8_t ppduLinkQuality) +{ + uint8_t data_len; + + uint8_t payload[80]; + uint8_t msdu_length=0; + + //int i; + + uint32_t SrcAddr[2]; + uint32_t DstAddr[2]; + + + //frame control variables + uint8_t source_address=0; + uint8_t destination_address=0; + + + dest_short *dest_short_ptr; + dest_long *dest_long_ptr; + + source_short *source_short_ptr; + source_long *source_long_ptr; + + //implement the intra PAN data messages + //intra_pan_source_short *intra_pan_source_short_ptr; + //intra_pan_source_long *intra_pan_source_long_ptr; + + + source_address=get_fc2_source_addr(pdu->frame_control2); + destination_address=get_fc2_dest_addr(pdu->frame_control2); + + //decrement buffer count + atomic buffer_count --; + + SrcAddr[0]=0x00000000; + SrcAddr[1]=0x00000000; + DstAddr[0]=0x00000000; + DstAddr[1]=0x00000000; + + + //printfUART("id %i %i \n",source_address,destination_address); + + + if ( get_fc1_intra_pan(pdu->frame_control1)== 0 ) + { + //INTRA PAN + if (destination_address > 1 && source_address > 1) + { + // Destination LONG - Source LONG + if (destination_address == LONG_ADDRESS && source_address == LONG_ADDRESS) + { + dest_long_ptr = (dest_long *) &pdu->data[0]; + source_long_ptr = (source_long *) &pdu->data[DEST_LONG_LEN]; + + //If a short destination address is included in the frame, it shall match either macShortAddress or the + //broadcast address (0 x ffff). Otherwise, if an extended destination address is included in the frame, it + //shall match aExtendedAddress. + if ( dest_long_ptr->destination_address0 !=aExtendedAddress0 && dest_long_ptr->destination_address1 !=aExtendedAddress1 ) + { + //////////printfUART("data rejected, ext destination not for me\n", ""); + return; + } + //If a destination PAN identifier is included in the frame, it shall match macPANId or shall be the + //broadcast PAN identifier (0 x ffff). + if(dest_long_ptr->destination_PAN_identifier != 0xffff && dest_long_ptr->destination_PAN_identifier != mac_PIB.macPANId ) + { + //////////printfUART("data rejected, wrong destination PAN\n", ""); + return; + } + data_len = 20; + + + DstAddr[1] = dest_long_ptr->destination_address0; + DstAddr[0] =dest_long_ptr->destination_address1; + + SrcAddr[1] =source_long_ptr->source_address0; + SrcAddr[0] =source_long_ptr->source_address1; + + msdu_length = pdu->length - data_len; + + memcpy(&payload,&pdu->data[data_len],msdu_length * sizeof(uint8_t)); + + signal MCPS_DATA.indication((uint16_t)source_address, (uint16_t)source_long_ptr->source_PAN_identifier, SrcAddr,(uint16_t)destination_address, (uint16_t)dest_long_ptr->destination_PAN_identifier, DstAddr, (uint16_t)msdu_length, payload, (uint16_t)ppduLinkQuality, 0x0000,0x0000); + + } + + // Destination SHORT - Source LONG + if ( destination_address == SHORT_ADDRESS && source_address == LONG_ADDRESS ) + { + dest_short_ptr = (dest_short *) &pdu->data[0]; + source_long_ptr = (source_long *) &pdu->data[DEST_SHORT_LEN]; + + //If a short destination address is included in the frame, it shall match either macShortAddress or the + //broadcast address (0 x ffff). Otherwise, if an extended destination address is included in the frame, it + //shall match aExtendedAddress. + if ( dest_short_ptr->destination_address != 0xffff && dest_short_ptr->destination_address != mac_PIB.macShortAddress) + { + //////////printfUART("data rejected, short destination not for me\n", ""); + return; + } + //If a destination PAN identifier is included in the frame, it shall match macPANId or shall be the + //broadcast PAN identifier (0 x ffff). + if(dest_short_ptr->destination_PAN_identifier != 0xffff && dest_short_ptr->destination_PAN_identifier != mac_PIB.macPANId ) + { + //////////printfUART("data rejected, wrong destination PAN\n", ""); + return; + } + + data_len = 14; + + DstAddr[0] =dest_short_ptr->destination_address; + + SrcAddr[1] =source_long_ptr->source_address0; + SrcAddr[0] =source_long_ptr->source_address1; + + msdu_length = pdu->length - data_len; + + memcpy(&payload,&pdu->data[data_len],msdu_length * sizeof(uint8_t)); + + signal MCPS_DATA.indication((uint16_t)source_address, (uint16_t)source_long_ptr->source_PAN_identifier, SrcAddr,(uint16_t)destination_address, (uint16_t)dest_short_ptr->destination_PAN_identifier, DstAddr, (uint16_t)msdu_length, payload, (uint16_t)ppduLinkQuality, 0x0000,0x0000); + + } + // Destination LONG - Source SHORT + if ( destination_address == LONG_ADDRESS && source_address == SHORT_ADDRESS ) + { + dest_long_ptr = (dest_long *) &pdu->data[0]; + source_short_ptr = (source_short *) &pdu->data[DEST_LONG_LEN]; + + //If a short destination address is included in the frame, it shall match either macShortAddress or the + //broadcast address (0 x ffff). Otherwise, if an extended destination address is included in the frame, it + //shall match aExtendedAddress. + if ( dest_long_ptr->destination_address0 !=aExtendedAddress0 && dest_long_ptr->destination_address1 !=aExtendedAddress1 ) + { + //////////printfUART("data rejected, ext destination not for me\n", ""); + return; + } + //If a destination PAN identifier is included in the frame, it shall match macPANId or shall be the + //broadcast PAN identifier (0 x ffff). + if(dest_long_ptr->destination_PAN_identifier != 0xffff && dest_long_ptr->destination_PAN_identifier != mac_PIB.macPANId ) + { + //////////printfUART("data rejected, wrong destination PAN\n", ""); + return; + } + + data_len = 14; + + DstAddr[1] = dest_long_ptr->destination_address0; + DstAddr[0] =dest_long_ptr->destination_address1; + + + SrcAddr[0] =source_short_ptr->source_address; + + msdu_length = pdu->length - data_len; + + memcpy(&payload,&pdu->data[data_len],msdu_length * sizeof(uint8_t)); + + signal MCPS_DATA.indication((uint16_t)source_address, (uint16_t)source_short_ptr->source_PAN_identifier, SrcAddr,(uint16_t)destination_address, (uint16_t)dest_long_ptr->destination_PAN_identifier, DstAddr, (uint16_t)msdu_length, payload, (uint16_t)ppduLinkQuality, 0x0000,0x0000); + + } + + + //Destination SHORT - Source SHORT + if ( destination_address == SHORT_ADDRESS && source_address == SHORT_ADDRESS ) + { + dest_short_ptr = (dest_short *) &pdu->data[0]; + source_short_ptr = (source_short *) &pdu->data[DEST_SHORT_LEN]; + + //If a short destination address is included in the frame, it shall match either macShortAddress or the + //broadcast address (0 x ffff). Otherwise, if an extended destination address is included in the frame, it + //shall match aExtendedAddress. + if ( dest_short_ptr->destination_address != 0xffff && dest_short_ptr->destination_address != mac_PIB.macShortAddress) + { + //printfUART("data rejected, short destination not for me\n", ""); + return; + } + //If a destination PAN identifier is included in the frame, it shall match macPANId or shall be the + //broadcast PAN identifier (0 x ffff). + if(dest_short_ptr->destination_PAN_identifier != 0xffff && dest_short_ptr->destination_PAN_identifier != mac_PIB.macPANId ) + { + //printfUART("SH SH data rejected, wrong destination PAN %x\n",mac_PIB.macPANId ); + return; + } + + data_len = 8; + + if ( get_fc1_ack_request(pdu->frame_control1) == 1 ) + { + build_ack(pdu->seq_num,0); + } + + DstAddr[0] =dest_short_ptr->destination_address; + + SrcAddr[0] =source_short_ptr->source_address; + + msdu_length = (pdu->length - 5) - data_len; + + + memcpy(&payload,&pdu->data[data_len],msdu_length * sizeof(uint8_t)); + + signal MCPS_DATA.indication((uint16_t)source_address, (uint16_t)source_short_ptr->source_PAN_identifier, SrcAddr,(uint16_t)destination_address, (uint16_t)dest_short_ptr->destination_PAN_identifier, DstAddr, (uint16_t)msdu_length,payload, (uint16_t)ppduLinkQuality, 0x0000,0x0000); + + } + } + + /*********NO DESTINATION ADDRESS PRESENT ****************/ + + if ( destination_address == 0 && source_address > 1 ) + { + + if (source_address == LONG_ADDRESS) + {//Source LONG + source_long_ptr = (source_long *) &pdu->data[0]; + + //If only source addressing fields are included in a data or MAC command frame, the frame shall be + //accepted only if the device is a PAN coordinator and the source PAN identifier matches macPANId. + if ( PANCoordinator==0 || source_long_ptr->source_PAN_identifier != mac_PIB.macPANId ) + { + //////////printfUART("data rejected, im not pan\n", ""); + return; + } + + data_len = 10; + + SrcAddr[1] =source_long_ptr->source_address0; + SrcAddr[0] =source_long_ptr->source_address1; + + msdu_length = pdu->length - data_len; + + memcpy(&payload,&pdu->data[data_len],msdu_length * sizeof(uint8_t)); + + signal MCPS_DATA.indication((uint16_t)source_address,(uint16_t)source_long_ptr->source_PAN_identifier, SrcAddr,(uint16_t)destination_address, 0x0000, DstAddr, (uint16_t)msdu_length, payload, (uint16_t)ppduLinkQuality, 0x0000,0x0000); + + } + else + {//Source SHORT + + source_short_ptr = (source_short *) &pdu->data[0]; + //If only source addressing fields are included in a data or MAC command frame, the frame shall be + //accepted only if the device is a PAN coordinator and the source PAN identifier matches macPANId. + if ( PANCoordinator==0 || source_short_ptr->source_PAN_identifier != mac_PIB.macPANId ) + { + //////////printfUART("data rejected, im not pan\n", ""); + return; + } + + data_len = 4; + + + SrcAddr[0] =source_short_ptr->source_address; + + msdu_length = pdu->length - data_len; + + memcpy(&payload,&pdu->data[data_len],msdu_length * sizeof(uint8_t)); + + signal MCPS_DATA.indication((uint16_t)source_address, (uint16_t)source_short_ptr->source_PAN_identifier, SrcAddr,(uint16_t)destination_address, 0x0000, DstAddr, (uint16_t)msdu_length, payload, (uint16_t)ppduLinkQuality, 0x0000,0x0000); + + } + } + /*********NO SOURCE ADDRESS PRESENT ****************/ + + if ( destination_address > 1 && source_address == 0 ) + { + if (destination_address == LONG_ADDRESS) + {//Destination LONG + dest_long_ptr = (dest_long *) &pdu->data[0]; + + //If a short destination address is included in the frame, it shall match either macShortAddress or the + //broadcast address (0 x ffff). Otherwise, if an extended destination address is included in the frame, it + //shall match aExtendedAddress. + if ( dest_long_ptr->destination_address0 !=aExtendedAddress0 && dest_long_ptr->destination_address1 !=aExtendedAddress1 ) + { + //////////printfUART("data rejected, ext destination not for me\n", ""); + return; + } + //If a destination PAN identifier is included in the frame, it shall match macPANId or shall be the + //broadcast PAN identifier (0 x ffff). + if(dest_long_ptr->destination_PAN_identifier != 0xffff && dest_long_ptr->destination_PAN_identifier != mac_PIB.macPANId ) + { + //////////printfUART("data rejected, wrong destination PAN\n", ""); + return; + } + + data_len = 10; + + DstAddr[1] = dest_long_ptr->destination_address0; + DstAddr[0] =dest_long_ptr->destination_address1; + + msdu_length = pdu->length - data_len; + + memcpy(&payload,&pdu->data[data_len],msdu_length * sizeof(uint8_t)); + + signal MCPS_DATA.indication((uint16_t)source_address,0x0000, SrcAddr,(uint16_t)destination_address, (uint16_t)dest_long_ptr->destination_PAN_identifier, DstAddr, (uint16_t)msdu_length, payload, (uint16_t)ppduLinkQuality, 0x0000,0x0000); + + } + else + {//Destination SHORT + dest_short_ptr = (dest_short *) &pdu->data[0]; + + //If a short destination address is included in the frame, it shall match either macShortAddress or the + //broadcast address (0 x ffff). Otherwise, if an extended destination address is included in the frame, it + //shall match aExtendedAddress. + if ( dest_short_ptr->destination_address != 0xffff && dest_short_ptr->destination_address != mac_PIB.macShortAddress) + { + //////////printfUART("data rejected, short destination not for me\n", ""); + return; + } + //If a destination PAN identifier is included in the frame, it shall match macPANId or shall be the + //broadcast PAN identifier (0 x ffff). + if(dest_short_ptr->destination_PAN_identifier != 0xffff && dest_short_ptr->destination_PAN_identifier != mac_PIB.macPANId ) + { + //////////printfUART("data rejected, wrong destination PAN\n", ""); + return; + } + + data_len = 4; + + DstAddr[0] =dest_short_ptr->destination_address; + + msdu_length = pdu->length - data_len; + + memcpy(&payload,&pdu->data[data_len],msdu_length * sizeof(uint8_t)); + + + signal MCPS_DATA.indication((uint16_t)source_address,0x0000, SrcAddr,(uint16_t)destination_address, (uint16_t)dest_short_ptr->destination_PAN_identifier, DstAddr, (uint16_t)msdu_length, payload, (uint16_t)ppduLinkQuality, 0x0000,0x0000); + + data_len = 4; + } + } + + } + else + { + //intra_pan == 1 + + + + } + + +return; +} + +void indication_cmd(MPDU *pdu, int8_t ppduLinkQuality) +{ + uint8_t cmd_type; + //uint8_t pk_ptr; + uint8_t addressing_fields_length=0; + + uint32_t SrcAddr[2]; + //uint32_t DstAddr[2];//NOT USED SO FAR + + //frame control variables + uint8_t source_address=0; + uint8_t destination_address=0; + + //NOT USED SO FAR + //dest_short *dest_short_ptr; + //dest_long *dest_long_ptr; + //NOT USED SO FAR + //source_short *source_short_ptr; + source_long *source_long_ptr; + + dest_short *dest_short_ptr; + dest_long *dest_long_ptr; + + //CHECK IMPLEMENT + //intra_pan_source_short *intra_pan_source_short_ptr; + //intra_pan_source_long *intra_pan_source_long_ptr; + + destination_address=get_fc2_dest_addr(pdu->frame_control2); + source_address=get_fc2_source_addr(pdu->frame_control2); + + //decrement buffer count + atomic buffer_count --; + + switch(destination_address) + { + case LONG_ADDRESS: addressing_fields_length = DEST_LONG_LEN; + dest_long_ptr = (dest_long *) &pdu->data[0]; + if(dest_long_ptr->destination_address0 !=aExtendedAddress0 && dest_long_ptr->destination_address1 !=aExtendedAddress1) + { + printfUART("NOT FOR ME",""); + return; + } + + break; + case SHORT_ADDRESS: addressing_fields_length = DEST_SHORT_LEN; + dest_short_ptr= (dest_short *) &pdu->data[0]; + //destination command not for me + if (dest_short_ptr->destination_address != mac_PIB.macShortAddress && dest_short_ptr->destination_address !=0xffff) + { + printfUART("NOT FOR ME",""); + //////////printfUART("NOT FOR ME %x me %e\n", dest_short_ptr->destination_address,mac_PIB.macShortAddress); + return; + } + break; + } + switch(source_address) + { + case LONG_ADDRESS: addressing_fields_length = addressing_fields_length + SOURCE_LONG_LEN; + break; + case SHORT_ADDRESS: addressing_fields_length = addressing_fields_length + SOURCE_SHORT_LEN; + break; + } + + cmd_type = pdu->data[addressing_fields_length]; + + + switch(cmd_type) + { + + case CMD_ASSOCIATION_REQUEST: + //check if association is allowed, if not discard the frame + + //////printfUART("CMD_ASSOCIATION_REQUEST \n", ""); + + + if (mac_PIB.macAssociationPermit == 0 ) + { + //////////printfUART("Association not alowed\n", ""); + if ( get_fc1_ack_request(pdu->frame_control1) == 1 ) + { + build_ack(pdu->seq_num,0); + } + return; + } + + if ( PANCoordinator==0 ) + { + //////////printfUART("i´m not a pan\n", ""); + return; + } + atomic{ + source_long_ptr = (source_long *) &pdu->data[DEST_SHORT_LEN]; + + SrcAddr[1] =source_long_ptr->source_address0; + SrcAddr[0] =source_long_ptr->source_address1; + + + signal MLME_ASSOCIATE.indication(SrcAddr, pdu->data[addressing_fields_length+1] , 0, 0); + + } + + if ( get_fc1_ack_request(pdu->frame_control1) == 1 ) + { + build_ack(pdu->seq_num,1); + } + + + break; + + case CMD_ASSOCIATION_RESPONSE: atomic{ + printfUART("CMD_ASSOCIATION_RESPONSE\n", ""); + + associating =0; + call T_ResponseWaitTime.stop(); + + if ( get_fc1_ack_request(pdu->frame_control1) == 1 ) + { + build_ack(pdu->seq_num,0); + } + + signal MLME_ASSOCIATE.confirm((uint16_t)(pdu->data[addressing_fields_length+1] + (pdu->data[addressing_fields_length+2] << 8)), pdu->data[addressing_fields_length+3]); + } + break; + + case CMD_DISASSOCIATION_NOTIFICATION: //////////printfUART("Received CMD_DISASSOCIATION_NOTIFICATION\n", ""); + + if ( get_fc1_ack_request(pdu->frame_control1) == 1 ) + { + build_ack(pdu->seq_num,0); + } + + process_dissassociation_notification(pdu); + break; + case CMD_DATA_REQUEST: + //printfUART("CMD_DATA_REQUEST\n", ""); + //////printfUART("DR\n", ""); + if ( get_fc1_ack_request(pdu->frame_control1) == 1 ) + { + //TODO + //Problems with consecutive reception of messages + + build_ack(pdu->seq_num,0); + } + + //cmd_data_request_0_3_reception = (cmd_data_request_0_3 *) pdu->data; + + source_long_ptr = (source_long *) &pdu->data[0]; + + SrcAddr[1] =source_long_ptr->source_address0; + SrcAddr[0] =source_long_ptr->source_address1; + + send_ind_trans_addr(SrcAddr); + + break; + case CMD_PANID_CONFLICT: + break; + + case CMD_ORPHAN_NOTIFICATION: + //printfUART("CMD_ORPHAN_NOTIFICATION\n", ""); + + source_long_ptr = (source_long *) &pdu->data[DEST_SHORT_LEN]; + + SrcAddr[1] =source_long_ptr->source_address0; + SrcAddr[0] =source_long_ptr->source_address1; + + signal MLME_ORPHAN.indication(SrcAddr, 0x00,0x00); + + + break; + case CMD_BEACON_REQUEST: + break; + case CMD_COORDINATOR_REALIGNMENT: + printfUART("CMD_COORDINATOR_REALIGNMENT\n", ""); + + process_coordinator_realignment(pdu); + + break; + case CMD_GTS_REQUEST: + ////////////printfUART("Received CMD_GTS_REQUEST\n", ""); + if ( get_fc1_ack_request(pdu->frame_control1) == 1 ) + { + build_ack(pdu->seq_num,0); + } + process_gts_request(pdu); + break; + default: break; + + } + +return; +} + +void indication_ack(MPDU *pdu, int8_t ppduLinkQuality) +{ + //decrement buffer count + + atomic buffer_count --; + + ////////////printfUART("ACK Received\n",""); + + atomic{ + if (send_ack_check == 1 && ack_sequence_number_check == pdu->seq_num) + { + //transmission SUCCESS + call T_ackwait.stop(); + + send_buffer_count --; + send_buffer_msg_out++; + + //failsafe + if(send_buffer_count > SEND_BUFFER_SIZE) + { + send_buffer_count =0; + send_buffer_msg_out=0; + send_buffer_msg_in=0; + } + + if (send_buffer_msg_out == SEND_BUFFER_SIZE) + send_buffer_msg_out=0; + + //received an ack for the association request + if( associating == 1 && association_cmd_seq_num == pdu->seq_num ) + { + //////////printfUART("ASSOC ACK\n",""); + call T_ResponseWaitTime.startOneShot(response_wait_time); + //call T_ResponseWaitTime.start(TIMER_ONE_SHOT, response_wait_time); + } + + if (gts_request == 1 && gts_request_seq_num == pdu->seq_num) + { + + call T_ResponseWaitTime.startOneShot(response_wait_time); + //call T_ResponseWaitTime.start(TIMER_ONE_SHOT, response_wait_time); + } + + //////////printfUART("TRANSMISSION SUCCESS\n",""); + + if (send_indirect_transmission > 0 ) + { //the message send was indirect + //remove the message from the indirect transmission queue + indirect_trans_queue[send_indirect_transmission-1].handler=0x00; + indirect_trans_count--; + //////////printfUART("SU id:%i ct:%i\n", send_indirect_transmission,indirect_trans_count); + } + + send_ack_check=0; + retransmit_count=0; + ack_sequence_number_check=0; + + + if (send_buffer_count > 0) + post send_frame_csma(); + + + } + } + + //CHECK + if (get_fc1_frame_pending(pdu->frame_control1) == 1 && pending_request_data ==1)// && associating == 1 + { + //////////printfUART("Frame_pending\n",""); + pending_request_data=0; + create_data_request_cmd(); + } + + //GTS mechanism, after the confirmation of the GTS request, must check if the beacon has the gts + /* + if (gts_ack == 1) + { + gts_ack=0; + gts_confirm=1; + call T_ResponseWaitTime.stop(); + + } + */ + if(gts_send_pending_data==1) + post start_gts_send(); + + if(coordinator_gts_send_pending_data==1 && coordinator_gts_send_time_slot == number_time_slot) + post start_coordinator_gts_send(); + +return; +} + + +void process_dissassociation_notification(MPDU *pdu) +{ +atomic{ + cmd_disassociation_notification *mac_disassociation_notification; + + //creation of a pointer to the disassociation notification structure + mac_disassociation_notification = (cmd_disassociation_notification*) pdu->data; + + signal MLME_DISASSOCIATE.indication(&mac_disassociation_notification->source_address0, mac_disassociation_notification->disassociation_reason, 0, 0); + } + +return; +} + + + + +void process_coordinator_realignment(MPDU *pdu) +{ + +atomic{ + cmd_coord_realignment *cmd_realignment = 0; + + dest_long *dest_long_ptr=0; + source_short *source_short_ptr=0; + + cmd_realignment = (cmd_coord_realignment*) &pdu->data[DEST_LONG_LEN + SOURCE_SHORT_LEN]; + + //creation of a pointer the addressing structures + dest_long_ptr = (dest_long *) &pdu->data[0]; + source_short_ptr = (source_short *) &pdu->data[DEST_LONG_LEN]; + + mac_PIB.macCoordShortAddress = ((cmd_realignment->coordinator_short_address0 << 8) | cmd_realignment->coordinator_short_address0 ); + mac_PIB.macShortAddress = cmd_realignment->short_address; + + + printfUART("PCR %i %i\n",mac_PIB.macCoordShortAddress,mac_PIB.macShortAddress); + + } +return; +} + + +/*****************************************************************************************************/ +/*****************************************************************************************************/ +/*****************************************************************************************************/ +/************************ BUILD FRAMES FUNCTIONS **********************************/ +/*****************************************************************************************************/ +/*****************************************************************************************************/ +/*****************************************************************************************************/ + + +task void create_beacon() +{ + int i=0; + uint8_t packet_length = 25; + int data_count=0; + int pending_data_index=0; + MPDU* pkt_ptr=0; + //pending frames + uint8_t short_addr_pending=0; + uint8_t long_addr_pending=0; + + uint8_t gts_directions=0x00; + + uint16_t frame_control; + + + atomic{ + + beacon_addr_short *mac_beacon_addr_short_ptr; + //mac_beacon_addr_short_ptr = (beacon_addr_short*) &mac_txmpdu.data[0]; + mac_beacon_addr_short_ptr = (beacon_addr_short*) &mac_beacon_txmpdu.data[0]; + //call PLME_SET_TRX_STATE.request(PHY_TX_ON); + + mac_beacon_txmpdu_ptr->length = 15; + + frame_control = set_frame_control(TYPE_BEACON,0,0,0,1,SHORT_ADDRESS,SHORT_ADDRESS); + + mac_beacon_txmpdu_ptr->frame_control1 = (uint8_t)( frame_control); + + mac_beacon_txmpdu_ptr->frame_control2 = (uint8_t)( frame_control >> 8); + + //mac_beacon_txmpdu_ptr->frame_control = set_frame_control(TYPE_BEACON,0,0,0,1,SHORT_ADDRESS,SHORT_ADDRESS); + mac_beacon_txmpdu_ptr->seq_num = mac_PIB.macBSN; + mac_PIB.macBSN++; + + + //relocation error + mac_beacon_addr_short_ptr->destination_PAN_identifier= mac_PIB.macPANId; + //relocation error + mac_beacon_addr_short_ptr->destination_address = 0xffff; + //relocation error + mac_beacon_addr_short_ptr->source_address = mac_PIB.macShortAddress; + if (mac_PIB.macShortAddress == 0x0000) + { //the device is the PAN Coordinator + mac_beacon_addr_short_ptr->superframe_specification = set_superframe_specification(mac_PIB.macBeaconOrder,(uint8_t)mac_PIB.macSuperframeOrder,final_CAP_slot,0,1,mac_PIB.macAssociationPermit); + } + else + { + mac_beacon_addr_short_ptr->superframe_specification = set_superframe_specification(mac_PIB.macBeaconOrder,(uint8_t)mac_PIB.macSuperframeOrder,final_CAP_slot,0,1,mac_PIB.macAssociationPermit); + } + + mac_beacon_txmpdu_ptr->data[8] = set_gts_specification(GTS_descriptor_count,mac_PIB.macGTSPermit); + + mac_beacon_txmpdu_ptr->data[9] = set_pending_address_specification(short_addr_pending,long_addr_pending); + + data_count = 9; + packet_length = 15; + + + //BUILDING the GTS DESCRIPTORS + if( (GTS_descriptor_count + GTS_null_descriptor_count) > 0 ) + { + data_count++; + + for(i=0; i< 7 ; i++) + { + if( GTS_db[i].gts_id != 0x00 && GTS_db[i].DevAddressType != 0x0000) + { + + mac_beacon_txmpdu_ptr->data[data_count] = GTS_db[i].DevAddressType; + ////////////printfUART("B gts %i\n", (GTS_db[i].DevAddressType >> 8 ) ); + + data_count++; + mac_beacon_txmpdu_ptr->data[data_count] = (GTS_db[i].DevAddressType >> 8 ); + ////////////printfUART("B gts %i\n", GTS_db[i].DevAddressType ); + + data_count++; + + mac_beacon_txmpdu_ptr->data[data_count] = set_gts_descriptor(15-i,GTS_db[i].length); + data_count++; + ////printfUART("B gts %i\n", set_gts_descriptor(GTS_db[i].starting_slot,GTS_db[i].length) ); + + packet_length = packet_length + 3; + + if ( GTS_db[i].direction == 1 ) + { + gts_directions = gts_directions | (1 << i); + } + else + { + gts_directions = gts_directions | (0 << i); + } + ////printfUART("dir %i\n", gts_directions); + } + } + mac_beacon_txmpdu_ptr->data[9] = gts_directions; + //CHECK + packet_length++; + //BUILDING the NULL GTS DESCRIPTORS + if ( GTS_null_descriptor_count > 0 ) + { + for(i=0; i< 7 ; i++) + { + if( GTS_null_db[i].DevAddressType != 0x0000) + { + mac_beacon_txmpdu_ptr->data[data_count] = GTS_null_db[i].DevAddressType; + ////////////printfUART("B gts %i\n", (GTS_db[i].DevAddressType >> 8 ) ); + data_count++; + mac_beacon_txmpdu_ptr->data[data_count] = (GTS_null_db[i].DevAddressType >> 8 ); + ////////////printfUART("B gts %i\n", GTS_db[i].DevAddressType ); + data_count++; + mac_beacon_txmpdu_ptr->data[data_count] = 0x00; + data_count++; + ////////////printfUART("B gts %i\n", set_gts_descriptor(GTS_db[i].starting_slot,GTS_db[i].length) ); + packet_length = packet_length +3; + } + } + } + //resetting the GTS specification field + mac_beacon_txmpdu_ptr->data[8] = set_gts_specification(GTS_descriptor_count + GTS_null_descriptor_count,mac_PIB.macGTSPermit); + + + } + + pending_data_index = data_count; + data_count++; + //IMPLEMENT PENDING ADDRESSES + //temporary + //indirect_trans_count =0; + + if (indirect_trans_count > 0 ) + { + //IMPLEMENT THE PENDING ADDRESSES CONSTRUCTION + + for(i=0;i 0x00) + { + pkt_ptr = (MPDU *)&indirect_trans_queue[i].frame; + //ADD INDIRECT TRANSMISSION DESCRIPTOR + if(get_fc2_dest_addr(pkt_ptr->frame_control2) == SHORT_ADDRESS) + { + short_addr_pending++; + packet_length = packet_length + 2; + mac_beacon_txmpdu_ptr->data[data_count]=pkt_ptr->data[2]; + data_count++; + mac_beacon_txmpdu_ptr->data[data_count]=pkt_ptr->data[3]; + data_count++; + } + } + } + for(i=0;i 0x00) + { + if(get_fc2_dest_addr(pkt_ptr->frame_control2) == LONG_ADDRESS) + { + long_addr_pending++; + packet_length = packet_length + 8; + + mac_beacon_txmpdu_ptr->data[data_count]=pkt_ptr->data[0]; + data_count++; + mac_beacon_txmpdu_ptr->data[data_count]=pkt_ptr->data[1]; + data_count++; + mac_beacon_txmpdu_ptr->data[data_count]=pkt_ptr->data[2]; + data_count++; + mac_beacon_txmpdu_ptr->data[data_count]=pkt_ptr->data[3]; + data_count++; + mac_beacon_txmpdu_ptr->data[data_count]=pkt_ptr->data[4]; + data_count++; + mac_beacon_txmpdu_ptr->data[data_count]=pkt_ptr->data[5]; + data_count++; + mac_beacon_txmpdu_ptr->data[data_count]=pkt_ptr->data[6]; + data_count++; + mac_beacon_txmpdu_ptr->data[data_count]=pkt_ptr->data[7]; + data_count++; + + } + } + } + + } + mac_beacon_txmpdu_ptr->data[pending_data_index] = set_pending_address_specification(short_addr_pending,long_addr_pending); + + /* + //adding the beacon payload + if (mac_PIB.macBeaconPayloadLenght > 0 ) + { + for (i=0;i < mac_PIB.macBeaconPayloadLenght;i++) + { + mac_beacon_txmpdu_ptr->data[data_count] = mac_PIB.macBeaconPayload[i]; + data_count++; + packet_length++; + } + + + } + */ + mac_beacon_txmpdu_ptr->data[data_count] = 0x12; + data_count++; + packet_length++; + mac_beacon_txmpdu_ptr->data[data_count] = 0x34; + data_count++; + packet_length++; + + //short_addr_pending=0; + //long_addr_pending=0; + + mac_beacon_txmpdu_ptr->length = packet_length; + + send_beacon_length = packet_length; + + send_beacon_frame_ptr = (uint8_t*)mac_beacon_txmpdu_ptr; + } +} + + +void create_data_frame(uint8_t SrcAddrMode, uint16_t SrcPANId, uint32_t SrcAddr[], uint8_t DstAddrMode, uint16_t DestPANId, uint32_t DstAddr[], uint8_t msduLength, uint8_t msdu[],uint8_t msduHandle, uint8_t TxOptions,uint8_t on_gts_slot,uint8_t pan) +{ + + int i_indirect_trans=0; + + dest_short *dest_short_ptr; + dest_long *dest_long_ptr; + + source_short *source_short_ptr; + source_long *source_long_ptr; + + //intra_pan_source_short *intra_pan_source_short_ptr; + //intra_pan_source_long *intra_pan_source_long_ptr; + + //CHECK + uint8_t intra_pan=0; + uint8_t data_len=0; + + uint8_t current_gts_element_count=0; + + MPDU *frame_pkt=0; + + uint16_t frame_control; + + //printfUART("create df\n",""); + + //decision of the buffer where to store de packet creation + if (on_gts_slot > 0 ) + { + + if (PANCoordinator == 1) + { + //setting the coordinator gts frame pointer + + //get the number of frames in the gts_slot_list + atomic current_gts_element_count = gts_slot_list[15-on_gts_slot].element_count; + + //////////printfUART("element count %i\n",gts_slot_list[15-on_gts_slot].element_count); + + if (current_gts_element_count == GTS_SEND_BUFFER_SIZE || available_gts_index_count == 0) + { + //////////printfUART("FULL\n",""); + signal MCPS_DATA.confirm(0x00, MAC_TRANSACTION_OVERFLOW); + return; + } + else + { + frame_pkt = (MPDU *) >s_send_buffer[available_gts_index[available_gts_index_count]]; + } + + } + else + { + //setting the device gts frame pointer + ////////////printfUART("start creation %i %i %i \n",gts_send_buffer_count,gts_send_buffer_msg_in,gts_send_buffer_msg_out); + + if(gts_send_buffer_count == GTS_SEND_BUFFER_SIZE) + { + signal MCPS_DATA.confirm(0x00, MAC_TRANSACTION_OVERFLOW); + return; + } + if (gts_send_buffer_msg_in == GTS_SEND_BUFFER_SIZE) + gts_send_buffer_msg_in=0; + + frame_pkt = (MPDU *) >s_send_buffer[gts_send_buffer_msg_in]; + + } + } + else + { + + if ( get_txoptions_indirect_transmission(TxOptions) == 1) + { + + //CREATE THE INDIRECT TRANSMISSION PACKET POINTER + //check if the is enough space to store the indirect transaction + if (indirect_trans_count == INDIRECT_BUFFER_SIZE) + { + signal MCPS_DATA.confirm(0x00, MAC_TRANSACTION_OVERFLOW); + //////////printfUART("buffer full %i\n", indirect_trans_count); + return; + } + + for(i_indirect_trans=0;i_indirect_trans UPSTREAM_BUFFER_SIZE) + return; + + if(upstream_buffer_msg_in == UPSTREAM_BUFFER_SIZE) + upstream_buffer_msg_in=0; + + frame_pkt = (MPDU *) &upstream_buffer[upstream_buffer_msg_in]; + + } + else + { + + ////printfUART("sb %i\n", send_buffer_count); + + if ((send_buffer_count +1) > SEND_BUFFER_SIZE) + return; + + if (send_buffer_msg_in == SEND_BUFFER_SIZE) + send_buffer_msg_in=0; + + frame_pkt = (MPDU *) &send_buffer[send_buffer_msg_in]; + } + + } + + + } + } + +atomic{ + + if (intra_pan == 0 ) + { + + if ( DstAddrMode > 1 && SrcAddrMode > 1 ) + { + // Destination LONG - Source LONG + if (DstAddrMode == LONG_ADDRESS && SrcAddrMode == LONG_ADDRESS) + { + dest_long_ptr = (dest_long *) &frame_pkt->data[0]; + source_long_ptr = (source_long *) &frame_pkt->data[DEST_LONG_LEN]; + + dest_long_ptr->destination_PAN_identifier=DestPANId; + dest_long_ptr->destination_address0=DstAddr[1]; + dest_long_ptr->destination_address1=DstAddr[0]; + + source_long_ptr->source_PAN_identifier=SrcPANId; + source_long_ptr->source_address0=SrcAddr[1]; + source_long_ptr->source_address1=SrcAddr[0]; + + data_len = 20; + } + + // Destination SHORT - Source LONG + if ( DstAddrMode == SHORT_ADDRESS && SrcAddrMode == LONG_ADDRESS ) + { + dest_short_ptr = (dest_short *) &frame_pkt->data[0]; + source_long_ptr = (source_long *) &frame_pkt->data[DEST_SHORT_LEN]; + + dest_short_ptr->destination_PAN_identifier=DestPANId; + dest_short_ptr->destination_address=(uint16_t)DstAddr[1]; + + source_long_ptr->source_PAN_identifier=SrcPANId; + source_long_ptr->source_address0=SrcAddr[1]; + source_long_ptr->source_address1=SrcAddr[0]; + + data_len = 14; + } + // Destination LONG - Source SHORT + if ( DstAddrMode == LONG_ADDRESS && SrcAddrMode == SHORT_ADDRESS ) + { + dest_long_ptr = (dest_long *) &frame_pkt->data[0]; + source_short_ptr = (source_short *) &frame_pkt->data[DEST_LONG_LEN]; + + dest_long_ptr->destination_PAN_identifier=DestPANId; + dest_long_ptr->destination_address0=DstAddr[1]; + dest_long_ptr->destination_address1=DstAddr[0]; + + source_short_ptr->source_PAN_identifier=SrcPANId; + source_short_ptr->source_address=(uint16_t)SrcAddr[1]; + + data_len = 14; + } + + + //Destination SHORT - Source SHORT + if ( DstAddrMode == SHORT_ADDRESS && SrcAddrMode == SHORT_ADDRESS ) + { + dest_short_ptr = (dest_short *) &frame_pkt->data[0]; + source_short_ptr = (source_short *) &frame_pkt->data[DEST_SHORT_LEN]; + + dest_short_ptr->destination_PAN_identifier=DestPANId; + dest_short_ptr->destination_address=(uint16_t)DstAddr[1]; + + source_short_ptr->source_PAN_identifier=SrcPANId; + source_short_ptr->source_address=(uint16_t)SrcAddr[1]; + + data_len = 8; + } + } + + if ( DstAddrMode == 0 && SrcAddrMode > 1 ) + { + + if (SrcAddrMode == LONG_ADDRESS) + {//Source LONG + source_long_ptr = (source_long *) &frame_pkt->data[0]; + + source_long_ptr->source_PAN_identifier=SrcPANId; + source_long_ptr->source_address0=SrcAddr[1]; + source_long_ptr->source_address1=SrcAddr[0]; + + data_len = 10; + } + else + {//Source SHORT + + source_short_ptr = (source_short *) &frame_pkt->data[0]; + + source_short_ptr->source_PAN_identifier=SrcPANId; + source_short_ptr->source_address=(uint16_t)SrcAddr[1]; + + data_len = 4; + } + } + + if ( DstAddrMode > 1 && SrcAddrMode == 0 ) + { + if (DstAddrMode == LONG_ADDRESS) + {//Destination LONG + dest_long_ptr = (dest_long *) &frame_pkt->data[0]; + + dest_long_ptr->destination_PAN_identifier=DestPANId; + dest_long_ptr->destination_address0=DstAddr[1]; + dest_long_ptr->destination_address1=DstAddr[0]; + + data_len = 10; + } + else + {//Destination SHORT + dest_short_ptr = (dest_short *) &frame_pkt->data[0]; + + dest_short_ptr->destination_PAN_identifier=DestPANId; + dest_short_ptr->destination_address=(uint16_t)DstAddr[1]; + + data_len = 4; + } + } + } + else + { + //intra_pan == 1 + + } + + memcpy(&frame_pkt->data[data_len],&msdu[0],msduLength*sizeof(uint8_t)); + + if(on_gts_slot > 0) + { + //preparing a GTS transmission + + ////////////printfUART("GTS send slt: %i count %i %u\n",on_gts_slot,gts_slot_list[15-on_gts_slot].element_count,mac_PIB.macDSN); + frame_pkt->length = data_len + msduLength + MPDU_HEADER_LEN; + + frame_control = set_frame_control(TYPE_DATA,0,0,1,intra_pan,DstAddrMode,SrcAddrMode); + frame_pkt->frame_control1 =(uint8_t)( frame_control); + frame_pkt->frame_control2 =(uint8_t)( frame_control >> 8); + + frame_pkt->seq_num = mac_PIB.macDSN; + mac_PIB.macDSN++; + + //ADDING DATA TO THE GTS BUFFER + atomic{ + if (PANCoordinator == 1) + { + gts_slot_list[15-on_gts_slot].element_count ++; + gts_slot_list[15-on_gts_slot].gts_send_frame_index[gts_slot_list[15-on_gts_slot].element_in] = available_gts_index[available_gts_index_count]; + //gts_slot_list[15-on_gts_slot].length = frame_pkt->length; + + gts_slot_list[15-on_gts_slot].element_in ++; + + if (gts_slot_list[15-on_gts_slot].element_in == GTS_SEND_BUFFER_SIZE) + gts_slot_list[15-on_gts_slot].element_in=0; + + available_gts_index_count --; + + //current_gts_pending_frame++; + } + else + { + gts_send_buffer_count++; + gts_send_buffer_msg_in++; + ////////////printfUART("end c %i %i %i \n",gts_send_buffer_count,gts_send_buffer_msg_in,gts_send_buffer_msg_out); + } + } + } + else + { + //////////printfUART("CSMA send %i\n", get_txoptions_ack(TxOptions)); + frame_pkt->length = data_len + msduLength + MPDU_HEADER_LEN; + //frame_pkt->frame_control = set_frame_control(TYPE_DATA,0,0,get_txoptions_ack(TxOptions),intra_pan,DstAddrMode,SrcAddrMode); + + frame_control = set_frame_control(TYPE_DATA,0,0,get_txoptions_ack(TxOptions),intra_pan,DstAddrMode,SrcAddrMode); + frame_pkt->frame_control1 =(uint8_t)( frame_control); + frame_pkt->frame_control2 =(uint8_t)( frame_control >> 8); + + frame_pkt->seq_num = mac_PIB.macDSN; + + //////printfUART("sqn %i\n", mac_PIB.macDSN); + + mac_PIB.macDSN++; + + if ( get_txoptions_indirect_transmission(TxOptions) == 1) + { + indirect_trans_queue[i_indirect_trans].handler = indirect_trans_count + 1; + indirect_trans_queue[i_indirect_trans].transaction_persistent_time = 0x0000; + + indirect_trans_count++; + + //////////printfUART("ADDED HDL: %i ADDR: %i\n",indirect_trans_count,DstAddr[1]); + } + else + { + if (get_txoptions_upstream_buffer(TxOptions) == 1) + { + upstream_buffer[upstream_buffer_msg_in].retransmission =0; + upstream_buffer[upstream_buffer_msg_in].indirect =0; + + upstream_buffer_count++; + + upstream_buffer_msg_in++; + + //printfUART("up bc %i\n", upstream_buffer_count); + post send_frame_csma_upstream(); + + } + else + { + + //enable retransmissions + send_buffer[send_buffer_msg_in].retransmission = 1; + send_buffer[send_buffer_msg_in].indirect = 0; + + send_buffer_count++; + + send_buffer_msg_in++; + + post send_frame_csma(); + } + + } + + } + + } +return; +} + + +error_t create_association_response_cmd(uint32_t DeviceAddress[],uint16_t shortaddress, uint8_t status) +{ + + cmd_association_response *mac_association_response; + dest_long *dest_long_ptr; + source_long *source_long_ptr; + + int i=0; + + MPDU *frame_pkt=0; + + uint16_t frame_control; + + //atomic{ + /* + if (send_buffer_msg_in == SEND_BUFFER_SIZE) + send_buffer_msg_in=0; + + frame_pkt = (MPDU *) &send_buffer[send_buffer_msg_in]; + */ + + //check if the is enough space to store the indirect transaction + if (indirect_trans_count == INDIRECT_BUFFER_SIZE) + { + printfUART("i full",""); + return MAC_TRANSACTION_OVERFLOW; + } + + for(i=0;idata[0]; + source_long_ptr = (source_long *) &frame_pkt->data[DEST_LONG_LEN]; + + mac_association_response = (cmd_association_response *) &frame_pkt->data[DEST_LONG_LEN + SOURCE_LONG_LEN]; + + frame_pkt->length = 29; + //frame_pkt->frame_control = set_frame_control(TYPE_CMD,0,0,1,0,LONG_ADDRESS,LONG_ADDRESS); + + frame_control = set_frame_control(TYPE_CMD,0,0,1,0,LONG_ADDRESS,LONG_ADDRESS); + + frame_pkt->frame_control1 =(uint8_t)( frame_control); + frame_pkt->frame_control2 =(uint8_t)( frame_control >> 8); + + frame_pkt->seq_num = mac_PIB.macDSN; + mac_PIB.macDSN++; + + dest_long_ptr->destination_PAN_identifier = mac_PIB.macPANId; + + dest_long_ptr->destination_address0 = DeviceAddress[1]; + dest_long_ptr->destination_address1 = DeviceAddress[0]; + + source_long_ptr->source_PAN_identifier = mac_PIB.macPANId; + + source_long_ptr->source_address0 = aExtendedAddress0; + source_long_ptr->source_address1 = aExtendedAddress1; + + mac_association_response->command_frame_identifier = CMD_ASSOCIATION_RESPONSE; + + //mac_association_response->short_address = shortaddress; + mac_association_response->short_address1 = (uint8_t)(shortaddress); + mac_association_response->short_address2 = (uint8_t)(shortaddress >> 8); + + + mac_association_response->association_status = status; +/* + + //increment the send buffer variables + send_buffer_count++; + send_buffer_msg_in++; + } + post send_frame_csma(); +*/ + printfUART("ASS RESP S: %i\n",shortaddress); + + indirect_trans_queue[i].handler = indirect_trans_count+1; + + indirect_trans_queue[i].transaction_persistent_time = 0x0000; + + indirect_trans_count++; + + printfUART("IAD\n", ""); + +return MAC_SUCCESS; +} + + +void create_association_request_cmd(uint8_t CoordAddrMode,uint16_t CoordPANId,uint32_t CoordAddress[],uint8_t CapabilityInformation) +{ +atomic{ + + cmd_association_request *cmd_association_request_ptr; + dest_short *dest_short_ptr; + source_long *source_long_ptr; + + MPDU *frame_pkt=0; + + uint16_t frame_control; + + if (send_buffer_msg_in == SEND_BUFFER_SIZE) + send_buffer_msg_in=0; + + frame_pkt = (MPDU *) &send_buffer[send_buffer_msg_in]; + + //creation of a pointer to the association response structure + dest_short_ptr = (dest_short *) &frame_pkt->data[0]; + source_long_ptr = (source_long *) &frame_pkt->data[DEST_SHORT_LEN]; + + cmd_association_request_ptr = (cmd_association_request *) &send_buffer[send_buffer_msg_in].data[DEST_SHORT_LEN + SOURCE_LONG_LEN]; + + frame_pkt->length = 21; + //frame_pkt->frame_control = set_frame_control(TYPE_CMD,0,0,1,0,SHORT_ADDRESS,LONG_ADDRESS); + + frame_control = set_frame_control(TYPE_CMD,0,0,1,0,SHORT_ADDRESS,LONG_ADDRESS); + frame_pkt->frame_control1 =(uint8_t)( frame_control); + frame_pkt->frame_control2 =(uint8_t)( frame_control >> 8); + + frame_pkt->seq_num = mac_PIB.macDSN; + + association_cmd_seq_num = mac_PIB.macDSN; + + mac_PIB.macDSN++; + + //enable retransmissions + send_buffer[send_buffer_msg_in].retransmission =1; + send_buffer[send_buffer_msg_in].indirect = 0; + + dest_short_ptr->destination_PAN_identifier = CoordPANId; //mac_PIB.macPANId; + + if (CoordAddrMode == SHORT_ADDRESS ) + { + dest_short_ptr->destination_address = (uint16_t)(CoordAddress[1] & 0x000000ff) ; //mac_PIB.macPANId; + } + else + { + //CHECK + + //implement the long address version + + } + + source_long_ptr->source_PAN_identifier = 0xffff; + + source_long_ptr->source_address0 = aExtendedAddress0; + source_long_ptr->source_address1 = aExtendedAddress1; + + cmd_association_request_ptr->command_frame_identifier = CMD_ASSOCIATION_REQUEST; + + cmd_association_request_ptr->capability_information = CapabilityInformation; + + //increment the send buffer variables + send_buffer_count++; + send_buffer_msg_in++; + + pending_request_data=1; + + ////printfUART("Association request %i %i \n", send_buffer_count,send_buffer_msg_in); + + + post send_frame_csma(); + + } +return; +} + +void create_data_request_cmd() +{ + //////////printfUART("create_data_request_cmd\n", ""); + +atomic{ + //dest_short *dest_short_ptr; + source_long *source_long_ptr; + + + MPDU *frame_pkt; + + uint16_t frame_control; + + if (send_buffer_msg_in == SEND_BUFFER_SIZE) + send_buffer_msg_in=0; + + frame_pkt = (MPDU *) &send_buffer[send_buffer_msg_in]; + + + source_long_ptr= (source_long *) &send_buffer[send_buffer_msg_in].data[0]; + + //creation of a pointer to the association response structure + //dest_short_ptr = (dest_short *) &frame_pkt->data[0]; + source_long_ptr = (source_long *) &frame_pkt->data[0]; + + + frame_pkt->length = 16; + //frame_pkt->frame_control = set_frame_control(TYPE_CMD,0,0,1,1,0,LONG_ADDRESS); //dest | source + + frame_control = set_frame_control(TYPE_CMD,0,0,1,1,0,LONG_ADDRESS); + frame_pkt->frame_control1 =(uint8_t)( frame_control); + frame_pkt->frame_control2 =(uint8_t)( frame_control >> 8); + + frame_pkt->seq_num = mac_PIB.macDSN; + + mac_PIB.macDSN++; + + //enable retransmissions + send_buffer[send_buffer_msg_in].retransmission =1; + send_buffer[send_buffer_msg_in].indirect = 0; + + + source_long_ptr->source_PAN_identifier = mac_PIB.macPANId; + + source_long_ptr->source_address0 = aExtendedAddress0;//aExtendedAddress0; + source_long_ptr->source_address1 = aExtendedAddress1; + + //command_frame_identifier = CMD_DATA_REQUEST; + frame_pkt->data[SOURCE_LONG_LEN]=CMD_DATA_REQUEST; + + //increment the send buffer variables + send_buffer_count++; + send_buffer_msg_in++; + + post send_frame_csma(); + + + } +return; +} + +void create_beacon_request_cmd() +{ + +atomic{ + cmd_beacon_request *mac_beacon_request; + + MPDU *frame_pkt; + + uint16_t frame_control; + + if (send_buffer_msg_in == SEND_BUFFER_SIZE) + send_buffer_msg_in=0; + + frame_pkt = (MPDU *) &send_buffer[send_buffer_msg_in]; + + mac_beacon_request= (cmd_beacon_request*) &send_buffer[send_buffer_msg_in].data; + + frame_pkt->length = 10; + //frame_pkt->frame_control = set_frame_control(TYPE_CMD,0,0,0,0,SHORT_ADDRESS,0); //dest | source + + frame_control = set_frame_control(TYPE_CMD,0,0,0,0,SHORT_ADDRESS,0); + frame_pkt->frame_control1 =(uint8_t)( frame_control); + frame_pkt->frame_control2 =(uint8_t)( frame_control >> 8); + + frame_pkt->seq_num = mac_PIB.macDSN; + + mac_PIB.macDSN++; + + //enable retransmissions + send_buffer[send_buffer_msg_in].retransmission =1; + send_buffer[send_buffer_msg_in].indirect = 0; + + mac_beacon_request->destination_PAN_identifier = 0xffff; + + mac_beacon_request->destination_address = 0xffff; + + mac_beacon_request->command_frame_identifier = CMD_BEACON_REQUEST; + + + //increment the send buffer variables + send_buffer_count++; + send_buffer_msg_in++; + + post send_frame_csma(); + + } + +return; +} + +void create_orphan_notification() +{ + + atomic{ + + cmd_default *cmd_orphan_notification=0; + + dest_short *dest_short_ptr=0; + source_long *source_long_ptr=0; + + MPDU *frame_pkt=0; + + uint16_t frame_control=0; + + if (send_buffer_msg_in == SEND_BUFFER_SIZE) + send_buffer_msg_in=0; + + frame_pkt = (MPDU *) &send_buffer[send_buffer_msg_in]; + + frame_pkt->length = 20; + + cmd_orphan_notification = (cmd_default*) &send_buffer[send_buffer_msg_in].data[DEST_SHORT_LEN + SOURCE_LONG_LEN]; + + //creation of a pointer the addressing structures + dest_short_ptr = (dest_short *) &frame_pkt->data[0]; + source_long_ptr = (source_long *) &frame_pkt->data[DEST_SHORT_LEN]; + + + frame_control = set_frame_control(TYPE_CMD,0,0,0,0,SHORT_ADDRESS,LONG_ADDRESS); + frame_pkt->frame_control1 =(uint8_t)( frame_control); + frame_pkt->frame_control2 =(uint8_t)( frame_control >> 8); + + + frame_pkt->seq_num = mac_PIB.macDSN; + + mac_PIB.macDSN++; + + + dest_short_ptr->destination_PAN_identifier = 0xffff; //mac_PIB.macPANId; + + dest_short_ptr->destination_address = 0xffff ; //mac_PIB.macPANId; + + source_long_ptr->source_PAN_identifier = 0xffff; + + source_long_ptr->source_address0 = aExtendedAddress0; + source_long_ptr->source_address1 = aExtendedAddress1; + + + cmd_orphan_notification->command_frame_identifier = CMD_ORPHAN_NOTIFICATION; + + //increment the send buffer variables + send_buffer_count++; + send_buffer_msg_in++; + + post send_frame_csma(); + } + +return; +} + + +void create_coordinator_realignment_cmd(uint32_t device_extended0, uint32_t device_extended1, uint16_t device_short_address) +{ + +atomic{ + + cmd_coord_realignment *cmd_realignment =0; + + dest_long *dest_long_ptr=0; + source_short *source_short_ptr=0; + + MPDU *frame_pkt=0; + + uint16_t frame_control=0; + + if (send_buffer_msg_in == SEND_BUFFER_SIZE) + send_buffer_msg_in=0; + + frame_pkt = (MPDU *) &send_buffer[send_buffer_msg_in]; + + frame_pkt->length = 27; + //frame_pkt->frame_control = set_frame_control(TYPE_CMD,0,0,0,0,SHORT_ADDRESS,0); //dest | source + + cmd_realignment = (cmd_coord_realignment*) &send_buffer[send_buffer_msg_in].data[DEST_LONG_LEN + SOURCE_SHORT_LEN]; + + //creation of a pointer the addressing structures + dest_long_ptr = (dest_long *) &frame_pkt->data[0]; + source_short_ptr = (source_short *) &frame_pkt->data[DEST_LONG_LEN]; + + + frame_control = set_frame_control(TYPE_CMD,0,0,0,0,LONG_ADDRESS,SHORT_ADDRESS); + frame_pkt->frame_control1 =(uint8_t)( frame_control); + frame_pkt->frame_control2 =(uint8_t)( frame_control >> 8); + + frame_pkt->seq_num = mac_PIB.macDSN; + + mac_PIB.macDSN++; + + dest_long_ptr->destination_PAN_identifier = 0xffff; + dest_long_ptr->destination_address0 = device_extended0; + dest_long_ptr->destination_address1 = device_extended1; + + source_short_ptr->source_PAN_identifier = mac_PIB.macPANId; + source_short_ptr->source_address = mac_PIB.macCoordShortAddress; + + + cmd_realignment->command_frame_identifier = CMD_COORDINATOR_REALIGNMENT; + + mac_PIB.macPANId = 0x1234; + + mac_PIB.macCoordShortAddress =0x0000; + + cmd_realignment->PAN_identifier0 = (mac_PIB.macPANId); + cmd_realignment->PAN_identifier1 = (mac_PIB.macPANId >> 8); + + cmd_realignment->coordinator_short_address0 = (mac_PIB.macCoordShortAddress); + cmd_realignment->coordinator_short_address1 = (mac_PIB.macCoordShortAddress >> 8); + + cmd_realignment->logical_channel = LOGICAL_CHANNEL; + cmd_realignment->short_address = device_short_address; + + + //increment the send buffer variables + send_buffer_count++; + send_buffer_msg_in++; + + post send_frame_csma(); + + } + +return; +} + + +void create_gts_request_cmd(uint8_t gts_characteristics) +{ +atomic{ + cmd_gts_request *mac_gts_request; + + MPDU *frame_pkt; + + uint16_t frame_control; + ////printfUART("create_gts_request_cmd\n", ""); + + + if (send_buffer_msg_in == SEND_BUFFER_SIZE) + send_buffer_msg_in=0; + + frame_pkt = (MPDU *) &send_buffer[send_buffer_msg_in]; + + mac_gts_request= (cmd_gts_request*) &send_buffer[send_buffer_msg_in].data; + + frame_pkt->length = 11; + + if ( get_characteristic_type(gts_characteristics) != 0 ) + { + //frame_pkt->frame_control = set_frame_control(TYPE_CMD,0,0,1,1,0,SHORT_ADDRESS); //dest | source + + frame_control = set_frame_control(TYPE_CMD,0,0,1,1,0,SHORT_ADDRESS); + frame_pkt->frame_control1 =(uint8_t)( frame_control); + frame_pkt->frame_control2 =(uint8_t)( frame_control >> 8); + } + else + { + //frame_pkt->frame_control = set_frame_control(TYPE_CMD,0,0,1,1,0,SHORT_ADDRESS); + + frame_control = set_frame_control(TYPE_CMD,0,0,1,1,0,SHORT_ADDRESS); + frame_pkt->frame_control1 =(uint8_t)( frame_control); + frame_pkt->frame_control2 =(uint8_t)( frame_control >> 8); + } + + frame_pkt->seq_num = mac_PIB.macDSN; + + gts_request_seq_num = frame_pkt->seq_num; + + mac_PIB.macDSN++; + + //enable retransmissions + send_buffer[send_buffer_msg_in].retransmission =1; + send_buffer[send_buffer_msg_in].indirect = 0; + + //mac_gts_request->source_PAN_identifier = 0x0001; + mac_gts_request->source_PAN_identifier = mac_PIB.macPANId; + + mac_gts_request->source_address = mac_PIB.macShortAddress; + + mac_gts_request->command_frame_identifier = CMD_GTS_REQUEST; + + //mac_gts_request->gts_characteristics = set_gts_characteristics(2,1,1); + mac_gts_request->gts_characteristics =gts_characteristics; + + //increment the send buffer variables + send_buffer_count++; + send_buffer_msg_in++; + + post send_frame_csma(); + + } + +return; +} + +void create_disassociation_notification_cmd(uint32_t DeviceAddress[],uint8_t disassociation_reason) +{ + + atomic{ + cmd_disassociation_notification *mac_disassociation_notification; + MPDU *frame_pkt; + + uint16_t frame_control; + + if (send_buffer_msg_in == SEND_BUFFER_SIZE) + send_buffer_msg_in=0; + + frame_pkt = (MPDU *) &send_buffer[send_buffer_msg_in]; + + //creation of a pointer to the disassociation notification structure + mac_disassociation_notification = (cmd_disassociation_notification*) &send_buffer[send_buffer_msg_in].data; + + + frame_pkt->length = 27; + + //frame_pkt->frame_control = set_frame_control(TYPE_CMD,0,0,1,0,LONG_ADDRESS,LONG_ADDRESS); + + frame_control = set_frame_control(TYPE_CMD,0,0,1,0,LONG_ADDRESS,LONG_ADDRESS); + frame_pkt->frame_control1 =(uint8_t)( frame_control); + frame_pkt->frame_control2 =(uint8_t)( frame_control >> 8); + + frame_pkt->seq_num = mac_PIB.macDSN; + + mac_PIB.macDSN++; + + //enable retransmissions + send_buffer[send_buffer_msg_in].retransmission =1; + send_buffer[send_buffer_msg_in].indirect = 0; + + mac_disassociation_notification->destination_PAN_identifier = mac_PIB.macPANId; + + mac_disassociation_notification->destination_address0 = DeviceAddress[0]; + mac_disassociation_notification->destination_address1 = DeviceAddress[1]; + + mac_disassociation_notification->source_PAN_identifier = mac_PIB.macPANId; + + mac_disassociation_notification->source_address0 = aExtendedAddress0; + mac_disassociation_notification->source_address1 = aExtendedAddress1; + + mac_disassociation_notification->command_frame_identifier = CMD_DISASSOCIATION_NOTIFICATION; + + mac_disassociation_notification->disassociation_reason = disassociation_reason; + + //increment the send buffer variables + send_buffer_count++; + send_buffer_msg_in++; + + post send_frame_csma(); + + } +return; +} + + + +void build_ack(uint8_t sequence,uint8_t frame_pending) +{ + uint16_t frame_control; + atomic{ + mac_ack_ptr->length = ACK_LENGTH; + //mac_ack_ptr->frame_control = set_frame_control(TYPE_ACK,0,frame_pending,0,0,0,0); + + frame_control = set_frame_control(TYPE_ACK,0,frame_pending,0,0,0,0); + mac_ack_ptr->frame_control1 =(uint8_t)( frame_control); + mac_ack_ptr->frame_control2 =(uint8_t)( frame_control >> 8); + + mac_ack_ptr->seq_num = sequence; + + call PD_DATA.request(mac_ack_ptr->length,(uint8_t*)mac_ack_ptr); + } +} + + + +/*****************************************************************************************************/ +/*****************************************************************************************************/ +/*****************************************************************************************************/ +/************************ INTERFACES PROVIDED **********************************/ +/*****************************************************************************************************/ +/*****************************************************************************************************/ +/*****************************************************************************************************/ + +/*********************************************************/ +/**************MLME_SCAN********************************/ +/*********************************************************/ + +task void data_channel_scan_indication() +{ + uint8_t link_qual; + + beacon_addr_short *beacon_ptr; + + //printfUART("data_channel_scan_indication\n",""); + + atomic link_qual = link_quality; + + atomic buffer_count--; + + switch(scan_type) + { + case ED_SCAN: + if (scanned_values[current_scanning-1] < link_qual) + scanned_values[current_scanning-1] = link_qual; + break; + + case ACTIVE_SCAN:break; + + case PASSIVE_SCAN: + switch( (buffer_msg[current_msg_out].frame_control1 & 0x7) ) + { + case TYPE_BEACON: + ////////////printfUART("Received Beacon\n",""); + beacon_ptr = (beacon_addr_short*) (&buffer_msg[current_msg_out].data); + + //Beacon NOTIFICATION + //BUILD the PAN descriptor of the COORDINATOR + //assuming that the adress is short + scan_pans[current_scanning-1].CoordPANId = beacon_ptr->destination_PAN_identifier; + scan_pans[current_scanning-1].CoordAddress=beacon_ptr->source_address; + scan_pans[current_scanning-1].LogicalChannel=current_channel; + //superframe specification field + scan_pans[current_scanning-1].SuperframeSpec = beacon_ptr->superframe_specification; + + if (scan_pans[current_scanning-1].lqi < link_qual) + scan_pans[current_scanning-1].lqi = link_qual; + + break; + + default: break; + //atomic buffer_count--; + ////////////printfUART("Invalid frame type\n",""); + + } + break; + case ORPHAN_SCAN: + //printfUART("osrm\n",""); + switch( (buffer_msg[current_msg_out].frame_control1 & 0x7) ) + { + case TYPE_CMD: + //printfUART("received cmd\n",""); + if (buffer_msg[current_msg_out].data[SOURCE_SHORT_LEN+ DEST_LONG_LEN] == CMD_COORDINATOR_REALIGNMENT) + { + printfUART("pf\n",""); + atomic scanning_channels = 0; + call T_ScanDuration.stop(); + process_coordinator_realignment(&buffer_msg[current_msg_out]); + + } + + break; + default: break; + } + break; + + } + + atomic{ + current_msg_out++; + if ( current_msg_out == RECEIVE_BUFFER_SIZE ) + current_msg_out = 0; + } +return; +} +/*******************T_ScanDuration**************************/ +event void T_ScanDuration.fired() { + + current_scanning++; + + printfUART("cs%i c%i\n",current_scanning,(0x0A + current_scanning)); + + call PLME_SET.request(PHYCURRENTCHANNEL, (0x0A + current_scanning)); + + current_channel = (0x0A + current_scanning); + + + if (current_scanning == 16 ) + { + //printfUART("scan end\n",""); + + atomic scanning_channels = 0; + + switch(scan_type) + { + case ED_SCAN: + signal MLME_SCAN.confirm(MAC_SUCCESS,scan_type, 0x00, 16 , scanned_values,0x00); + break; + + case ACTIVE_SCAN:break; + + case PASSIVE_SCAN: + //event result_t confirm(uint8_t status,uint8_t ScanType, uint32_t UnscannedChannels, uint8_t ResultListSize, uint8_t EnergyDetectList[], SCAN_PANDescriptor PANDescriptorList[]); + signal MLME_SCAN.confirm(MAC_SUCCESS,scan_type, 0x00, 16 , 0x00, scan_pans); + break; + + case ORPHAN_SCAN: + //orphan scan + //send opphan command on every channel directed to the current PAN coordinator + printfUART("oph s end not found\n",""); + signal MLME_SCAN.confirm(MAC_SUCCESS,scan_type, 0x00, 16 , 0x00, scan_pans); + + break; + } + } + else + { + switch(scan_type) + { + case ORPHAN_SCAN: printfUART("con\n",""); + create_orphan_notification(); + break; + } + + call T_ScanDuration.startOneShot(scan_duration); + } + +} + + + +command error_t MLME_SCAN.request(uint8_t ScanType, uint32_t ScanChannels, uint8_t ScanDuration) +{ +//pag 93 + printfUART("MLME_SCAN.request\n", ""); + + atomic scanning_channels = 1; + scan_type = ScanType; + channels_to_scan = ScanChannels; + + atomic current_scanning=0; + + + switch(ScanType) + { + //ED SCAN only FFD + case ED_SCAN: + call TimerAsync.set_timers_enable(0x00); + /* + + scanning_channels = 1; + scan_type = ScanType; + current_scanning=0; + scan_count=0; + channels_to_scan = ScanChannels; + scan_duration = ((aBaseSuperframeDuration * pow(2,ScanDuration)) * 4.0) / 250.0; + + //////////printfUART("channels_to_scan %y scan_duration %y\n", channels_to_scan,scan_duration); + + call T_ed_scan.start(TIMER_REPEAT,1); + + call T_scan_duration.start(TIMER_ONE_SHOT,scan_duration); + */ + + + //calculate the scan_duration in miliseconds + //#ifdef PLATFORM_MICAZ + scan_duration = ((aBaseSuperframeDuration * (powf(2,ScanDuration)+1)) * EFFECTIVE_SYMBOL_VALUE) / 1000.0; + //#else + // scan_duration = ((aBaseSuperframeDuration * (powf(2,ScanDuration)+1)) * EFFECTIVE_SYMBOL_VALUE) / 1000.0; + //#endif + //scan_duration = 2000; + + call T_ScanDuration.startOneShot(scan_duration); + + //printfUART("channels_to_scan %y scan_duration %y\n", channels_to_scan,scan_duration); + break; + //active scan only FFD + case ACTIVE_SCAN: + call TimerAsync.set_timers_enable(0x00); + break; + //passive scan + case PASSIVE_SCAN: + call TimerAsync.set_timers_enable(0x00); + + //calculate the scan_duration in miliseconds + //#ifdef PLATFORM_MICAZ + // scan_duration = ((aBaseSuperframeDuration * (powf(2,ScanDuration)+1)) * EFFECTIVE_SYMBOL_VALUE) / 1000.0; + //#else + // scan_duration = ((aBaseSuperframeDuration * (powf(2,ScanDuration)+1)) * EFFECTIVE_SYMBOL_VALUE) / 1000.0; + //#endif + + + //defines the time (miliseconds) that the device listen in each channel + scan_duration = 2000; + + printfUART("channels_to_scan %y scan_duration %i\n", channels_to_scan,scan_duration); + + call T_ScanDuration.startOneShot(scan_duration); + + //printfUART("channels_to_scan %y scan_duration %i\n", channels_to_scan,scan_duration); + + //atomic trx_status = PHY_RX_ON; + //call PLME_SET_TRX_STATE.request(PHY_RX_ON); + + + + break; + //orphan scan + case ORPHAN_SCAN: + + call TimerAsync.set_timers_enable(0x01); + + scan_duration = 4000; + + printfUART("orphan cts %y sdur %i\n", channels_to_scan,scan_duration); + + call T_ScanDuration.startOneShot(scan_duration); + + break; + + default: + break; + } + +return SUCCESS; +} + + + +/*********************************************************/ +/**************MLME_ORPHAN********************************/ +/*********************************************************/ + +command error_t MLME_ORPHAN.response(uint32_t OrphanAddress[1],uint16_t ShortAddress,uint8_t AssociatedMember, uint8_t security_enabled) +{ + + if (AssociatedMember==0x01) + { + create_coordinator_realignment_cmd(OrphanAddress[0], OrphanAddress[1], ShortAddress); + } + +return SUCCESS; +} + +/*********************************************************/ +/**************MLME_SYNC********************************/ +/*********************************************************/ + + +command error_t MLME_SYNC.request(uint8_t logical_channel,uint8_t track_beacon) +{ + call PLME_SET.request(PHYCURRENTCHANNEL,logical_channel); + + call TimerAsync.set_timers_enable(0x01); + + printfUART("sync req\n", ""); + + atomic findabeacon = 1; + +return SUCCESS; +} + +/*********************************************************/ +/**************MLME_RESET********************************/ +/*********************************************************/ + + +command error_t MLME_RESET.request(uint8_t set_default_PIB) +{ + + +return SUCCESS; +} + +/*********************************************************/ +/**************MLME_GTS***********************************/ +/*********************************************************/ + +command error_t MLME_GTS.request(uint8_t GTSCharacteristics, bool security_enable) +{ + + //uint32_t wait_time; + //if there is no short address asigned the node cannot send a GTS request + if (mac_PIB.macShortAddress == 0xffff) + signal MLME_GTS.confirm(GTSCharacteristics,MAC_NO_SHORT_ADDRESS); + + //gts_ack=1; + + gts_request =1; + + create_gts_request_cmd(GTSCharacteristics); + +return SUCCESS; +} + + +/*********************************************************/ +/**************MLME_START*********************************/ +/*********************************************************/ + +command error_t MLME_START.request(uint32_t PANId, uint8_t LogicalChannel, uint8_t beacon_order, uint8_t superframe_order,bool pan_coodinator,bool BatteryLifeExtension,bool CoordRealignment,bool securityenable,uint32_t StartTime) +{ + + uint32_t BO_EXPONENT; + uint32_t SO_EXPONENT; + + ////////printfUART("MLME_START.request\n", ""); + //pag 102 + atomic { + PANCoordinator=1; + Beacon_enabled_PAN=1; + //TEST + //atomic mac_PIB.macShortAddress = 0x0000; + + + if ( mac_PIB.macShortAddress == 0xffff) + { + + signal MLME_START.confirm(MAC_NO_SHORT_ADDRESS); + return SUCCESS; + } + else + { + atomic mac_PIB.macBeaconOrder = beacon_order; + + if (beacon_order == 15) + atomic mac_PIB.macSuperframeOrder = 15; + else + atomic mac_PIB.macSuperframeOrder = superframe_order; + + + //PANCoordinator is set to TRUE + if (pan_coodinator == 1) + { + atomic mac_PIB.macPANId = PANId; + call PLME_SET.request(PHYCURRENTCHANNEL,LogicalChannel); + } + if (CoordRealignment == 1) + { + //generates and broadcasts a coordinator realignment command containing the new PANId and LogicalChannels + } + if (securityenable == 1) + { + //security parameters + } + } + + if (mac_PIB.macSuperframeOrder == 0) + SO_EXPONENT = 1; + else + { + SO_EXPONENT = powf(2,mac_PIB.macSuperframeOrder); + + } + if ( mac_PIB.macBeaconOrder == 0) + BO_EXPONENT = 1; + else + { + BO_EXPONENT = powf(2,mac_PIB.macBeaconOrder); + + } + } + + BI = aBaseSuperframeDuration * BO_EXPONENT; + + SD = aBaseSuperframeDuration * SO_EXPONENT; + //backoff_period + backoff = aUnitBackoffPeriod; + + + atomic time_slot = SD / NUMBER_TIME_SLOTS; + + call TimerAsync.set_backoff_symbols(backoff); + + call TimerAsync.set_bi_sd(BI,SD); + + atomic{ + + call TimerAsync.set_timers_enable(0x01); + + call TimerAsync.reset(); + + } + + //////////////////////////////////////////////////// + /////////////////TDBS IMPLEMENTATION//////////////// + //////////////////////////////////////////////////// + if(TYPE_DEVICE == ROUTER) + { + atomic parent_offset = StartTime; + + call TimerAsync.set_track_beacon(1); + //initialization of the timer that shedules the beacon transmission offset + call TimerAsync.set_track_beacon_start_ticks(StartTime,0x00001E00,0x00000000); + } + else + { + atomic I_AM_IN_PARENT_CAP = 1; + } + + signal MLME_START.confirm(MAC_SUCCESS); + + return SUCCESS; +} + +/*************************************************************/ +/**************MLME_ASSOCIATE*********************************/ +/*************************************************************/ + +command error_t MLME_ASSOCIATE.request(uint8_t LogicalChannel,uint8_t CoordAddrMode,uint16_t CoordPANId,uint32_t CoordAddress[],uint8_t CapabilityInformation,bool securityenable) +{ + //update current channel + //call PLME_SET.request(PHYCURRENTCHANNEL,LogicalChannel); + + //printfUART("MLME_ASSOCIATE.request\n", ""); + + //updates the PAN ID + atomic{ + mac_PIB.macPANId = CoordPANId; + mac_PIB.macCoordShortAddress = (uint16_t)(CoordAddress[1] & 0x000000ff); + } + + associating=1; //boolean variable stating that the device is trying to associate + + call TimerAsync.set_timers_enable(1); + + //call PLME_SET.request(PHYCURRENTCHANNEL, LogicalChannel); + + current_channel = LogicalChannel; + + //printfUART("SELECTED cord id %i\n", mac_PIB.macPANId); + //printfUART("CoordAddress %i\n", mac_PIB.macCoordShortAddress); + //printfUART("LogicalChannel %i\n", LogicalChannel); + //printfUART("Cordaddr %i\n",CoordAddress[0]); + //printfUART("Cordaddr %i\n",CoordAddress[1]); + /* + a_CoordAddrMode = CoordAddrMode; + a_CoordPANId=CoordPANId; + a_CoordAddress[0]=CoordAddress[0]; + a_CoordAddress[1]=CoordAddress[1]; + a_CapabilityInformation=CapabilityInformation; + a_securityenable=securityenable; + */ + create_association_request_cmd(CoordAddrMode,CoordPANId,CoordAddress,CapabilityInformation); + + return SUCCESS; +} + +command error_t MLME_ASSOCIATE.response(uint32_t DeviceAddress[], uint16_t AssocShortAddress, uint8_t status, bool securityenable) +{ + + error_t status_response; + + //////printfUART("MAR\n", ""); + + status_response = create_association_response_cmd(DeviceAddress,AssocShortAddress,status); + ////////////printfUART("MLME_ASSOCIATE.response\n", ""); + + +return SUCCESS; +} + +/*************************************************************/ +/**************MLME_DISASSOCIATE*********************************/ +/*************************************************************/ + +command error_t MLME_DISASSOCIATE.request(uint32_t DeviceAddress[], uint8_t disassociate_reason, bool securityenable) +{ + create_disassociation_notification_cmd(DeviceAddress,disassociate_reason); +return SUCCESS; +} + +/*********************************************************/ +/**************MLME_GET***********************************/ +/*********************************************************/ +command error_t MLME_GET.request(uint8_t PIBAttribute) +{ + + switch(PIBAttribute) + { + case MACACKWAITDURATION : signal MLME_GET.confirm(MAC_SUCCESS,PIBAttribute,&mac_PIB.macAckWaitDuration); + break; + case MACASSOCIATIONPERMIT: signal MLME_GET.confirm(MAC_SUCCESS,PIBAttribute,&mac_PIB.macAssociationPermit); + break; + case MACAUTOREQUEST : signal MLME_GET.confirm(MAC_SUCCESS,PIBAttribute,&mac_PIB.macAutoRequest); + break; + case MACBATTLIFEEXT: signal MLME_GET.confirm(MAC_SUCCESS,PIBAttribute,&mac_PIB.macBattLifeExt); + break; + case MACBATTLIFEEXTPERIODS: signal MLME_GET.confirm(MAC_SUCCESS,PIBAttribute,&mac_PIB.macBattLifeExtPeriods); + break; + case MACBEACONPAYLOAD: signal MLME_GET.confirm(MAC_SUCCESS,PIBAttribute, mac_PIB.macBeaconPayload); + break; + case MACMAXBEACONPAYLOADLENGTH: signal MLME_GET.confirm(MAC_SUCCESS,PIBAttribute,&mac_PIB.macBeaconPayloadLenght); + break; + case MACBEACONORDER: signal MLME_GET.confirm(MAC_SUCCESS,PIBAttribute,&mac_PIB.macBeaconOrder); + break; + case MACBEACONTXTIME: signal MLME_GET.confirm(MAC_SUCCESS,PIBAttribute,(uint8_t *)&mac_PIB.macBeaconTxTime); + break; + case MACBSN: signal MLME_GET.confirm(MAC_SUCCESS,PIBAttribute,&mac_PIB.macBSN); + break; + case MACCOORDEXTENDEDADDRESS: signal MLME_GET.confirm(MAC_SUCCESS,PIBAttribute,(uint8_t *) &mac_PIB.macCoordExtendedAddress0); + break; + case MACCOORDSHORTADDRESS: signal MLME_GET.confirm(MAC_SUCCESS,PIBAttribute,(uint8_t *) &mac_PIB.macCoordShortAddress); + break; + case MACDSN: signal MLME_GET.confirm(MAC_SUCCESS,PIBAttribute,&mac_PIB.macDSN); + break; + case MACGTSPERMIT: signal MLME_GET.confirm(MAC_SUCCESS,PIBAttribute,&mac_PIB.macGTSPermit); + break; + case MACMAXCSMABACKOFFS: signal MLME_GET.confirm(MAC_SUCCESS,PIBAttribute,&mac_PIB.macMaxCSMABackoffs); + break; + case MACMINBE: signal MLME_GET.confirm(MAC_SUCCESS,PIBAttribute,&mac_PIB.macMinBE); + break; + case MACPANID: signal MLME_GET.confirm(MAC_SUCCESS,PIBAttribute,(uint8_t *) &mac_PIB.macPANId); + break; + case MACPROMISCUOUSMODE: signal MLME_GET.confirm(MAC_SUCCESS,PIBAttribute,&mac_PIB.macPromiscuousMode); + break; + case MACRXONWHENIDLE: signal MLME_GET.confirm(MAC_SUCCESS,PIBAttribute,&mac_PIB.macRxOnWhenIdle); + break; + case MACSHORTADDRESS: signal MLME_GET.confirm(MAC_SUCCESS,PIBAttribute,(uint8_t *) &mac_PIB.macShortAddress); + break; + case MACSUPERFRAMEORDER: signal MLME_GET.confirm(MAC_SUCCESS,PIBAttribute,&mac_PIB.macSuperframeOrder); + break; + case MACTRANSACTIONPERSISTENCETIME: signal MLME_GET.confirm(MAC_SUCCESS,PIBAttribute,(uint8_t *) &mac_PIB.macTransactionPersistenceTime); + break; + + default: signal MLME_GET.confirm(MAC_UNSUPPORTED_ATTRIBUTE,PIBAttribute,0x00); + break; + } + +return SUCCESS; +} + +/*********************************************************/ +/**************MLME_SET***********************************/ +/*********************************************************/ +command error_t MLME_SET.request(uint8_t PIBAttribute,uint8_t PIBAttributeValue[]) +{ + +//int i; + +//printfUART("set %i\n",PIBAttribute); + +atomic{ + + switch(PIBAttribute) + { + + + case MACACKWAITDURATION : mac_PIB.macAckWaitDuration = PIBAttributeValue[0]; + //////////printfUART("mac_PIB.macAckWaitDuration: %x\n",mac_PIB.macAckWaitDuration); + signal MLME_SET.confirm(MAC_SUCCESS,PIBAttribute); + break; + + case MACASSOCIATIONPERMIT: if ((uint8_t)PIBAttributeValue[1] == 0x00) + { + mac_PIB.macAssociationPermit = 0x00; + } + else + { + mac_PIB.macAssociationPermit = 0x01; + } + ////////printfUART("mac_PIB.macAssociationPermit: %i %y\n",mac_PIB.macAssociationPermit,PIBAttributeValue[1]); + signal MLME_SET.confirm(MAC_SUCCESS,PIBAttribute); + break; + + case MACAUTOREQUEST : mac_PIB.macAutoRequest = PIBAttributeValue[0]; + //////////printfUART("mac_PIB.macAutoRequest: %i\n",mac_PIB.macAutoRequest); + signal MLME_SET.confirm(MAC_SUCCESS,PIBAttribute); + break; + + case MACBATTLIFEEXT: mac_PIB.macBattLifeExt = PIBAttributeValue[0]; + //////////printfUART("mac_PIB.macBattLifeExt %i\n",mac_PIB.macBattLifeExt); + signal MLME_SET.confirm(MAC_SUCCESS,PIBAttribute); + break; + case MACBATTLIFEEXTPERIODS: mac_PIB.macBattLifeExtPeriods = PIBAttributeValue[0]; + //////////printfUART("mac_PIB.macBattLifeExtPeriods %i\n",mac_PIB.macBattLifeExtPeriods); + signal MLME_SET.confirm(MAC_SUCCESS,PIBAttribute); + break; + + case MACBEACONPAYLOAD: /*for(i=0;i < mac_PIB.macBeaconPayloadLenght;i++) + { + mac_PIB.macBeaconPayload[i] = PIBAttributeValue[i]; + }*/ + + memcpy(&PIBAttributeValue[0],&mac_PIB.macBeaconPayload[0],mac_PIB.macBeaconPayloadLenght * sizeof(uint8_t)); + + signal MLME_SET.confirm(MAC_SUCCESS,PIBAttribute); + break; + + case MACMAXBEACONPAYLOADLENGTH: mac_PIB.macBeaconPayloadLenght = PIBAttributeValue[0]; + //////////printfUART("mac_PIB.macBeaconPayloadLenght %i\n",mac_PIB.macBeaconPayloadLenght); + signal MLME_SET.confirm(MAC_SUCCESS,PIBAttribute); + break; + + case MACBEACONORDER: mac_PIB.macBeaconOrder = PIBAttributeValue[0]; + //////////printfUART("mac_PIB.macBeaconOrder %i\n",mac_PIB.macBeaconOrder); + signal MLME_SET.confirm(MAC_SUCCESS,PIBAttribute); + break; + case MACBEACONTXTIME: mac_PIB.macBeaconTxTime =PIBAttributeValue[0]; + //////////printfUART("mac_PIB.macBeaconTxTime %i\n",mac_PIB.macBeaconTxTime); + signal MLME_SET.confirm(MAC_SUCCESS,PIBAttribute); + break; + case MACBSN: mac_PIB.macBSN = PIBAttributeValue[0]; + //////////printfUART("mac_PIB.macBSN %i\n",mac_PIB.macBSN); + signal MLME_SET.confirm(MAC_SUCCESS,PIBAttribute); + break; + + case MACCOORDEXTENDEDADDRESS: //mac_PIB.macCoordExtendedAddress0 = ((PIBAttributeValue[0] >> 24) | (PIBAttributeValue[1] >> 16) | (PIBAttributeValue[2] >> 8) | (PIBAttributeValue[3])) ; + //mac_PIB.macCoordExtendedAddress1 = ((PIBAttributeValue[4] >> 24) | (PIBAttributeValue[5] >> 16) | (PIBAttributeValue[6] >> 8) | (PIBAttributeValue[7])); + + //////////printfUART("mac_PIB.macCoordExtendedAddress0 %y\n",mac_PIB.macCoordExtendedAddress0); + //////////printfUART("mac_PIB.macCoordExtendedAddress1 %y\n",mac_PIB.macCoordExtendedAddress1); + signal MLME_SET.confirm(MAC_SUCCESS,PIBAttribute); + break; + + + case MACCOORDSHORTADDRESS: mac_PIB.macCoordShortAddress= ((PIBAttributeValue[0] << 8) |PIBAttributeValue[1]); + //printfUART("mac_PIB.macCoordShortAddress: %x\n",mac_PIB.macCoordShortAddress); + signal MLME_SET.confirm(MAC_SUCCESS,PIBAttribute); + break; + + case MACDSN: mac_PIB.macDSN = PIBAttributeValue[0]; + //////////printfUART("mac_PIB.macDSN: %x\n",mac_PIB.macDSN); + signal MLME_SET.confirm(MAC_SUCCESS,PIBAttribute); + break; + case MACGTSPERMIT: mac_PIB.macGTSPermit = PIBAttributeValue[0]; + //////////printfUART("mac_PIB.macGTSPermit: %x\n",mac_PIB.macGTSPermit); + signal MLME_SET.confirm(MAC_SUCCESS,PIBAttribute); + break; + case MACMAXCSMABACKOFFS: mac_PIB.macMaxCSMABackoffs = PIBAttributeValue[0]; + //////////printfUART("mac_PIB.macMaxCSMABackoffs: %x\n",mac_PIB.macMaxCSMABackoffs); + signal MLME_SET.confirm(MAC_SUCCESS,PIBAttribute); + break; + case MACMINBE: mac_PIB.macMinBE = PIBAttributeValue[0]; + //////////printfUART("mac_PIB.macMinBE: %x\n",mac_PIB.macMinBE); + signal MLME_SET.confirm(MAC_SUCCESS,PIBAttribute); + break; + + case MACPANID: mac_PIB.macPANId = ((PIBAttributeValue[0] << 8)| PIBAttributeValue[1]); + printfUART("mac_PIB.macPANId: %x\n",mac_PIB.macPANId); + + //TODO ENABLE HARDWARE VERIFICATION + //call CC2420Config.setPanAddr(mac_PIB.macPANId); + //call CC2420Config.setAddressRecognition(TRUE); + //call CC2420Config.sync(); + + call AddressFilter.set_coord_address(mac_PIB.macCoordShortAddress, mac_PIB.macPANId); + + + signal MLME_SET.confirm(MAC_SUCCESS,PIBAttribute); + break; + + case MACPROMISCUOUSMODE: mac_PIB.macPromiscuousMode = PIBAttributeValue[0]; + //////////printfUART("mac_PIB.macPromiscuousMode: %x\n",mac_PIB.macPromiscuousMode); + signal MLME_SET.confirm(MAC_SUCCESS,PIBAttribute); + break; + case MACRXONWHENIDLE: mac_PIB.macRxOnWhenIdle = PIBAttributeValue[0]; + //////////printfUART("mac_PIB.macRxOnWhenIdle: %x\n",mac_PIB.macRxOnWhenIdle); + signal MLME_SET.confirm(MAC_SUCCESS,PIBAttribute); + break; + + + case MACSHORTADDRESS: mac_PIB.macShortAddress = ((PIBAttributeValue[0] << 8) |PIBAttributeValue[1]); + + printfUART("mac_PIB.macShortAddress: %y\n",mac_PIB.macShortAddress); + + //TODO ENABLE HARDWARE VERIFICATION + //call CC2420Config.setPanAddr(0x0000); + //call CC2420Config.setShortAddr(0x0001); + //call CC2420Config.setAddressRecognition(TRUE); + //call CC2420Config.sync(); + + call AddressFilter.set_address(mac_PIB.macShortAddress, aExtendedAddress0, aExtendedAddress0); + + + signal MLME_SET.confirm(MAC_SUCCESS,PIBAttribute); + break; + + case MACSUPERFRAMEORDER: mac_PIB.macSuperframeOrder = PIBAttributeValue[0]; + //////////printfUART("mac_PIB.macSuperframeOrder: %x\n",mac_PIB.macSuperframeOrder); + signal MLME_SET.confirm(MAC_SUCCESS,PIBAttribute); + break; + + case MACTRANSACTIONPERSISTENCETIME: mac_PIB.macTransactionPersistenceTime = PIBAttributeValue[0]; + //////////printfUART("mac_PIB.macTransactionPersistenceTime: %y\n",mac_PIB.macTransactionPersistenceTime); + signal MLME_SET.confirm(MAC_SUCCESS,PIBAttribute); + break; + + default: signal MLME_SET.confirm(MAC_UNSUPPORTED_ATTRIBUTE,PIBAttribute); + break; + + + } + +} + +return SUCCESS; +} +/*************************************************************/ +/************** MCPS - DATA *******************/ +/*************************************************************/ + +command error_t MCPS_DATA.request(uint8_t SrcAddrMode, uint16_t SrcPANId, uint32_t SrcAddr[], uint8_t DstAddrMode, uint16_t DestPANId, uint32_t DstAddr[], uint8_t msduLength, uint8_t msdu[],uint8_t msduHandle, uint8_t TxOptions) +{ + int i; + //uint8_t valid_gts=0; + uint32_t total_ticks; + + //////printfUART("MCPS_DATA.request\n", ""); + //check conditions on page 58 + + //atomic mac_PIB.macShortAddress = TOS_LOCAL_ADDRESS; + + /* + //printfUART("SrcAddrMode %x\n", SrcAddrMode); + //printfUART("SrcPANId %x\n", SrcPANId); + //printfUART("SrcAddr %x\n", SrcAddr[0]); + //printfUART("SrcAddr %x\n", SrcAddr[1]); + //printfUART("DstAddrMode %x\n", DstAddrMode); + //printfUART("DestPANId %x\n", DestPANId); + //printfUART("DstAddr %x\n", DstAddr[0]); + //printfUART("DstAddr %x\n", DstAddr[1]); + //printfUART("msduLength %x\n", msduLength); + //printfUART("msduHandle %x\n", msduHandle); + //printfUART("TxOptions %x\n", TxOptions); + */ + + atomic{ + + if (mac_PIB.macShortAddress == 0xffff) + return FAIL; + } + + if(PANCoordinator == 1) + { + //PAN COORDINATOR OPERATION + ////////////printfUART("GTS TRANS: %i TxOptions: %u dest:%u\n", get_txoptions_gts(TxOptions),TxOptions,DstAddr[1]); + + if (get_txoptions_gts(TxOptions) == 1) + { + //GTS TRANSMISSION + for (i=0 ; i < 7 ; i++) + { + //SEARCH FOR A VALID GTS + if ( GTS_db[i].DevAddressType == (uint16_t)DstAddr[1] && GTS_db[i].direction == 1 && GTS_db[i].gts_id != 0) + { + + //atomic{ + ////////////printfUART("BUFFER UNTIL GTS SLOT n: %i ss: %i\n",number_time_slot,GTS_db[valid_gts].starting_slot); + create_data_frame(SrcAddrMode, SrcPANId, SrcAddr, DstAddrMode, DestPANId, DstAddr, msduLength, msdu, msduHandle, TxOptions,GTS_db[i].starting_slot,1); + //} + return SUCCESS; + break; + } + } + signal MCPS_DATA.confirm(msduHandle, MAC_INVALID_GTS); + return FAIL; + } + else + { + //NORMAL/INDIRECT TRANSMISSION + + ////////////printfUART("IND TRANS: %i TxOptions: %u\n", get_txoptions_indirect_transmission(TxOptions),TxOptions); + //check if its an indirect transmission + //if ( get_txoptions_indirect_transmission(TxOptions) == 1) + //{ + //INDIRECT TRANSMISSION + + ////////////printfUART("CREATE INDIRECT TRANSMISSION\n",""); + + + + + //} + //else + //{ + //NORMAL TRANSMISSION + //printfUART("SEND NO GTS NO IND\n",""); + create_data_frame(SrcAddrMode, SrcPANId, SrcAddr, DstAddrMode, DestPANId, DstAddr, msduLength, msdu, msduHandle, TxOptions,0,0); + //} + } + } + else + { + //NON PAN COORDINATOR OPERATION + atomic{ + + ////////////printfUART("sslot: %i ini %i\n",s_GTSss,init_s_GTSss); + //check if it a gts transmission + if (get_txoptions_gts(TxOptions) == 1) + { + //GTS TRANSMISSION + if (s_GTSss == 0x00) + { + ////////////printfUART("NO VALID GTS \n",""); + signal MCPS_DATA.confirm(msduHandle, MAC_INVALID_GTS); + } + else + { + total_ticks = call TimerAsync.get_total_tick_counter(); + msdu[0] =(uint8_t)(total_ticks >> 0 ); + msdu[1] =(uint8_t)(total_ticks >> 8); + msdu[2] =(uint8_t)(total_ticks >> 16); + msdu[3] =(uint8_t)(total_ticks >> 24); + + if (on_sync == 1 && s_GTSss > 0) + create_data_frame(SrcAddrMode, SrcPANId, SrcAddr, DstAddrMode, DestPANId, DstAddr, msduLength, msdu, msduHandle, TxOptions,s_GTSss,0); + } + } + else + { + //NORMAL TRANSMISSION + printfUART("TRnsm\n",""); + create_data_frame(SrcAddrMode, SrcPANId, SrcAddr, DstAddrMode, DestPANId, DstAddr, msduLength, msdu, msduHandle, TxOptions,0,0); + } + } + } + return SUCCESS; +} + + + + +/*************************************************************/ +/************** MCPS - PURGE *******************/ +/*************************************************************/ + +command error_t MCPS_PURGE.request(uint8_t msduHandle) +{ + + + +return SUCCESS; +} + +/*****************************************************************************************************/ +/*****************************************************************************************************/ +/*****************************************************************************************************/ +/************************ OTHER FUNCTIONS **********************************/ +/*****************************************************************************************************/ +/*****************************************************************************************************/ +/*****************************************************************************************************/ + +task void signal_loss() +{ + //TODO + atomic signal MLME_SYNC_LOSS.indication(beacon_loss_reason); //MAC_BEACON_LOSS + return; +} + +//inicialization of the mac constants +void init_MacCon() +{ +/*****************************************************/ +/* Boolean Variables */ +/*****************************************************/ +PANCoordinator = 0; +//(0 NO beacon transmission; 1 beacon transmission); +Beacon_enabled_PAN = 0; +//(SYNC)the device will try to track the beacon ie enable its receiver just before the espected time of each beacon +TrackBeacon=0; +//(SYNC)the device will try to locate one beacon +findabeacon=0; +//(RESET) when the reset command arrives it checks whether or not to reset the PIB +SetDefaultPIB=0; +/*****************************************************/ +/* Integer Variables */ +/*****************************************************/ +/* +//Beacon Interval +uint32_t BI; +//Superframe duration +uint32_t SD; +*/ +//(SYNC)number of beacons lost before sending a Beacon-Lost indication comparing to aMaxLostBeacons +missed_beacons=0; +//current_channel +current_channel=0; + + +/*****************************************************/ +/* Other Variables */ +/*****************************************************/ +pending_reset=0; + +} + +//inicialization of the mac PIB +void init_MacPIB() +{ + +atomic{ + //mac PIB default values + + //mac_PIB.macAckWaitDuration = 54; OLD VALUE//Number os symbols to wait for an acknowledgment + mac_PIB.macAckWaitDuration = 65; + + mac_PIB.macAssociationPermit = 1; //1 - PAN allowing associations + mac_PIB.macAutoRequest = 1; //indication if a device automatically sends a data request command if address is listed in the beacon frame + + mac_PIB.macBattLifeExt= 0; //batery life extension CSMA-CA + + mac_PIB.macBattLifeExtPeriods=6; + //mac_PIB.macBeaconPayload; //payload of the beacon + mac_PIB.macBeaconPayloadLenght=0; //beacon payload lenght + + mac_PIB.macBeaconTxTime=(0xffffff << 24); //***** + + + mac_PIB.macBSN=call Random.rand16(); //sequence number of the beacon frame + + + mac_PIB.macCoordExtendedAddress0 = 0x00000000; //64bits address of the coordinator with witch the device is associated + mac_PIB.macCoordExtendedAddress1 = 0x00000000; + + mac_PIB.macCoordShortAddress = 0x0000; //16bits address of the coordinator with witch the device is associated + + + if (DEVICE_DEPTH == 0x01) + mac_PIB.macCoordShortAddress =D1_PAN_SHORT; + if (DEVICE_DEPTH == 0x02) + mac_PIB.macCoordShortAddress =D2_PAN_SHORT; + if (DEVICE_DEPTH == 0x03) + mac_PIB.macCoordShortAddress =D3_PAN_SHORT; + if (DEVICE_DEPTH == 0x04) + mac_PIB.macCoordShortAddress =D4_PAN_SHORT; + + + mac_PIB.macDSN=call Random.rand16(); //sequence number of the transmited data or MAC command frame + + //alowing gts requests (used in beacon) + mac_PIB.macGTSPermit=1; // + + //Number of maximum CSMA backoffs + mac_PIB.macMaxCSMABackoffs=4; + mac_PIB.macMinBE=0; + + //mac_PIB.macPANId=0xffff; //16bits identifier of the PAN on witch this device is operating + mac_PIB.macPANId = MAC_PANID; + + mac_PIB.macPromiscuousMode=0; + mac_PIB.macRxOnWhenIdle=0; + + //mac_PIB.macShortAddress=TOS_LOCAL_ADDRESS; //16bits short address + mac_PIB.macShortAddress=0xffff; + + + mac_PIB.macBeaconOrder=7; //specification of how often the coordinator transmits a beacon + mac_PIB.macSuperframeOrder=3; + + //default mac_PIB.macTransactionPersistenceTime=0x01f4; + mac_PIB.macTransactionPersistenceTime=0x0010; + + //******************************************* + + } +} + +////////////////////////////////////////////////////////////// +////////////////////////CSMA-CA functions//////////////////// +///////////////////////////////////////////////////////////// + +/*****************************************************/ +/* SEND FRAME FUNCTION */ +/*****************************************************/ + +task void send_frame_csma_upstream() +{//used in TDBS + atomic{ + + ////////printfUART("sf %i, %i \n",send_buffer_count,upstream_buffer_count); + ////////printfUART("I_AM_IN_IP %i \n",I_AM_IN_IP); + ////printfUART("send up IPCAP %i %i \n",I_AM_IN_PARENT_CAP,upstream_buffer_count); + + //beacon synchronization + if(upstream_buffer_count > 0 && I_AM_IN_PARENT_CAP == 1) + { + + ////////printfUART("s up\n",""); + sending_upstream_frame =1; + + performing_csma_ca = 1; + + perform_csma_ca(); + } + + + } + +} + + +task void send_frame_csma() +{ + atomic{ + + // + ///printfUART("I_AM_IN_IP %i %i\n",I_AM_IN_IP,send_buffer_count); + + if ((send_buffer_count > 0 && send_buffer_count <= SEND_BUFFER_SIZE && performing_csma_ca == 0) || I_AM_IN_IP != 0) + { + ////printfUART("sf %i\n",send_buffer_count); + //////printfUART("peform\n",""); + + performing_csma_ca = 1; + + perform_csma_ca(); + } + else + { + //printfUART("NOT SEND\n",""); + } + + + } + +} + + +task void perform_csma_ca_slotted() +{ + uint8_t random_interval; + + + + //DEFERENCE CHANGE + if (check_csma_ca_send_conditions(send_buffer[send_buffer_msg_out].length,send_buffer[send_buffer_msg_out].frame_control1) == 1 ) + { + cca_deference = 0; + } + else + { + //nao e necessario + cca_deference = 1; + return; + } + + atomic{ + //printfUART("CCA: %i\n", call CCA.get()) ; + + if(call CCA.get() == CCA_BUSY ) + { + ////////////printfUART("CCA: 1\n", "") ; + //STEP 5 + CW--; + if (CW == 0 ) + { + //send functions + csma_cca_backoff_boundary =0; + + ////////printfUART("s_up_f %i\n",sending_upstream_frame); + //TDBS Implementation + if(sending_upstream_frame == 0) + { + + //////printfUART("rts %i\n",get_ack_request(send_buffer[send_buffer_msg_out].frame_control)); + + //verify if the message must be ack + if ( get_fc1_ack_request(send_buffer[send_buffer_msg_out].frame_control1) == 1 ) + { + send_ack_check=1; + ack_sequence_number_check=send_buffer[send_buffer_msg_out].seq_num; + //verify retransmission + send_retransmission = send_buffer[send_buffer_msg_out].retransmission; + //verify if its an indirect transmission + send_indirect_transmission = send_buffer[send_buffer_msg_out].indirect; + //SEND WITH ACK_REQUEST + call PD_DATA.request(send_buffer[send_buffer_msg_out].length,(uint8_t *)&send_buffer[send_buffer_msg_out]); + + //////printfUART("out ck\n",""); + + + call T_ackwait.startOneShot(ackwait_period); + } + else + { + + call PD_DATA.request(send_buffer[send_buffer_msg_out].length,(uint8_t *)&send_buffer[send_buffer_msg_out]); + + send_buffer_count --; + send_buffer_msg_out++; + + //failsafe + if(send_buffer_count > SEND_BUFFER_SIZE) + { + send_buffer_count =0; + send_buffer_msg_out=0; + send_buffer_msg_in=0; + } + + if (send_buffer_msg_out == SEND_BUFFER_SIZE) + send_buffer_msg_out=0; + + if (send_buffer_count > 0 && send_buffer_count <= SEND_BUFFER_SIZE) + post send_frame_csma(); + + //printfUART("sk %i\n",send_buffer_count); + + ////////printfUART("%i %i %i\n",send_buffer_count,send_buffer_msg_in,send_buffer_msg_out); + } + + } + else + { + //TDBS Implementation + + call PD_DATA.request(upstream_buffer[upstream_buffer_msg_out].length,(uint8_t *)&upstream_buffer[upstream_buffer_msg_out]); + + upstream_buffer_count --; + upstream_buffer_msg_out++; + + if (upstream_buffer_msg_out == UPSTREAM_BUFFER_SIZE) + upstream_buffer_msg_out=0; + + sending_upstream_frame=0; + } + performing_csma_ca = 0; + } + } + else + { + //CHECK NOT USED + //csma_backoff_counter++; + //csma_backoff_counter_inst++; + + if (NB < mac_PIB.macMaxCSMABackoffs) + { + //////////printfUART("NB:%i BE:%i L CW: %i\n",NB,BE,CW); + //STEP 4 + CW = 2; + NB++; + BE = min(BE+1,aMaxBE); + + //STEP 2 + //random_interval = pow(2,BE) - 1; + + //delay_backoff_period = (call Random.rand() & random_interval); + //verification of the backoff_deference + //DEFERENCE CHANGE + if (backoff_deference == 0) + { + random_interval = powf(2,BE) - 1; + delay_backoff_period = (call Random.rand16() & random_interval ); + + if (check_csma_ca_backoff_send_conditions((uint32_t) delay_backoff_period) == 1) + { + backoff_deference = 1; + } + } + else + { + backoff_deference = 0; + } + + + //delay_backoff_period=0; + + //printfUART("delay_backoff_period:%i\n",delay_backoff_period); + csma_delay=1; + } + else + { + //CSMA/CA FAIL + csma_delay=0; + csma_cca_backoff_boundary=0; + + send_buffer_count --; + send_buffer_msg_out++; + + //failsafe + if(send_buffer_count > SEND_BUFFER_SIZE) + { + send_buffer_count =0; + send_buffer_msg_out=0; + send_buffer_msg_in=0; + } + + if (send_buffer_msg_out == SEND_BUFFER_SIZE) + send_buffer_msg_out=0; + + if (send_buffer_count > 0 && send_buffer_count <= SEND_BUFFER_SIZE) + post send_frame_csma(); + + performing_csma_ca = 0; + + //printfUART("SLOTTED FAIL\n",""); + /* + if(associating == 1) + { + associating=0; + signal MLME_ASSOCIATE.confirm(0x0000,MAC_CHANNEL_ACCESS_FAILURE); + }*/ + } + } + } +return; +} + +task void perform_csma_ca_unslotted() +{ + uint8_t random_interval; + + atomic{ + if (NB < mac_PIB.macMaxCSMABackoffs) + { + //STEP 3 + //perform CCA + //////////printfUART("CCA: %i\n", TOSH_READ_CC_CCA_PIN()) ; + + //if CCA is clear send message + if(call CCA.get() == CCA_BUSY) + { + //send functions + //////////printfUART("UNSLOTTED SUCCESS\n",""); + atomic{ + csma_delay =0; + + + + if (check_csma_ca_send_conditions(send_buffer[send_buffer_msg_out].length,send_buffer[send_buffer_msg_out].frame_control1) == 1 ) + { + call PD_DATA.request(send_buffer[send_buffer_msg_out].length,(uint8_t *)&send_buffer[send_buffer_msg_out]); + + send_buffer_count --; + send_buffer_msg_out++; + + //failsafe + if(send_buffer_count > SEND_BUFFER_SIZE) + { + send_buffer_count =0; + send_buffer_msg_out=0; + send_buffer_msg_in=0; + } + + if (send_buffer_msg_out == SEND_BUFFER_SIZE) + send_buffer_msg_out=0; + } + + + performing_csma_ca =0; + + } + return; //SUCCESS + + } + + //CCA is not clear, perform new iteration of the CSMA/CA UNSLOTTED + + //STEP 4 + NB++; + BE = min(BE+1,aMaxBE); + + //////////printfUART("NB:%i BE:%i\n",NB,BE); + + //STEP 2 + //#ifdef PLATFORM_MICAZ + random_interval = powf(2,BE) - 1; + //#else + // random_interval = powf(2,BE) - 1; + //#endif + delay_backoff_period = (call Random.rand16() & random_interval ); + //delay_backoff_period=1; + csma_delay=1; + + ////////////printfUART("delay_backoff_period:%i\n",delay_backoff_period); + } + else + { + atomic csma_delay=0; + //////////printfUART("UNSLOTTED FAIL\n",""); + } + } +return; +} + + +void perform_csma_ca() +{ + uint8_t random_interval; + csma_slotted=1; + //STEP 1 + if (csma_slotted == 0 ) + { + atomic{ + //UNSLOTTED version + init_csma_ca(csma_slotted); + //STEP 2 + random_interval = powf(2,BE) - 1; + delay_backoff_period = (call Random.rand16() & random_interval ); + + csma_delay=1; + //////////printfUART("delay_backoff_period:%i\n",delay_backoff_period); + } + return; + } + else + { + //SLOTTED version + atomic{ + //DEFERENCE CHANGE + if (cca_deference==0) + { + init_csma_ca(csma_slotted); + if (mac_PIB.macBattLifeExt == 1 ) + { + BE = min(2, mac_PIB.macMinBE); + } + else + { + BE = mac_PIB.macMinBE; + } + csma_locate_backoff_boundary = 1; + } + else + { + cca_deference = 0; + csma_delay=0; + csma_locate_backoff_boundary=0; + csma_cca_backoff_boundary = 1; + + } + } + return; + } +} + + +uint8_t min(uint8_t val1, uint8_t val2) +{ + if (val1 < val2) + { + return val1; + } + else + { + return val2; + } +} + +void init_csma_ca(bool slotted) +{ + +//initialization of the CSMA/CA protocol variables + ////////////printfUART("init_csma_ca\n", "") ; + + csma_delay=0; + + if (slotted == 0 ) + { + NB=0; + BE=mac_PIB.macMinBE; + } + else + { + NB=0; + CW=2; + + csma_cca_backoff_boundary=0; + csma_locate_backoff_boundary=0; + } + +return; +} + + +uint8_t calculate_ifs(uint8_t pk_length) +{ + if (pk_length > aMaxSIFSFrameSize) + return aMinLIFSPeriod; // + ( ((pk_length * 8) / 250.00) / 0.34 ); + else + return aMinSIFSPeriod; // + ( ((pk_length * 8) / 250.00) / 0.34 ); +} + +uint32_t calculate_gts_expiration() +{ + uint32_t exp_res; + if( mac_PIB.macBeaconOrder > 9 ) + exp_res= 1; + else + { + //#ifdef PLATFORM_MICAZ + exp_res= powf(2,(8-mac_PIB.macBeaconOrder)); + //#else + // exp_res= powf(2,(8-mac_PIB.macBeaconOrder)); + //#endif + } + //////////printfUART("alculat %i\n",exp_res ) ; + return exp_res; +} + +uint8_t check_csma_ca_send_conditions(uint8_t frame_length,uint8_t frame_control1) +{ + uint8_t ifs_symbols; + uint32_t frame_tx_time; + uint32_t remaining_gts_duration; + + + ifs_symbols=calculate_ifs(frame_length); + //wait_ifs=1; + //call TimerAsync.set_ifs_symbols(ifs_symbols); + + ////////////printfUART("ifs_symbols %i\n",ifs_symbols ) ; + + if (get_fc1_ack_request(frame_control1) == 1 ) + frame_tx_time = frame_length + ACK_LENGTH + aTurnaroundTime + ifs_symbols; + else + frame_tx_time = frame_length + ifs_symbols; + + atomic remaining_gts_duration = time_slot - ( call TimerAsync.get_current_number_backoff_on_time_slot() * aUnitBackoffPeriod); + + ////////////printfUART("frame_tx %d remaing %d\n",frame_tx_time,remaining_gts_duration ) ; + + if (frame_tx_time < remaining_gts_duration) + return 1; + else + return 0; + +} + +//DEFERENCE CHANGE +uint8_t check_csma_ca_backoff_send_conditions(uint32_t delay_backoffs) +{ + + uint32_t number_of_sd_ticks=0; + uint32_t current_ticks=0; + uint32_t ticks_remaining =0; + uint32_t number_of_backoffs_remaining =0; + + number_of_sd_ticks = call TimerAsync.get_sd_ticks(); + + current_ticks = call TimerAsync.get_current_ticks(); + + ticks_remaining = number_of_sd_ticks - current_ticks; + + number_of_backoffs_remaining = ticks_remaining / 5; + + if (number_of_backoffs_remaining > delay_backoffs) + return 0; + else + return 1; + + + +} + +uint8_t check_gts_send_conditions(uint8_t frame_length) +{ + uint8_t ifs_symbols; + uint32_t frame_tx_time; + uint32_t remaining_gts_duration; + + + ifs_symbols=calculate_ifs(frame_length); + //wait_ifs=1; + //call TimerAsync.set_ifs_symbols(ifs_symbols); + + ////////////printfUART("ifs_symbols %i\n",ifs_symbols ) ; + + frame_tx_time = frame_length + ACK_LENGTH + aTurnaroundTime + ifs_symbols; + + remaining_gts_duration = time_slot - ( call TimerAsync.get_current_number_backoff_on_time_slot() * aUnitBackoffPeriod); + + ////////////printfUART("frame_tx %d remaing %d\n",frame_tx_time,remaining_gts_duration ) ; + + if (frame_tx_time < remaining_gts_duration) + return 1; + else + return 0; +} + +////////////////////////////////////////////////////////////// +////////////////////////GTS functions//////////////////////// +///////////////////////////////////////////////////////////// + +void init_GTS_db() +{ + //initialization of the GTS database + int i; +atomic{ + for (i=0 ; i < 7 ; i++) + { + GTS_db[i].gts_id=0x00; + GTS_db[i].starting_slot=0x00; + GTS_db[i].length=0x00; + GTS_db[i].direction=0x00; + GTS_db[i].DevAddressType=0x0000; + + } + } +return; +} + +error_t remove_gts_entry(uint16_t DevAddressType) +{ + uint8_t r_lenght=0; + //int r_start_slot=7; + int i; + + atomic{ + for (i=0; i < 7 ; i++) + { + if( GTS_db[i].DevAddressType == DevAddressType ) + { + + r_lenght = GTS_db[i].length; + //r_start_slot = i; + //delete the values + GTS_db[i].gts_id=0x00; + GTS_db[i].starting_slot=0x00; + GTS_db[i].length=0x00; + GTS_db[i].direction=0x00; + GTS_db[i].DevAddressType=0x0000; + GTS_db[i].expiration=0x00; + + ////////////printfUART("GTS Entry removed dev:%i len:%i pos %i\n", DevAddressType,r_lenght,i); + GTS_startslot = GTS_startslot + r_lenght; + GTS_descriptor_count--; + final_CAP_slot = final_CAP_slot + r_lenght; + } + + if ( r_lenght > 0) + { + if ( GTS_db[i].gts_id != 0x00 && GTS_db[i].DevAddressType !=0x0000) + { + GTS_db[i-r_lenght].gts_id = GTS_db[i].gts_id; + GTS_db[i-r_lenght].starting_slot = i-r_lenght; + GTS_db[i-r_lenght].length = GTS_db[i].length; + GTS_db[i-r_lenght].direction = GTS_db[i].direction; + GTS_db[i-r_lenght].DevAddressType = GTS_db[i].DevAddressType; + GTS_db[i-r_lenght].expiration = GTS_db[i].expiration; + + //delete the values + GTS_db[i].gts_id=0x00; + GTS_db[i].starting_slot=0x00; + GTS_db[i].length=0x00; + GTS_db[i].direction=0x00; + GTS_db[i].DevAddressType=0x0000; + GTS_db[i].expiration=0x00; + + ////////////printfUART("UPDATED\n","" ); + } + } + } + } +return SUCCESS; +} + +error_t add_gts_entry(uint8_t gts_length,bool direction,uint16_t DevAddressType) +{ + int i; + ////////////printfUART("ADDING gts_length: %i\n", gts_length); + ////////////printfUART("dir: %i\n", direction); + ////////////printfUART("addr: %i\n", DevAddressType); + + //check aMinCAPLength + if ( (GTS_startslot - gts_length) < 5 ) + { + ////////////printfUART("ADD FAIL%i\n", ""); + + } + + //if it has more than 7 timeslots alocated + if ( (GTS_startslot -gts_length) < 9 ) + { + return FAIL; + } + + //check if the address already exists in the GTS list + for (i=0 ; i < 7 ; i++) + { + if ( GTS_db[i].DevAddressType == DevAddressType && GTS_db[i].direction == direction && GTS_db[i].gts_id > 0) + { + ////////////printfUART("ALREADY ADDED\n", ""); + return FAIL; + } + if ( GTS_null_db[i].DevAddressType == DevAddressType && GTS_null_db[i].gts_id > 0) + { + ////////////printfUART("REJECTED\n", ""); + return FAIL; + } + + + } + +atomic{ + + ////////////printfUART("GTS_startslot: %i\n", GTS_startslot); + GTS_startslot = GTS_startslot - gts_length; + + GTS_db[15-GTS_startslot].gts_id=GTS_id; + GTS_db[15-GTS_startslot].starting_slot=GTS_startslot; + GTS_db[15-GTS_startslot].length=gts_length; + GTS_db[15-GTS_startslot].direction=direction; + GTS_db[15-GTS_startslot].DevAddressType=DevAddressType; + GTS_db[15-GTS_startslot].expiration=0x00; + + ////////////printfUART("GTS Entry added start:%i len:%i\n", GTS_startslot,gts_length); + + GTS_id++; + GTS_descriptor_count++; + + final_CAP_slot = final_CAP_slot - gts_length; + + } + return SUCCESS; +} + + +//GTS null functions +void init_GTS_null_db() +{ + //initialization of the GTS database + int i; + atomic{ + for (i=0 ; i < 7 ; i++) + { + GTS_null_db[i].gts_id=0x00; + GTS_null_db[i].starting_slot=0x00; + GTS_null_db[i].length=0x00; + //GTS_null_db[i].direction=0x00; + GTS_null_db[i].DevAddressType=0x0000; + GTS_null_db[i].persistencetime=0x00; + } + } +return; +} + + +error_t add_gts_null_entry(uint8_t gts_length,bool direction,uint16_t DevAddressType) +{ + int i; + + //check if the address already exists in the GTS list + for (i=0 ; i < 7 ; i++) + { + if ( GTS_null_db[i].DevAddressType == DevAddressType && GTS_null_db[i].gts_id > 0) + { + ////////////printfUART("ALREADY ADDED null\n", ""); + return FAIL; + } + } + + for (i=0 ; i < 7 ; i++) + { + if ( GTS_null_db[i].DevAddressType==0x0000 && GTS_null_db[i].gts_id == 0x00) + { + GTS_null_db[i].gts_id=GTS_id; + GTS_null_db[i].starting_slot=0x00; + GTS_null_db[i].length=0x00; + //GTS_null_db[i].direction=0x00; + GTS_null_db[i].DevAddressType=DevAddressType; + GTS_null_db[i].persistencetime=0x00; + + + ////////////printfUART("GTS null Entry added addr:%x\n", DevAddressType); + + GTS_id++; + GTS_null_descriptor_count++; + + return SUCCESS; + } + } + + +return FAIL; +} + +task void increment_gts_null() +{ + int i; + + ////////////printfUART("init inc\n",""); +atomic{ + for (i=0 ; i < 7 ; i++) + { + if ( GTS_null_db[i].DevAddressType != 0x0000 && GTS_null_db[i].gts_id != 0x00) + { + ////////////printfUART("increm %x\n", GTS_null_db[i].DevAddressType); + GTS_null_db[i].persistencetime++; + + } + + if ( GTS_null_db[i].persistencetime > (aGTSDescPersistenceTime -1) ) + { + GTS_null_db[i].gts_id=0x00; + GTS_null_db[i].starting_slot=0x00; + GTS_null_db[i].length=0x00; + //GTS_null_db[i].direction=0x00; + GTS_null_db[i].DevAddressType=0x0000; + GTS_null_db[i].persistencetime=0x00; + + ////////////printfUART("GTS null removed addr:%x\n", GTS_null_db[i].DevAddressType); + + atomic GTS_null_descriptor_count--; + } + + } + + } +////////////printfUART("end inc\n",""); +return; +} + +task void check_gts_expiration() +{ + int i; +////////////printfUART("init exp\n",""); +atomic{ + atomic gts_expiration=calculate_gts_expiration(); + ////////////printfUART("gts_expiration:%i\n", gts_expiration); + atomic gts_expiration=2; + ////////////printfUART("gts_expiration:%i\n", gts_expiration); + + for (i=0 ; i < 7 ; i++) + { + + if ( GTS_db[i].DevAddressType != 0x0000 && GTS_db[i].gts_id != 0x00) + { + if( GTS_db[i].expiration == (gts_expiration + 1) && GTS_db[i].direction ==0x00) + { + ////////////printfUART("GTS expired addr:%x\n", GTS_null_db[i].DevAddressType); + //remove gts, indicate on the gts null list + atomic{ + + add_gts_null_entry(GTS_db[i].length,GTS_db[i].direction,GTS_db[i].DevAddressType); + + remove_gts_entry(GTS_db[i].DevAddressType); + } + } + else + { + atomic GTS_db[i].expiration ++; + } + } + } + + + } + ////////////printfUART("end exp\n",""); +return; +} + +void init_available_gts_index() + { + int i=0; + atomic{ + available_gts_index_count = GTS_SEND_BUFFER_SIZE; + for(i=0;i < GTS_SEND_BUFFER_SIZE;i++) + { + available_gts_index[i]=i; + } + } + return; + } +/*****************************GTS BUFFER******************************/ +void init_gts_slot_list() +{ + int i=0; + for(i=0;i<7;i++) + { + gts_slot_list[i].element_count = 0x00; + gts_slot_list[i].element_in = 0x00; + gts_slot_list[i].element_out = 0x00; + } +} + + +task void start_coordinator_gts_send() +{ +atomic{ + + coordinator_gts_send_pending_data =0; + + if(gts_slot_list[15-number_time_slot].element_count > 0) + { + if (check_gts_send_conditions(gts_send_buffer[gts_slot_list[15-number_time_slot].gts_send_frame_index[gts_slot_list[15-number_time_slot].element_out]].length) == 1 ) + { + + gts_send_buffer[gts_slot_list[15-number_time_slot].gts_send_frame_index[gts_slot_list[15-number_time_slot].element_out]].length = gts_send_buffer[gts_slot_list[15-number_time_slot].gts_send_frame_index[gts_slot_list[15-number_time_slot].element_out]].length -2; + + call PD_DATA.request(gts_send_buffer[gts_slot_list[15-number_time_slot].gts_send_frame_index[gts_slot_list[15-number_time_slot].element_out]].length,(uint8_t *)>s_send_buffer[gts_slot_list[15-number_time_slot].gts_send_frame_index[gts_slot_list[15-number_time_slot].element_out]]); + + available_gts_index_count++; + available_gts_index[available_gts_index_count] = gts_slot_list[15-number_time_slot].gts_send_frame_index[gts_slot_list[15-number_time_slot].element_out]; + + gts_slot_list[15-number_time_slot].element_count--; + gts_slot_list[15-number_time_slot].element_out++; + + if (gts_slot_list[15-number_time_slot].element_out == GTS_SEND_BUFFER_SIZE) + gts_slot_list[15-number_time_slot].element_out=0; + + if(gts_slot_list[15-number_time_slot].element_count > 0 ) + { + coordinator_gts_send_pending_data =1; + coordinator_gts_send_time_slot = number_time_slot; + } + } + } +} +return; +} + +task void start_gts_send() +{ + + atomic{ + gts_send_pending_data = 0; + + if(gts_send_buffer_count > 0) + { + if (check_gts_send_conditions(gts_send_buffer[gts_send_buffer_msg_out].length) == 1 ) + { + + gts_send_buffer[gts_send_buffer_msg_out].length = gts_send_buffer[gts_send_buffer_msg_out].length -2; + + call PD_DATA.request(gts_send_buffer[gts_send_buffer_msg_out].length,(uint8_t *)>s_send_buffer[gts_send_buffer_msg_out]); + + gts_send_buffer_count --; + gts_send_buffer_msg_out++; + + if (gts_send_buffer_msg_out == GTS_SEND_BUFFER_SIZE) + gts_send_buffer_msg_out=0; + + ////////////printfUART("after send %i %i %i \n",gts_send_buffer_count,gts_send_buffer_msg_in,gts_send_buffer_msg_out); + + if (gts_send_buffer_count > 0) + gts_send_pending_data = 1; + } + } + +} +return; +} + +////////////////////////////////////////////////////////////// +//////////Indirect transmission functions//////////////////// +///////////////////////////////////////////////////////////// + +void init_indirect_trans_buffer() +{ + int i; + for(i=0;i 0x00) + { + frame_ptr = (MPDU *)indirect_trans_queue[i].frame; + destination_address=get_fc2_dest_addr(frame_ptr->frame_control2); + + switch(destination_address) + { + case LONG_ADDRESS: dest_long_ptr = (dest_long *) frame_ptr->data; + break; + case SHORT_ADDRESS: dest_short_ptr = (dest_short *) frame_ptr->data; + break; + } + + //check the full address + if ( (dest_long_ptr->destination_address0 == DeviceAddress[1] && dest_long_ptr->destination_address1 == DeviceAddress[0]) || ( dest_short_ptr->destination_address == (uint16_t)DeviceAddress[0] )) + { + + if (send_buffer_msg_in == SEND_BUFFER_SIZE) + send_buffer_msg_in=0; + + memcpy(&send_buffer[send_buffer_msg_in],(MPDU *) &indirect_trans_queue[i].frame,sizeof(MPDU)); + + //enable retransmissions + send_buffer[send_buffer_msg_in].retransmission =0; + send_buffer[send_buffer_msg_in].indirect = i + 1; + + //check upon reception + indirect_trans_queue[i].handler=0x00; + //verify temporary error on the association request + + indirect_trans_count--; + if(indirect_trans_count > INDIRECT_BUFFER_SIZE ) + { + indirect_trans_count=0; + } + + atomic send_buffer_count++; + atomic send_buffer_msg_in++; + + post send_frame_csma(); + + //printfUART("i send\n",""); + + return; + } + } + } + //printfUART("i not found",""); + + +return; +} +/* + event void CC2420Config.syncDone( error_t error ) + { + + //printfUART("CC2420Config %i p %x sa %x\n",call CC2420Config.isAddressRecognitionEnabled(),call CC2420Config.getPanAddr(), call CC2420Config.getShortAddr()); + + return; + } + +*/ + +/***************************DEBUG FUNCTIONS******************************/ +/* This function are list functions with the purpose of debug, to use then uncomment the declatarion +on top of this file*/ +/* + +void list_mac_pib() +{ +//////////printfUART("mac_PIB.macAckWaitDuration: %x\n",mac_PIB.macAckWaitDuration); +//////////printfUART("mac_PIB.macAssociationPermit: %i\n",mac_PIB.macAssociationPermit); +//////////printfUART("mac_PIB.macAutoRequest: %i\n",mac_PIB.macAutoRequest); +//////////printfUART("mac_PIB.macBattLifeExt %i\n",mac_PIB.macBattLifeExt); +//////////printfUART("mac_PIB.macBattLifeExtPeriods %i\n",mac_PIB.macBattLifeExtPeriods); +//beacon payload +//////////printfUART("mac_PIB.macBeaconPayloadLenght %i\n",mac_PIB.macBeaconPayloadLenght); +//////////printfUART("mac_PIB.macBeaconOrder %i\n",mac_PIB.macBeaconOrder); +//////////printfUART("mac_PIB.macBeaconTxTime %i\n",mac_PIB.macBeaconTxTime); +//////////printfUART("mac_PIB.macBSN %i\n",mac_PIB.macBSN); +//////////printfUART("mac_PIB.macCoordExtendedAddress0 %y\n",mac_PIB.macCoordExtendedAddress0); +//////////printfUART("mac_PIB.macCoordExtendedAddress1 %y\n",mac_PIB.macCoordExtendedAddress1); +//////////printfUART("mac_PIB.macCoordShortAddress: %x\n",mac_PIB.macCoordShortAddress); +//////////printfUART("mac_PIB.macDSN: %x\n",mac_PIB.macDSN); +//////////printfUART("mac_PIB.macGTSPermit: %x\n",mac_PIB.macGTSPermit); +//////////printfUART("mac_PIB.macMaxCSMABackoffs: %x\n",mac_PIB.macMaxCSMABackoffs); +//////////printfUART("mac_PIB.macMinBE: %x\n",mac_PIB.macMinBE); +//////////printfUART("mac_PIB.macPANId: %x\n",mac_PIB.macPANId); +//////////printfUART("mac_PIB.macPromiscuousMode: %x\n",mac_PIB.macPromiscuousMode); +//////////printfUART("mac_PIB.macRxOnWhenIdle: %x\n",mac_PIB.macRxOnWhenIdle); +//////////printfUART("mac_PIB.macShortAddress: %y\n",mac_PIB.macShortAddress); +//////////printfUART("mac_PIB.macSuperframeOrder: %x\n",mac_PIB.macSuperframeOrder); +//////////printfUART("mac_PIB.macTransactionPersistenceTime: %y\n",mac_PIB.macTransactionPersistenceTime); + +return; +} + +void list_gts() +{ + int i; + //////////printfUART("GTS list%i\n", GTS_descriptor_count); + + for (i=0; i< 7;i++) + { + //////////printfUART("GTSID: %i",GTS_db[i].gts_id); + //////////printfUART("start slot: %i",GTS_db[i].starting_slot); + //////////printfUART("lenght: %i",GTS_db[i].length); + //////////printfUART("dir: %i",GTS_db[i].direction); + //////////printfUART("DevAddressType: %i",GTS_db[i].DevAddressType); + //////////printfUART("expiration: %i \n",GTS_db[i].expiration); + } + +} + +void list_my_gts() +{ +atomic{ + //////////printfUART("SEND GTS s_GTSss: %i s_GTS_length: %i\n",s_GTSss,s_GTS_length); + + //////////printfUART("RECEIVE GTS r_GTSss: %i r_GTS_length: %i\n",r_GTSss,r_GTS_length); +} +} +*/ + +void list_indirect_trans_buffer() +{ + int i; + printfUART("indirect_trans_count %i\n", indirect_trans_count); + + for (i=0; i< INDIRECT_BUFFER_SIZE;i++) + { + printfUART("hand: %i \n",indirect_trans_queue[i].handler); + + //printfUART("start slot: %i",GTS_db[i].starting_slot); + + } + +} +/* +void list_gts_null() +{ + int i; + //////////printfUART("GTS null list%i\n", GTS_null_descriptor_count); + + for (i=0; i< GTS_null_descriptor_count;i++) + { + ////////////printfUART("GTSID: %i",GTS_null_db[i].gts_id); + //////////printfUART("start slot: %i",GTS_null_db[i].starting_slot); + //////////printfUART("lenght: %i",GTS_null_db[i].length); + ////////////printfUART("dir: %i",GTS_null_db[i].direction); + //////////printfUART("DevAddressType: %i \n",GTS_null_db[i].DevAddressType); + //////////printfUART("persistencetime: %i \n",GTS_null_db[i].persistencetime); + } + +} + +*/ + + +} + diff --git a/tos/lib/net/zigbee/ieee802154/macTDBS/mac_const.h b/tos/lib/net/zigbee/ieee802154/macTDBS/mac_const.h new file mode 100644 index 00000000..8c61d05a --- /dev/null +++ b/tos/lib/net/zigbee/ieee802154/macTDBS/mac_const.h @@ -0,0 +1,225 @@ +/* + * @author IPP HURRAY http://www.hurray.isep.ipp.pt/art-wise + * @author open-zb http://www.open-zb.net + * @author Andre Cunha + */ + +// The MAC constants are defined in here. +// Notice that these makes use of the PHY constants. +//pag 134 + +#ifndef __MAC_CONST__ +#define __MAC_CONST__ + + +#define aBaseSlotDuration 60 +#define aBaseSuperframeDuration 960 //aBaseSlotDuration*aNumSuperframeSlots + +//#define aExtendedAddress // This should be defined by the device! + +#define aMaxBE 5 //CSMA-CA + +#define aMaxBeaconOverhead 75 +#define aMaxBeaconPayloadLength aMaxPHYPacketSize-aMaxBeaconOverhead +#define aGTSDescPersistenceTime 4 +#define aMaxFrameOverhead 25 +#define aMaxFrameResponseTime 1220 +#define aMaxFrameRetries 1 + +//(SYNC)number of beacons lost before sending a Beacon-Lost indication +#define aMaxLostBeacons 4 +#define aMaxMACFrameSize aMaxPHYPacketSize-aMaxFrameOverhead +#define aMaxSIFSFrameSize 18 +#define aMinCAPLength 440 +#define aMinLIFSPeriod 40 +#define aMinSIFSPeriod 12 +#define aNumSuperframeSlots 16 +#define aResponseWaitTime 32*aBaseSuperframeDuration +#define aUnitBackoffPeriod 20 + + +#define TYPE_BEACON 0 +#define TYPE_DATA 1 +#define TYPE_ACK 2 +#define TYPE_CMD 3 + +#define SHORT_ADDRESS 2 +#define LONG_ADDRESS 3 +#define RESERVED_ADDRESS 1 + +#define NUMBER_TIME_SLOTS 16 + +#define ACK_LENGTH 5 + +//buffer sizes +#define MAX_GTS_BUFFER 7 + +//#define MAX_GTS_PEND 2 +//#define MAX_GTS_IN_SLOT 1 + +#define INDIRECT_BUFFER_SIZE 2 +#define RECEIVE_BUFFER_SIZE 4 +#define SEND_BUFFER_SIZE 3 + +#define UPSTREAM_BUFFER_SIZE 3 + +#define GTS_SEND_BUFFER_SIZE 3 + +#define BACKOFF_PERIOD_MS 0.34724 +#define BACKOFF_PERIOD_US 347.24 + +//value of each symbol in us +#define EFFECTIVE_SYMBOL_VALUE 17.362 + +// MAC PIB attribute +typedef struct +{ + //pag 135 + uint8_t macAckWaitDuration; + bool macAssociationPermit;//FDD + bool macAutoRequest; + bool macBattLifeExt; + uint8_t macBattLifeExtPeriods; + + uint8_t macBeaconPayload[aMaxBeaconPayloadLength];//FDD + + uint8_t macBeaconPayloadLenght;//FDD + uint8_t macBeaconOrder;//FDD + + uint32_t macBeaconTxTime;//FDD + uint8_t macBSN;//FDD + uint32_t macCoordExtendedAddress0; + uint32_t macCoordExtendedAddress1; + uint16_t macCoordShortAddress; + uint8_t macDSN; + bool macGTSPermit;//FDD + uint8_t macMaxCSMABackoffs; + uint8_t macMinBE; + uint16_t macPANId; + bool macPromiscuousMode;//FDD + bool macRxOnWhenIdle; + uint32_t macShortAddress; + uint8_t macSuperframeOrder;//FDD + uint32_t macTransactionPersistenceTime;//FDD + +} macPIB; + +// MAC PIB security ACL entry descriptor +typedef struct +{ + uint32_t ACLExtendedAddress[2]; + uint16_t ACLShortAddress; + uint16_t ACLPANId; + uint8_t ACLSecurityMaterialLength; + //variable string + uint8_t ACLSecurityMaterial; + uint8_t ACLSecuritySuite; + +}ACLDescriptor; + +// MAC PIB security attribute +typedef struct +{ + //pag 138 + ACLDescriptor macACLEntryDescriptorSet; + uint8_t macACLEntryDescriptorSetSize; + bool macDefaultSecurity; + uint8_t macDefaultSecurityMaterialLength; + //variable string + uint8_t macDefaultSecurityMaterial; + uint8_t macDefaultSecuritySuite; + uint8_t macSecurityMode; + +}macPIBsec; + +//MAC PANDescriptor +typedef struct +{ + //pag76 + uint8_t CoordAddrMode; + uint16_t CoordPANId; + uint32_t CoordAddress0; + uint32_t CoordAddress1; + uint8_t LogicalChannel; + //superframe specification field + uint16_t SuperframeSpec; + bool GTSPermit; + uint8_t LinkQuality; + uint32_t TimeStamp; + bool SecurityUse; + uint8_t ACLEntry; + bool SecurityFailure; + +}PANDescriptor; + +//GTS entry (used in the PAN coordinator) +typedef struct +{ + uint8_t gts_id; + uint8_t starting_slot; + uint8_t length; + uint8_t direction; + uint16_t DevAddressType; + uint8_t expiration; + +}GTSinfoEntryType; + +//GTS entry (used in the PAN coordinator) +typedef struct +{ + uint8_t gts_id; + uint8_t starting_slot; + uint8_t length; + uint16_t DevAddressType; + uint8_t persistencetime; + +}GTSinfoEntryType_null; + +typedef struct +{ + uint8_t handler; + uint16_t transaction_persistent_time; + + //MPDU frame; + uint8_t frame[127]; + +}indirect_transmission_element; + +typedef struct gts_slot_element +{ + uint8_t element_count; + uint8_t element_in; + uint8_t element_out; + uint8_t gts_send_frame_index[GTS_SEND_BUFFER_SIZE]; + +}gts_slot_element; + + +typedef struct time_stamp32 +{ + +uint32_t time_stamp; + +}time_stamp32; + +typedef struct time_stamp16 +{ + +uint16_t time_stamp; + +}time_stamp16; + +//MAC ACTIVE CHANNEL SCAN REDUCED PAN DESCRIPTOR (SHOR ADDRESS ONLY) +typedef struct SCAN_PANDescriptor +{ + //pag76 + uint16_t CoordPANId; + uint16_t CoordAddress; + uint8_t LogicalChannel; + //superframe specification field + uint16_t SuperframeSpec; + uint8_t lqi; +}SCAN_PANDescriptor; + + +#endif diff --git a/tos/lib/net/zigbee/ieee802154/macTDBS/mac_enumerations.h b/tos/lib/net/zigbee/ieee802154/macTDBS/mac_enumerations.h new file mode 100644 index 00000000..f8004b2c --- /dev/null +++ b/tos/lib/net/zigbee/ieee802154/macTDBS/mac_enumerations.h @@ -0,0 +1,117 @@ +/* + * @author IPP HURRAY http://www.hurray.isep.ipp.pt/art-wise + * @author open-zb http://www.open-zb.net + * @author Andre Cunha + */ + +#ifndef __MAC_ENUMERATIONS__ +#define __MAC_ENUMERATIONS__ + +//Mac enumerations standard pag 110 + +enum { + MAC_SUCCESS = 0x00, + MAC_BEACON_LOSS = 0xE0, + MAC_CHANNEL_ACCESS_FAILURE = 0xE1, + MAC_DENIED = 0xE2, + //MLME-RESET + MAC_DISABLE_TRX_FAILURE = 0xE3, + MAC_FAILED_SECURITY_CHECK = 0xE4, + MAC_FRAME_TOO_LONG = 0xE5, + MAC_INVALID_GTS = 0xE6, + MAC_INVALID_HANDLE = 0xE7, + MAC_INVALID_PARAMETER = 0xE8, + MAC_NO_ACK = 0xE9, + MAC_NO_BEACON = 0xEA, + MAC_NO_DATA = 0xEB, + MAC_NO_SHORT_ADDRESS = 0xEC, + MAC_OUT_OF_CAP = 0xED, + MAC_PAN_ID_CONFLICT = 0xEE, + MAC_REALIGNMENT = 0xEF, + MAC_TRANSACTION_EXPIRED = 0xF0, + MAC_TRANSACTION_OVERFLOW = 0xF1, + MAC_TX_ACTIVE = 0xF2, + MAC_UNAVAILABLE_KEY = 0xF3, + MAC_UNSUPPORTED_ATTRIBUTE = 0xF4 + }; + + + +//mac dissassociation enums +enum{ + MAC_PAN_COORD_LEAVE = 0x01, + MAC_PAN_DEVICE_LEAVE = 0x02, + +}; + + + +//mac commands enums +enum { + + CMD_ASSOCIATION_REQUEST = 0x01, + CMD_ASSOCIATION_RESPONSE = 0x02, + CMD_DISASSOCIATION_NOTIFICATION = 0x03, + CMD_DATA_REQUEST = 0x04, + CMD_PANID_CONFLICT = 0x05, + CMD_ORPHAN_NOTIFICATION = 0x06, + CMD_BEACON_REQUEST = 0x07, + CMD_COORDINATOR_REALIGNMENT = 0x08, + CMD_GTS_REQUEST = 0x09 +}; + + +//mac association responses +enum { + + CMD_RESP_ASSOCIATION_SUCCESSFUL = 0x00, + CMD_RESP_PAN_CAPACITY =0x01, + CMD_RESP_ACCESS_DENIED =0x02 + +}; + +//MAC PIB Enumeration +enum { + + MACACKWAITDURATION = 0x40, + MACASSOCIATIONPERMIT=0x41, + MACAUTOREQUEST = 0x42, + MACBATTLIFEEXT=0x43, + MACBATTLIFEEXTPERIODS=0x44, + MACBEACONPAYLOAD=0x45, + MACMAXBEACONPAYLOADLENGTH=0x46, + MACBEACONORDER=0x47, + MACBEACONTXTIME=0x48, + MACBSN=0x49, + MACCOORDEXTENDEDADDRESS=0x4a, + MACCOORDSHORTADDRESS=0x4b, + MACDSN=0x4c, + MACGTSPERMIT=0x4d, + MACMAXCSMABACKOFFS=0x4e, + MACMINBE=0x4f, + MACPANID=0x50, + MACPROMISCUOUSMODE=0x51, + MACRXONWHENIDLE=0x52, + MACSHORTADDRESS=0x53, + MACSUPERFRAMEORDER=0x54, + MACTRANSACTIONPERSISTENCETIME=0x55 + +}; + +//gts enumerations +enum{ + GTS_TX_ONLY = 0x00, + GTS_RX_ONLY = 0x01 +}; + +//channel scan enumerations +enum{ + ED_SCAN = 0x00, + ACTIVE_SCAN = 0x01, + PASSIVE_SCAN = 0x02, + ORPHAN_SCAN = 0x03 +}; + + +#endif + diff --git a/tos/lib/net/zigbee/ieee802154/nwk/Makefile b/tos/lib/net/zigbee/ieee802154/nwk/Makefile new file mode 100644 index 00000000..55edac20 --- /dev/null +++ b/tos/lib/net/zigbee/ieee802154/nwk/Makefile @@ -0,0 +1,12 @@ +COMPONENT=NWK + +PFLAGS += -I$(TOSROOT)/tos/ieee802154/includes \ + -I$(TOSROOT)/tos/ieee802154/mac \ + -I$(TOSROOT)/tos/ieee802154/phy \ + -I$(TOSROOT)/tos/ieee802154/timerasync \ + -I$(TOSROOT)/tos/ieee802154/interfaces \ + -I$(TOSROOT)/tos/ieee802154/interfaces/mac \ + -I$(TOSROOT)/tos/ieee802154/interfaces/phy \ + -I$(TOSROOT)/tos/chips/cc2420/ieee802154 +include $(MAKERULES) + diff --git a/tos/lib/net/zigbee/ieee802154/nwk/NWK.nc b/tos/lib/net/zigbee/ieee802154/nwk/NWK.nc new file mode 100644 index 00000000..a54e271f --- /dev/null +++ b/tos/lib/net/zigbee/ieee802154/nwk/NWK.nc @@ -0,0 +1,111 @@ +/* + * @author IPP HURRAY http://www.hurray.isep.ipp.pt/art-wise + * @author Andre Cunha + * + */ +#include + +#include "phy_const.h" +#include "phy_enumerations.h" +#include "mac_const.h" +#include "mac_enumerations.h" +#include "mac_func.h" + +#include "nwk_func.h" +#include "nwk_enumerations.h" +#include "nwk_const.h" + + +configuration NWK { + + //provides + + //NLDE NWK data service + + provides interface NLDE_DATA; + + + //NLME NWK Management service + + provides interface NLME_NETWORK_FORMATION; + provides interface NLME_NETWORK_DISCOVERY; + provides interface NLME_START_ROUTER; + provides interface NLME_JOIN; + provides interface NLME_LEAVE; + + /* + provides interface NLME_PERMIT_JOINING; + provides interface NLME_DIRECT_JOIN; + provides interface NLME_RESET; + */ + provides interface NLME_SYNC; + + provides interface NLME_GET; + provides interface NLME_SET; + +} +implementation { + + components MainC; + MainC.SoftwareInit -> NWKM; + + components LedsC; + components NWKM; + + components Mac; + + NWKM.Leds -> LedsC; + + + components RandomC; + NWKM.Random -> RandomC; + + + //MAC interfaces + + NWKM.MLME_START -> Mac.MLME_START; + + NWKM.MLME_GET ->Mac.MLME_GET; + NWKM.MLME_SET ->Mac.MLME_SET; + + NWKM.MLME_BEACON_NOTIFY ->Mac.MLME_BEACON_NOTIFY; + NWKM.MLME_GTS -> Mac.MLME_GTS; + + NWKM.MLME_ASSOCIATE->Mac.MLME_ASSOCIATE; + NWKM.MLME_DISASSOCIATE->Mac.MLME_DISASSOCIATE; + + NWKM.MLME_ORPHAN->Mac.MLME_ORPHAN; + NWKM.MLME_SYNC->Mac.MLME_SYNC; + NWKM.MLME_SYNC_LOSS->Mac.MLME_SYNC_LOSS; + NWKM.MLME_RESET->Mac.MLME_RESET; + + NWKM.MLME_SCAN->Mac.MLME_SCAN; + + + NWKM.MCPS_DATA->Mac.MCPS_DATA; + + + + //NLDE NWK data service + NLDE_DATA=NWKM; + + //NLME NWK Management service + NLME_NETWORK_FORMATION=NWKM; + NLME_NETWORK_DISCOVERY=NWKM; + + NLME_START_ROUTER=NWKM; + + NLME_JOIN=NWKM; + NLME_LEAVE=NWKM; + + /* + NLME_PERMIT_JOINING=NWKM; + NLME_DIRECT_JOIN=NWKM; + NLME_RESET=NWKM; + */ + NLME_SYNC=NWKM; + NLME_GET=NWKM; + NLME_SET=NWKM; + + +} diff --git a/tos/lib/net/zigbee/ieee802154/nwk/NWKM.nc b/tos/lib/net/zigbee/ieee802154/nwk/NWKM.nc new file mode 100644 index 00000000..be241313 --- /dev/null +++ b/tos/lib/net/zigbee/ieee802154/nwk/NWKM.nc @@ -0,0 +1,1501 @@ +/* + * @author IPP HURRAY http://www.hurray.isep.ipp.pt/art-wise + * @author Andre Cunha + * + */ +#include +#include "printfUART.h" + +module NWKM { + +//uses + uses interface Leds; + + //MAC interfaces + + uses interface MLME_START; + + uses interface MLME_GET; + uses interface MLME_SET; + + uses interface MLME_BEACON_NOTIFY; + uses interface MLME_GTS; + + uses interface MLME_ASSOCIATE; + uses interface MLME_DISASSOCIATE; + + uses interface MLME_ORPHAN; + + uses interface MLME_SYNC; + uses interface MLME_SYNC_LOSS; + + uses interface MLME_RESET; + + uses interface MLME_SCAN; + + + uses interface MCPS_DATA; + + + uses interface Random; + +//provides + + provides interface Init; + provides interface NLDE_DATA; + + //NLME NWK Management services + provides interface NLME_NETWORK_FORMATION; + provides interface NLME_NETWORK_DISCOVERY; + provides interface NLME_START_ROUTER; + provides interface NLME_JOIN; + provides interface NLME_LEAVE; + provides interface NLME_SYNC; + + /* + provides interface NLME_PERMIT_JOINING; + provides interface NLME_DIRECT_JOIN; + provides interface NLME_RESET; +*/ + provides interface NLME_GET; + provides interface NLME_SET; + + +} +implementation { + + + nwkIB nwk_IB; + + uint8_t device_type = END_DEVICE; + +/*****************************************************/ +/*************Neighbourtable Variables****************/ +/*****************************************************/ + + //neighbour table array: + neighbortableentry neighbortable[NEIGHBOUR_TABLE_SIZE]; + //number of neigbourtable entries: + uint8_t neighbour_count; + //the index of the parents neighbortable entry + uint8_t parent; + + +/*****************************************************/ +/****************ASSOCIATION Variables********************/ +/*****************************************************/ + + //CURRENT NETWORK ADDRESS + uint16_t networkaddress=0x0000; + + //COORDINATOR + //address assignement variables + uint8_t depth=0; + uint8_t cskip=0; + + uint8_t cskip_routing=0; + + //neighbour table parent index + uint8_t parent_index; + + //NON COORDINATOR + + //current pan characteristics + uint16_t panid; + uint8_t beaconorder; + uint8_t superframeorder; + + //next child router address + uint16_t next_child_router_address; + uint8_t number_child_router=0x01; + uint8_t number_child_end_devices=0x01; +/*****************************************************/ +/****************Integer Variables********************/ +/*****************************************************/ + + uint8_t joined=0; + uint8_t sync_loss=0; + //uint8_t synchronizing=0; + uint8_t syncwait; + + + //USED AFTER DE SCAN //GIVE SOME TIME TO THE DEVICE TO SYNC WITH THE PARENT + uint8_t received_beacon_count=0; + + uint8_t go_associate =0; + + PANDescriptor pan_des; + uint32_t coordinator_addr[2]; +/******************************************************/ +/*********NEIGHBOuRTABLE MANAGEMENT FUNCTIONS*********/ +/******************************************************/ + + void init_nwkIB(); + + uint8_t check_neighbortableentry(uint8_t addrmode,uint32_t Extended_Address0,uint32_t Extended_Address1); + + void add_neighbortableentry (uint16_t PAN_Id,uint32_t Extended_Address0,uint32_t Extended_Address1,uint32_t Network_Address,uint8_t Device_Type,uint8_t Relationship); + void update_neighbortableentry (uint16_t PAN_Id,uint32_t Extended_Address0,uint32_t Extended_Address1,uint32_t Network_Address,uint8_t Device_Type,uint8_t Relationship); + + uint8_t find_suitable_parent(); + + uint16_t Cskip(uint8_t d); + + uint16_t nexthopaddress(uint16_t destinationaddress,uint8_t d); + + void list_neighbourtable(); + + + + command error_t Init.init() { + + printfUART_init();//make the possibility to print + + init_nwkIB(); + + nwk_IB.nwkSequenceNumber=call Random.rand16(); + + return SUCCESS; + } + + + +/*****************************************************************************************************/ +/**************************************MLME-SCAN*******************************************************/ +/*****************************************************************************************************/ +event error_t MLME_SCAN.confirm(uint8_t status,uint8_t ScanType, uint32_t UnscannedChannels, uint8_t ResultListSize, uint8_t EnergyDetectList[], SCAN_PANDescriptor PANDescriptorList[]) +{ +//FAULT-TOLERANCE + +//the device channel scan ends with a scan confirm containing a list of the PANs (beacons received during the scan) + + int i; + uint8_t max_lqi=0; + uint8_t best_pan_index=0; + + + networkdescriptor networkdescriptorlist[1]; + + + //call Leds.redOff(); + + printfUART("4 rec scan\n", ""); + + //printfUART("MLME_SCAN.confirm %i\n", ScanType); + + if (ScanType == ORPHAN_SCAN) + { + printfUART("new scan \n", ""); + + call MLME_SCAN.request(PASSIVE_SCAN,0xFFFFFFFF,7); + return SUCCESS; + } + + + + if(ScanType == ED_SCAN) + { + for(i=0;i 0 ) + { + call MLME_ASSOCIATE.response(DeviceAddress,neighbortable[cindex - 1].Network_Address,MAC_SUCCESS,0); + } + else + { + if(nwk_IB.nwkAvailableAddresses > 0) + { + + //verify if the device is associating as a router or an end device + if ( get_alternate_PAN_coordinator(CapabilityInformation) == 1) + { + //add device to the neighbour table + add_neighbortableentry(panid,DeviceAddress[0],DeviceAddress[1],next_child_router_address,ROUTER,NEIGHBOR_IS_CHILD); + + printfUART("An_cr %x\n",next_child_router_address); + + //send response, this shall lead to confirm in child device + call MLME_ASSOCIATE.response(DeviceAddress,next_child_router_address,MAC_SUCCESS,0); + //calculate the next address + next_child_router_address = networkaddress + ((number_child_router-1) * cskip) +1 ; + //increment the number of associated routers + number_child_router++; + //decrese the number of available addresses //the available addresses are influenced by the network configurations + nwk_IB.nwkAvailableAddresses--; + + printfUART("Dn_cr %x\n",next_child_router_address); + } + else + { + //verify if its possible to associate children in the address space + //the number of end devices must be greater than 1 and lesser or iqual to maximum children minus maximum routers + if (number_child_end_devices > 1 && number_child_end_devices > (MAXCHILDREN - MAXROUTERS)) + { + call MLME_ASSOCIATE.response(DeviceAddress,0xffff,CMD_RESP_PAN_CAPACITY,0); + //return SUCCESS; + } + else + { + //CHECK COMMENTED ON SHORT VERSION + add_neighbortableentry(panid,DeviceAddress[0],DeviceAddress[1],nwk_IB.nwkNextAddress,END_DEVICE,NEIGHBOR_IS_CHILD); + //send response, this shall lead to confirm in child device + call MLME_ASSOCIATE.response(DeviceAddress,nwk_IB.nwkNextAddress,MAC_SUCCESS,0); + + nwk_IB.nwkNextAddress=nwk_IB.nwkNextAddress + nwk_IB.nwkAddressIncrement; + + number_child_end_devices++; + + nwk_IB.nwkAvailableAddresses--; + + } + } + + if (nwk_IB.nwkAvailableAddresses == 0 ) + { + call MLME_SET.request(MACASSOCIATIONPERMIT,(uint8_t *)0x00000000); + } + } + else + { + //if there are no available addresses the coordinator/router shall not respond to the association request + call MLME_ASSOCIATE.response(DeviceAddress,0xffff,CMD_RESP_PAN_CAPACITY,0); + } + } +} + return SUCCESS; +} + +event error_t MLME_ASSOCIATE.confirm(uint16_t AssocShortAddress, uint8_t status) +{ + + uint8_t v_temp[2]; + ////printfUART("MLME_ASSOCIATE.confirm\n",""); + + if (AssocShortAddress == 0xffff) + { + //association failed + //printfUART("nwkass fail\n",""); + signal NLME_JOIN.confirm(panid,NWK_NOT_PERMITTED); + + } + else + { + + networkaddress = AssocShortAddress; + //add_neighbortableentry(panid,DeviceAddress[0],DeviceAddress[1],nwk_IB.nwkNextAddress,END_DEVICE,NEIGHBOR_IS_CHILD); + //set the short address + + if (status == MAC_SUCCESS) + { + joined = 0x01; + v_temp[0] = (uint8_t)(networkaddress >> 8); + v_temp[1] = (uint8_t)(networkaddress ); + + //call MLME_SET.request(MACSHORTADDRESS,(uint32_t*)(uint32_t)&networkaddress); + call MLME_SET.request(MACSHORTADDRESS,v_temp); + + signal NLME_JOIN.confirm(panid, NWK_SUCCESS); + } + else + { + signal NLME_JOIN.confirm(panid,NWK_NOT_PERMITTED); + } + } + return SUCCESS; +} +/*****************************************************************************************************/ +/**************************************MLME-DISASSOCIATE**********************************************/ +/*****************************************************************************************************/ +event error_t MLME_DISASSOCIATE.indication(uint32_t DeviceAddress[], uint8_t DisassociateReason, bool SecurityUse, uint8_t ACLEntry) +{ + ////printfUART("MLME_DISASSOCIATE.indication:SUCCESS\n", ""); + signal NLME_LEAVE.confirm(DeviceAddress, NWK_SUCCESS); + + return SUCCESS; +} + +event error_t MLME_DISASSOCIATE.confirm(uint8_t status) +{ + if (status == MAC_SUCCESS) + { + signal NLME_LEAVE.confirm(0, status); + ////printfUART("MLME_DISASSOCIATE.confirm:SUCCESS\n", ""); + } + else + { + signal NLME_LEAVE.confirm(0, NWK_LEAVE_UNCONFIRMED); + ////printfUART("MLME_DISASSOCIATE.confirm:leave unconfirmed\n", ""); + } + + return SUCCESS; +} +/*****************************************************************************************************/ +/*****************************************************************************************************/ +/**************** MCPS EVENTS *************************************/ +/*****************************************************************************************************/ +/*****************************************************************************************************/ + + +/*****************************************************************************************************/ +/********************* MCPS-DATA ***************************************/ +/*****************************************************************************************************/ +event error_t MCPS_DATA.confirm(uint8_t msduHandle, uint8_t status) +{ + ////printfUART("MCPS_DATA.confirm\n", ""); + signal NLDE_DATA.confirm(1,status); + + return SUCCESS; +} +event error_t MCPS_DATA.indication(uint16_t SrcAddrMode, uint16_t SrcPANId, uint32_t SrcAddr[2], uint16_t DstAddrMode, uint16_t DestPANId, uint32_t DstAddr[2], uint16_t msduLength,uint8_t msdu[100],uint16_t mpduLinkQuality, uint16_t SecurityUse, uint16_t ACLEntry) +{ + uint8_t payload[100]; + uint32_t route_destination_address[2]; + uint32_t net_addr[2]; + uint8_t next_hop_index; + + routing_fields *routing_fields_ptr; + routing_fields_ptr = (routing_fields *)&msdu[0]; + + net_addr[1] =(uint32_t) networkaddress; + net_addr[0]=0x00000000; + + if ( routing_fields_ptr->destination_address == networkaddress) + { + //I am the destination + memcpy(&payload,&msdu[8],(msduLength-8)*sizeof(uint8_t)); + + //pass data on to APL layer + signal NLDE_DATA.indication(routing_fields_ptr->source_address,(uint16_t)(msduLength-8),payload, mpduLinkQuality); + + return SUCCESS; + } + else + { + //I am not the destination + if(device_type != COORDINATOR) + { + if( (networkaddress < routing_fields_ptr->destination_address) && (routing_fields_ptr->destination_address < (networkaddress + cskip_routing ) ) ) + { + printfUART("route down to appropriate child\n", ""); + + //check if destination is one of my children + next_hop_index = check_neighbortableentry(SHORT_ADDRESS,(uint32_t)routing_fields_ptr->destination_address,0x00000000); + + if (next_hop_index == 0) + { + //destination is not my child + route_destination_address[0]=0x00000000; + route_destination_address[1]=nexthopaddress(routing_fields_ptr->destination_address,depth); + } + else + { + //Im routing to my child + route_destination_address[0]=0x00000000; + route_destination_address[1]=neighbortable[next_hop_index-1].Network_Address; + } + //send message + call MCPS_DATA.request(SHORT_ADDRESS, panid, net_addr, SHORT_ADDRESS, DestPANId, route_destination_address, msduLength, msdu,1,set_txoptions(1,0,0,0)); + } + else + { + + //changes to meet with the BEACON SYNCHRONIZATION requirements + //route up to the parent + atomic{ + route_destination_address[0]=0x00000000; + route_destination_address[1]=neighbortable[parent].Network_Address; + + call MCPS_DATA.request(SHORT_ADDRESS, panid, net_addr, SHORT_ADDRESS, DestPANId, route_destination_address, msduLength, msdu,1,set_txoptions_upstream(1,0,0,0,1)); + } + } + } + else + { + //I AM THE PAN COORDINATOR + //THE COORDINATOR ALWAYS ROUTES DOWN + + //route down to appropriate child + //check if destination is one of my children + next_hop_index = check_neighbortableentry(SHORT_ADDRESS,(uint32_t)routing_fields_ptr->destination_address,0x00000000); + + if (next_hop_index == 0 ) + { + //no entry in neigbortable + //calculate route address + route_destination_address[0]=0x00000000; + route_destination_address[1]=nexthopaddress(routing_fields_ptr->destination_address,depth); + + call MCPS_DATA.request(SHORT_ADDRESS, panid, net_addr, SHORT_ADDRESS, DestPANId, route_destination_address, msduLength, msdu,1,set_txoptions(1,0,0,0)); + } + else + { + //is my child + route_destination_address[0]=0x00000000; + route_destination_address[1]=neighbortable[next_hop_index-1].Network_Address; + + call MCPS_DATA.request(SHORT_ADDRESS, panid, net_addr, SHORT_ADDRESS, DestPANId, route_destination_address, msduLength, msdu,1,set_txoptions(1,0,0,0)); + } + + } + + + } + +return SUCCESS; +} + + +/*************************************************************/ +/*******************NLDE IMPLEMENTATION***********************/ +/*************************************************************/ + +/*************************************************************/ +/*************************NLDE - DATA*************************/ +/*************************************************************/ + +//This primitive requests the transfer of a data PDU +//page 159-161 + +command error_t NLDE_DATA.request(uint16_t DstAddr, uint16_t NsduLength, uint8_t Nsdu[100], uint8_t NsduHandle, uint8_t Radius, uint8_t DiscoverRoute, uint8_t SecurityEnable) +{ + + uint32_t srcadd[2]; + //prefixed size because the devices reset itself when there is an error in the length + uint8_t MSDU[100]; + uint32_t route_destination_address[2]; + routing_fields *routing_fields_ptr; + uint8_t next_hop_index; + + routing_fields_ptr = (routing_fields *)&MSDU[0]; + + if(joined==0) + { + signal NLDE_DATA.confirm(NsduHandle, NWK_INVALID_REQUEST); + } + else + { + routing_fields_ptr->frame_control= set_route_frame_control(0x00,0x01,DiscoverRoute,SecurityEnable); + routing_fields_ptr->destination_address=DstAddr; + routing_fields_ptr->source_address=networkaddress; + routing_fields_ptr->radius=Radius; + routing_fields_ptr->sequence_number=nwk_IB.nwkSequenceNumber; + nwk_IB.nwkSequenceNumber++; + + memcpy(&MSDU[8],&Nsdu[0],NsduLength*sizeof(uint8_t)); + + srcadd[0] = 0x00000000; + srcadd[1] = (uint32_t)networkaddress; + + if (device_type == END_DEVICE) + { + //if the device is an end device always sends the message to the parent + + route_destination_address[0]=0x00000000; + route_destination_address[1]=neighbortable[parent].Network_Address; + //ack + call MCPS_DATA.request(SHORT_ADDRESS, panid, srcadd, SHORT_ADDRESS,panid, route_destination_address, (NsduLength + 8), MSDU,1,set_txoptions(1,0,0,0)); + return SUCCESS; + } + + //send message if the device is the COORDINATOR or a ROUTER + if( (networkaddress < routing_fields_ptr->destination_address) && (routing_fields_ptr->destination_address < (networkaddress + cskip_routing ) ) ) + { + //route down to appropriate child + //check if destination is one of my children + next_hop_index = check_neighbortableentry(SHORT_ADDRESS,(uint32_t)routing_fields_ptr->destination_address,0x00000000); + + if (next_hop_index == 0) + { + //destination is not my child + route_destination_address[0]=0x00000000; + route_destination_address[1]=nexthopaddress(routing_fields_ptr->destination_address,depth); + } + else + { + //Im routing to my child + route_destination_address[0]=0x00000000; + route_destination_address[1]=neighbortable[next_hop_index-1].Network_Address; + } + //send the data //ack + call MCPS_DATA.request(SHORT_ADDRESS, panid, srcadd, SHORT_ADDRESS, panid, route_destination_address, (NsduLength + 8), MSDU,1,set_txoptions(1,0,0,0)); + } + else + { + //route up to parent + atomic{ + route_destination_address[0]=0x00000000; + route_destination_address[1]=neighbortable[parent].Network_Address; + //ack + call MCPS_DATA.request(SHORT_ADDRESS, panid, srcadd, SHORT_ADDRESS, panid, route_destination_address, (NsduLength + 8), MSDU,1,set_txoptions_upstream(1,0,0,0,1)); + } + } + + } + + return SUCCESS; +} + +/*************************************************************/ +/*******************NLME IMPLEMENTATION***********************/ +/*************************************************************/ + +/*************************************************************/ +/*******************NLME - START - ROUTER*********************/ +/*************************************************************/ + +//This primitive allows the NHL of a ZigBee Router to initialize or change its superframe configuration. +//p171 and 210 +command error_t NLME_START_ROUTER.request(uint8_t BeaconOrder, uint8_t SuperframeOrder, bool BatteryLifeExtension,uint32_t StartTime) +{ + //printfUART("NLME_START_ROUTER.request\n", ""); + + device_type = ROUTER; + + if(TYPE_DEVICE == ROUTER) + { + + //assign current BO and SO + beaconorder = BeaconOrder; + superframeorder = SuperframeOrder; + + call MLME_SET.request(MACBEACONORDER, (uint8_t *)&BeaconOrder); + + call MLME_SET.request(MACSUPERFRAMEORDER, (uint8_t *)&SuperframeOrder); + + //******************************************************* + //***********SET PAN VARIABLES*************************** + depth=DEVICE_DEPTH; + + nwk_IB.nwkAvailableAddresses=AVAILABLEADDRESSES; + nwk_IB.nwkAddressIncrement= ADDRESSINCREMENT; + + nwk_IB.nwkMaxChildren=MAXCHILDREN; //number of children a device is allowed to have on its current network + nwk_IB.nwkMaxDepth=MAXDEPTH; //the depth a device can have + nwk_IB.nwkMaxRouters=MAXROUTERS; + + cskip = Cskip(depth); + + cskip_routing = Cskip(depth -1); + + nwk_IB.nwkNextAddress = networkaddress + (cskip * nwk_IB.nwkMaxRouters) + nwk_IB.nwkAddressIncrement; + + next_child_router_address = networkaddress +((number_child_router-1) * cskip) +1; + + + number_child_router++; + + + printfUART("cskip %d\n", cskip); + printfUART("C %d D %d r %d\n", MAXCHILDREN,MAXDEPTH,MAXROUTERS); + + // command error_t request(uint32_t PANId, uint8_t LogicalChannel, uint8_t BeaconOrder, uint8_t SuperframeOrder,bool PANCoordinator,bool BatteryLifeExtension,bool CoordRealignment,bool SecurityEnable); + call MLME_START.request(panid,LOGICAL_CHANNEL,BeaconOrder, SuperframeOrder, 0, 0,0,0,StartTime); + + } + else + { + + signal NLME_START_ROUTER.confirm(NWK_INVALID_REQUEST); + + } + return SUCCESS; +} + + +/*************************************************************/ +/******************NLME - NETWORK - FORMATION*****************/ +/*************************************************************/ + +//This primitive allows the NHL to request to start a ZigBee network with itself as the coordinator +//Page 167-169 +command error_t NLME_NETWORK_FORMATION.request(uint32_t ScanChannels, uint8_t ScanDuration, uint8_t BeaconOrder, uint8_t SuperframeOrder, uint16_t PANId, bool BatteryLifeExtension) +{ + + uint8_t v_temp[6]; + + v_temp[0] = 0x06; + + device_type = COORDINATOR; + //device_type = ROUTER; + + call MLME_SET.request(MACMAXBEACONPAYLOADLENGTH,v_temp); + + //protocol ID + v_temp[0] = 0x00; + //uint8_t nwk_payload_profile_protocolversion(uint8_t stackprofile,uint8_t nwkcprotocolversion) + v_temp[1] = nwk_payload_profile_protocolversion(0x00,0x00); + //uint8_t nwk_payload_capacity(uint8_t routercapacity,uint8_t devicedepth,uint8_t enddevicecapacity) + v_temp[2] = nwk_payload_capacity(0x01,0x00,0x01); + + //TX OFFSET (3 bytes) + v_temp[3] = 0x56; + v_temp[4] = 0x34; + v_temp[5] = 0x12; + + + call MLME_SET.request(MACBEACONPAYLOAD,v_temp); + + + ////printfUART("NLME_NETWORK_FORMATION.request\n", ""); + //perform an energydetection scan + //perform an active scan + //and select a suitable channel + //panid must be less than or equal to 0x3fff + + //assign current panid + panid=PANId; + + //assign current BO and SO + beaconorder = BeaconOrder; + superframeorder = SuperframeOrder; + + call MLME_SET.request(MACBEACONORDER, (uint8_t *)&BeaconOrder); + + call MLME_SET.request(MACSUPERFRAMEORDER, (uint8_t *)&SuperframeOrder); + + v_temp[0] = (uint8_t)(PANId >> 8); + v_temp[1] = (uint8_t)PANId; + + call MLME_SET.request(MACPANID, v_temp); + + //static assignement of the coordinator address + networkaddress=0x0000;//Network address of the ZC of a network always 0x0000; + + //////printfUART("setting short addr: %i\n", networkaddress); + + v_temp[0] = (uint8_t)(networkaddress >> 8); + v_temp[1] = (uint8_t)(networkaddress); + + + call MLME_SET.request(MACSHORTADDRESS,v_temp); + + + //******************************************************* + //***********SET PAN VARIABLES*************************** + //nwk_IB.nwkNextAddress=networkaddress+0x0001; + depth=DEVICE_DEPTH; + nwk_IB.nwkAvailableAddresses=AVAILABLEADDRESSES; + nwk_IB.nwkAddressIncrement= ADDRESSINCREMENT; + + nwk_IB.nwkMaxChildren=MAXCHILDREN; //number of children a device is allowed to have on its current network + nwk_IB.nwkMaxDepth=MAXDEPTH; //the depth a device can have + nwk_IB.nwkMaxRouters=MAXROUTERS; + + cskip = Cskip(depth); + + cskip_routing = Cskip(depth -1 ); + + nwk_IB.nwkNextAddress = networkaddress + (cskip * nwk_IB.nwkMaxRouters) + nwk_IB.nwkAddressIncrement; + + next_child_router_address = networkaddress +((number_child_router-1) * cskip) +1; + + number_child_router++; + + printfUART("cskip %d\n", cskip); + printfUART("C %d D %d r %d\n", MAXCHILDREN,MAXDEPTH,MAXROUTERS); + + + call MLME_START.request(PANId, LOGICAL_CHANNEL,BeaconOrder ,SuperframeOrder,1,0,0,0,0); + + return SUCCESS; +} + +/*************************************************************/ +/***************NLME - NETWORK - DISCOVERY *******************/ +/*************************************************************/ + +//This primitive allows the next higher layer to request that the NWK layer discover networks currently operating within the POS. +//p164 and 210 +command error_t NLME_NETWORK_DISCOVERY.request(uint32_t ScanChannels, uint8_t Scanduration) +{ + + //ISSUE an MLME_SCAN.request to find the available networks + //Temporary descover of the network + //Channel Scan is not working properly + //manually assign the network descriptor + + /* + networkdescriptor networkdescriptorlist[1]; +*/ + printfUART("2 lauch passive scan\n", ""); + //The networkdescriptorlist must contain information about every network that was heard + + //make NetworkDescriptorList out of the PanDescriptorList + + call MLME_SCAN.request(PASSIVE_SCAN,0xFFFFFFFF,7); + +/* + + networkdescriptorlist[0].PANId=0x1234; + networkdescriptorlist[0].LogicalChannel=LOGICAL_CHANNEL; + networkdescriptorlist[0].StackProfile=0x00; + networkdescriptorlist[0].ZigBeeVersion=0x01; + networkdescriptorlist[0].BeaconOrder=7; + networkdescriptorlist[0].SuperframeOrder=6; + networkdescriptorlist[0].PermitJoining=1; + + //temporary assignement on the neighbout table of the suitable PAN coordinator + if (DEVICE_DEPTH == 0x01) + add_neighbortableentry(networkdescriptorlist[0].PANId,D1_PAN_EXT0,D1_PAN_EXT1,D1_PAN_SHORT,COORDINATOR,NEIGHBOR_IS_PARENT); + if (DEVICE_DEPTH == 0x02) + add_neighbortableentry(networkdescriptorlist[0].PANId,D2_PAN_EXT0,D2_PAN_EXT1,D2_PAN_SHORT,COORDINATOR,NEIGHBOR_IS_PARENT); + if (DEVICE_DEPTH == 0x03) + add_neighbortableentry(networkdescriptorlist[0].PANId,D3_PAN_EXT0,D3_PAN_EXT1,D3_PAN_SHORT,COORDINATOR,NEIGHBOR_IS_PARENT); + if (DEVICE_DEPTH == 0x04) + add_neighbortableentry(networkdescriptorlist[0].PANId,D4_PAN_EXT0,D4_PAN_EXT1,D4_PAN_SHORT,COORDINATOR,NEIGHBOR_IS_PARENT); + + + + signal NLME_NETWORK_DISCOVERY.confirm(1,networkdescriptorlist, NWK_SUCCESS); +*/ + return SUCCESS; +} + +/*************************************************************/ +/************************NLME - JOIN**************************/ +/*************************************************************/ +//This primitive allows the NHL to request to join a network either through association. +//p173 and 210 +command error_t NLME_JOIN.request(uint16_t PANId, bool JoinAsRouter, bool RejoinNetwork, uint32_t ScanChannels, uint8_t ScanDuration, uint8_t PowerSource, uint8_t RxOnWhenIdle, uint8_t MACSecurity) +{ + + //Assume we have selected a suitable parent and all previous conditions were true + uint32_t destinaddress[2]; + + printfUART("9 find parent\n", ""); + + //list_neighbourtable(); + + parent_index = find_suitable_parent(); + + panid = PANId; + + //printfUART("NLME_JOIN %i %i\n", parent_index,panid); + + if(parent_index == 0) + { + signal NLME_JOIN.confirm(PANId,NWK_NOT_PERMITTED); + } + else + { + //assign the true value to parent index + parent_index = parent_index - 1; + + //destinaddress[0]=neighbortable[parent_index].Extended_Address0; + //destinaddress[1]=neighbortable[parent_index].Extended_Address1; + //verificar o endereço do pan coordinator + destinaddress[0]=0x00000000; + + + destinaddress[1] = neighbortable[parent_index].Network_Address; + + /* + if (DEVICE_DEPTH == 0x01) + destinaddress[1]=D1_PAN_SHORT; + if (DEVICE_DEPTH == 0x02) + destinaddress[1]=D2_PAN_SHORT; + if (DEVICE_DEPTH == 0x03) + destinaddress[1]=D3_PAN_SHORT; + if (DEVICE_DEPTH == 0x04) + destinaddress[1]=D4_PAN_SHORT; + */ + + printfUART("10 associate to %i\n", destinaddress[1]); + //set_capability_information(uint8_t alternate_PAN_coordinator, uint8_t device_type, uint8_t power_source, uint8_t receiver_on_when_idle, uint8_t security, uint8_t allocate_address) + + if (JoinAsRouter == 0x01) + call MLME_ASSOCIATE.request(LOGICAL_CHANNEL,SHORT_ADDRESS,PANId,destinaddress, set_capability_information(JoinAsRouter,0x01,PowerSource,RxOnWhenIdle,MACSecurity,0x01),0); + else + { + + printfUART("11 go ass\n", ""); + + coordinator_addr[0]=0x00000000; + coordinator_addr[1] = neighbortable[parent_index].Network_Address; + //BUILD the PAN descriptor of the COORDINATOR + //assuming that the adress is short + pan_des.CoordAddrMode = SHORT_ADDRESS; + pan_des.CoordPANId = panid; + pan_des.CoordAddress0=0x00000000; + pan_des.CoordAddress1=(uint32_t)neighbortable[parent_index].Network_Address; + pan_des.LogicalChannel=neighbortable[parent_index].Logical_Channel; + //superframe specification field + //pan_des.SuperframeSpec = neighbortable[parent_index].SuperframeSpec; + + pan_des.GTSPermit=0x01; + pan_des.LinkQuality=0x00; + pan_des.TimeStamp=0x000000; + pan_des.SecurityUse=0; + pan_des.ACLEntry=0x00; + pan_des.SecurityFailure=0x00; + + received_beacon_count=0; + go_associate=1; + + //call MLME_ASSOCIATE.request(LOGICAL_CHANNEL,SHORT_ADDRESS,PANId,destinaddress, set_capability_information(JoinAsRouter,0x00,PowerSource,RxOnWhenIdle,MACSecurity,0x01),0); + } + } + + return SUCCESS; +} + + +/*************************************************************/ +/************************NLME - LEAVE*************************/ +/*************************************************************/ + +//This primitive allows the NHL to request that it or another device leaves the network +//page 181-183 +command error_t NLME_LEAVE.request(uint32_t DeviceAddress[],bool RemoveChildren, bool MACSecurityEnable) +{ + uint32_t devaddr[2]; + ////printfUART("NLME_LEAVE.request\n", ""); + if (DeviceAddress == 0)//child asked to leave + { + if(RemoveChildren == 0)//implemented like it is always 0 + { + //send leave request command frame: RemoveChildren subfield=0 of the command option field of the command frame payload + //call MCPS_DATA.request(uint8_t SrcAddrMode, uint16_t SrcPANId, uint8_t SrcAddr[], uint8_t DstAddrMode, uint16_t DestPANId, uint8_t DstAddr[], uint8_t msduLength, uint8_t msdu[],uint8_t msduHandle, uint8_t TxOptions); + devaddr[0]=neighbortable[parent].Extended_Address0; + devaddr[1]=neighbortable[parent].Extended_Address1; + call MLME_DISASSOCIATE.request(devaddr,0x02,0); + } + else + { + //send leave request command frame: RemoveChildren subfield=1 + //try to remove the children, call NLME_LEAVE.request(uint32_t DeviceAddress[]=address of child,bool RemoveChildren, bool MACSecurityEnable) + //call MCPS_DATA.request(uint8_t SrcAddrMode, uint16_t SrcPANId, uint8_t SrcAddr[], uint8_t DstAddrMode, uint16_t DestPANId, uint8_t DstAddr[], uint8_t msduLength, uint8_t msdu[],uint8_t msduHandle, uint8_t TxOptions); + } + } + else//parent forced a child to leave + { + //if(check_neighbortableentry(DeviceAddress[0], DeviceAddress[1]) == 0) + //{ + // signal NLME_LEAVE.confirm(DeviceAddress,NWK_UNKNOWN_DEVICE); + // //call MCPS_DATA.request(uint8_t SrcAddrMode, uint16_t SrcPANId, uint8_t SrcAddr[], uint8_t DstAddrMode, uint16_t DestPANId, uint8_t DstAddr[], uint8_t msduLength, uint8_t msdu[],uint8_t msduHandle, uint8_t TxOptions); + //} + + } + + + return SUCCESS; +} + +/*************************************************************/ +/************************NLME - SYNC**************************/ +/*************************************************************/ + +//This primitive allows the NHL to synchronize or extract data from its ZigBee coordinator or router +//page 186-187 +command error_t NLME_SYNC.request(bool Track) +{ + + return SUCCESS; +} + +/*************************************************************/ +/***************** NLME-SET ********************/ +/*************************************************************/ + +command error_t NLME_SET.request(uint8_t NIBAttribute, uint16_t NIBAttributeLength, uint16_t NIBAttributeValue) +{ + + atomic{ + + switch(NIBAttribute) + { + case NWKSEQUENCENUMBER : nwk_IB.nwkSequenceNumber = (uint8_t) NIBAttributeValue; + //////printfUART("nwk_IB.nwkSequenceNumber: %x\n",nwk_IB.nwkSequenceNumber); + signal NLME_SET.confirm(NWK_SUCCESS,NIBAttribute); + break; + + case NWKPASSIVEACKTIMEOUT : nwk_IB.nwkPassiveAckTimeout = (uint8_t) NIBAttributeValue; + //////printfUART("nwk_IB.nwkPassiveAckTimeout: %x\n",nwk_IB.nwkPassiveAckTimeout); + signal NLME_SET.confirm(NWK_SUCCESS,NIBAttribute); + break; + + + case NWKMAXBROADCASTRETRIES : nwk_IB.nwkMaxBroadcastRetries = (uint8_t) NIBAttributeValue; + //////printfUART("nwk_IB.nwkMaxBroadcastRetries: %x\n",nwk_IB.nwkMaxBroadcastRetries); + signal NLME_SET.confirm(NWK_SUCCESS,NIBAttribute); + break; + + case NWKMAXCHILDREN : nwk_IB.nwkMaxChildren = (uint8_t) NIBAttributeValue; + //////printfUART("nwk_IB.nwkMaxChildren: %x\n",nwk_IB.nwkMaxChildren); + signal NLME_SET.confirm(NWK_SUCCESS,NIBAttribute); + break; + + case NWKMAXDEPTH : nwk_IB.nwkMaxDepth = (uint8_t) NIBAttributeValue; + //////printfUART("nwk_IB.nwkMaxDepth: %x\n",nwk_IB.nwkMaxDepth); + signal NLME_SET.confirm(NWK_SUCCESS,NIBAttribute); + break; + + case NWKMAXROUTERS : nwk_IB.nwkMaxRouters = (uint8_t) NIBAttributeValue; + //////printfUART("nwk_IB.nwkMaxRouters: %x\n",nwk_IB.nwkMaxRouters); + signal NLME_SET.confirm(NWK_SUCCESS,NIBAttribute); + break; + + case NWKMETWORKBROADCASTDELIVERYTIME : nwk_IB.nwkNetworkBroadcastDeliveryTime = (uint8_t) NIBAttributeValue; + //////printfUART("nwk_IB.nwkNetworkBroadcastDeliveryTime: %x\n",nwk_IB.nwkNetworkBroadcastDeliveryTime); + signal NLME_SET.confirm(NWK_SUCCESS,NIBAttribute); + break; + case NWKREPORTCONSTANTCOST : nwk_IB.nwkReportConstantCost = (uint8_t) NIBAttributeValue; + //////printfUART("nwk_IB.nwkReportConstantCost: %x\n",nwk_IB.nwkReportConstantCost); + signal NLME_SET.confirm(NWK_SUCCESS,NIBAttribute); + break; + case NWKROUTEDISCOVERYRETRIESPERMITED : nwk_IB.nwkRouteDiscoveryRetriesPermitted = (uint8_t) NIBAttributeValue; + //////printfUART("nwk_IB.nwkRouteDiscoveryRetriesPermitted: %x\n",nwk_IB.nwkRouteDiscoveryRetriesPermitted); + signal NLME_SET.confirm(NWK_SUCCESS,NIBAttribute); + break; + + case NWKSYMLINK : nwk_IB.nwkSymLink = (uint8_t) NIBAttributeValue; + //////printfUART("nwk_IB.nwkSymLink: %x\n",nwk_IB.nwkSymLink); + signal NLME_SET.confirm(NWK_SUCCESS,NIBAttribute); + break; + + case NWKCAPABILITYINFORMATION : nwk_IB.nwkCapabilityInformation = (uint8_t) NIBAttributeValue; + //////printfUART("nwk_IB.nwkCapabilityInformation: %x\n",nwk_IB.nwkCapabilityInformation); + signal NLME_SET.confirm(NWK_SUCCESS,NIBAttribute); + break; + + case NWKUSETREEADDRALLOC : nwk_IB.nwkUseTreeAddrAlloc = (uint8_t) NIBAttributeValue; + //////printfUART("nwk_IB.nwkUseTreeAddrAlloc: %x\n",nwk_IB.nwkUseTreeAddrAlloc); + signal NLME_SET.confirm(NWK_SUCCESS,NIBAttribute); + break; + + case NWKUSETREEROUTING : nwk_IB.nwkUseTreeRouting = (uint8_t) NIBAttributeValue; + //////printfUART("nwk_IB.nwkUseTreeRouting: %x\n",nwk_IB.nwkUseTreeRouting); + signal NLME_SET.confirm(NWK_SUCCESS,NIBAttribute); + break; + + case NWKNEXTADDRESS : nwk_IB.nwkNextAddress = NIBAttributeValue; + //////printfUART("nwk_IB.nwkNextAddress: %x\n",nwk_IB.nwkNextAddress); + signal NLME_SET.confirm(NWK_SUCCESS,NIBAttribute); + break; + + case NWKAVAILABLEADDRESSES : nwk_IB.nwkAvailableAddresses = NIBAttributeValue; + //////printfUART("nwk_IB.nwkAvailableAddresses: %x\n",nwk_IB.nwkAvailableAddresses); + signal NLME_SET.confirm(NWK_SUCCESS,NIBAttribute); + break; + + case NWKADDRESSINCREMENT : nwk_IB.nwkAddressIncrement =NIBAttributeValue; + //////printfUART("nwk_IB.nwkAddressIncrement: %x\n",nwk_IB.nwkAddressIncrement); + signal NLME_SET.confirm(NWK_SUCCESS,NIBAttribute); + break; + + case NWKTRANSACTIONPERSISTENCETIME : nwk_IB.nwkTransactionPersistenceTime = (uint8_t) NIBAttributeValue; + //////printfUART("nwk_IB.nwkTransactionPersistenceTime: %x\n",nwk_IB.nwkTransactionPersistenceTime); + signal NLME_SET.confirm(NWK_SUCCESS,NIBAttribute); + break; + + default: signal NLME_SET.confirm(NWK_UNSUPPORTED_ATTRIBUTE,NIBAttribute); + break; + + } + + } + + + return SUCCESS; +} + +/*************************************************************/ +/***************** NLME-GET ********************/ +/*************************************************************/ + +command error_t NLME_GET.request(uint8_t NIBAttribute) +{ + switch(NIBAttribute) + { + case NWKSEQUENCENUMBER : signal NLME_GET.confirm(NWK_SUCCESS,NIBAttribute,0x0001,(uint16_t)&nwk_IB.nwkSequenceNumber); + break; + + case NWKPASSIVEACKTIMEOUT : signal NLME_GET.confirm(NWK_SUCCESS,NIBAttribute,0x0001,(uint16_t)&nwk_IB.nwkPassiveAckTimeout); + break; + + case NWKMAXBROADCASTRETRIES : signal NLME_GET.confirm(NWK_SUCCESS,NIBAttribute,0x0001,(uint16_t)&nwk_IB.nwkMaxBroadcastRetries); + break; + + case NWKMAXCHILDREN : signal NLME_GET.confirm(NWK_SUCCESS,NIBAttribute,0x0001,(uint16_t)&nwk_IB.nwkMaxChildren); + break; + + case NWKMAXDEPTH : signal NLME_GET.confirm(NWK_SUCCESS,NIBAttribute,0x0001,(uint16_t)&nwk_IB.nwkMaxDepth); + break; + + case NWKMAXROUTERS : signal NLME_GET.confirm(NWK_SUCCESS,NIBAttribute,0x0001,(uint16_t)&nwk_IB.nwkMaxRouters); + break; + + case NWKMETWORKBROADCASTDELIVERYTIME : signal NLME_GET.confirm(NWK_SUCCESS,NIBAttribute,0x0001,(uint16_t)&nwk_IB.nwkNetworkBroadcastDeliveryTime); + break; + + case NWKREPORTCONSTANTCOST : signal NLME_GET.confirm(NWK_SUCCESS,NIBAttribute,0x0001,(uint16_t)&nwk_IB.nwkReportConstantCost); + break; + + case NWKROUTEDISCOVERYRETRIESPERMITED : signal NLME_GET.confirm(NWK_SUCCESS,NIBAttribute,0x0001,(uint16_t)&nwk_IB.nwkRouteDiscoveryRetriesPermitted); + break; + + case NWKSYMLINK : signal NLME_GET.confirm(NWK_SUCCESS,NIBAttribute,0x0001,(uint16_t)&nwk_IB.nwkSymLink); + break; + + case NWKCAPABILITYINFORMATION : signal NLME_GET.confirm(NWK_SUCCESS,NIBAttribute,0x0001,(uint16_t)&nwk_IB.nwkCapabilityInformation); + break; + + case NWKUSETREEADDRALLOC : signal NLME_GET.confirm(NWK_SUCCESS,NIBAttribute,0x0001,(uint16_t)&nwk_IB.nwkUseTreeAddrAlloc); + break; + + case NWKUSETREEROUTING : signal NLME_GET.confirm(NWK_SUCCESS,NIBAttribute,0x0001,(uint16_t)&nwk_IB.nwkUseTreeRouting); + break; + + case NWKNEXTADDRESS : signal NLME_GET.confirm(NWK_SUCCESS,NIBAttribute,0x0002,(uint16_t)&nwk_IB.nwkNextAddress); + break; + + case NWKAVAILABLEADDRESSES : signal NLME_GET.confirm(NWK_SUCCESS,NIBAttribute,0x0002,(uint16_t)&nwk_IB.nwkAvailableAddresses); + break; + + case NWKADDRESSINCREMENT : signal NLME_GET.confirm(NWK_SUCCESS,NIBAttribute,0x0002,(uint16_t)&nwk_IB.nwkAddressIncrement); + break; + + case NWKTRANSACTIONPERSISTENCETIME : signal NLME_GET.confirm(NWK_SUCCESS,NIBAttribute,0x0001,(uint16_t)&nwk_IB.nwkTransactionPersistenceTime); + break; + + default: signal NLME_GET.confirm(NWK_UNSUPPORTED_ATTRIBUTE,NIBAttribute,0x0000,0x00); + break; + } + + return SUCCESS; +} + +/*************************************************************/ +/**************neighbor table management functions************/ +/*************************************************************/ + +//check if a specific neighbourtable Entry is present +//Return 0:Entry is not present +//Return i:Entry is present and return the index of the entry + 1 + uint8_t check_neighbortableentry(uint8_t addrmode,uint32_t Address0,uint32_t Address1) + { + + int i=0; + + + //printfUART("neighbourtable check c %i\n", neighbour_count); + + if (neighbour_count == 0) + { + //printfUART("no neib\n", ""); + return 0; + } + + if(addrmode == SHORT_ADDRESS) + { + for(i=0; i < neighbour_count; i++) + { + ///printfUART("compare %i %i\n", neighbortable[i].Network_Address, test); + + if(neighbortable[i].Network_Address == (uint16_t) Address0) + { + //printfUART("already present \n", "" ); + return i+1; + } + } + return 0; + } + else + { + for(i=0; i PhyM; + + + SplitControl = PhyM; + + //Test_send = PhyM; + + components CC2420ControlC; + PhyM.Resource -> CC2420ControlC; + PhyM.CC2420Power -> CC2420ControlC; + PhyM.CC2420Config ->CC2420ControlC; + + components CC2420TransmitC; + PhyM.SubControl -> CC2420TransmitC; + + PhyM.Sendframe ->CC2420TransmitC; + + components CC2420ReceiveC; + + //Receive = CC2420ReceiveC; + + + PhyM.SubControl -> CC2420ReceiveC; + + + PhyM.Receiveframe ->CC2420ReceiveC; + + + components RandomC; + PhyM.Random -> RandomC; + + components LedsC as Leds; + PhyM.Leds -> Leds; + + + PD_DATA=PhyM; + + PLME_ED=PhyM; + PLME_CCA=PhyM; + PLME_GET = PhyM; + PLME_SET=PhyM; + PLME_SET_TRX_STATE=PhyM; +} diff --git a/tos/lib/net/zigbee/ieee802154/phy/PhyM.nc b/tos/lib/net/zigbee/ieee802154/phy/PhyM.nc new file mode 100644 index 00000000..457f176c --- /dev/null +++ b/tos/lib/net/zigbee/ieee802154/phy/PhyM.nc @@ -0,0 +1,345 @@ +/* + * @author IPP HURRAY http://www.hurray.isep.ipp.pt/art-wise + * @author Andre Cunha + * + */ + +#include "frame_format.h" + +#include "phy_const.h" +#include "phy_enumerations.h" + + +module PhyM { + + provides interface SplitControl; + // provides interface Test_send; + + + //ieee802.15.4 phy interfaces + provides interface PD_DATA; + + provides interface PLME_ED; + provides interface PLME_CCA; + provides interface PLME_SET; + provides interface PLME_GET; + provides interface PLME_SET_TRX_STATE; + + + provides interface Init; + + uses interface Resource; + uses interface CC2420Power; + uses interface CC2420Config; + uses interface StdControl as SubControl; + + uses interface Random; + uses interface Leds; + + uses interface Sendframe; + + uses interface Receiveframe; + +} + +implementation { + + + phyPIB phy_PIB; + + //transceiver current status + //it can only be PHY_TRX_OFF, PHY_RX_ON and PHY_TX_ON + uint8_t currentRxTxState = PHY_TRX_OFF; + + //message received + //norace MPDU rxmpdu; + MPDU *rxmpdu_ptr; + + + error_t sendErr = SUCCESS; + + + + /** TRUE if we are to use CCA when sending the current packet */ + norace bool ccaOn; + + /****************** Prototypes ****************/ + task void startDone_task(); + task void startDone_task(); + task void stopDone_task(); + task void sendDone_task(); + + void shutdown(); + + + +/***************** Init Commands ****************/ + command error_t Init.init() { + + //atomic rxmpdu_ptr = &rxmpdu; + + //TODO + /* + //PHY PIB initialization + //phy_PIB.phyCurrentChannel=INIT_CURRENTCHANNEL; + phy_PIB.phyCurrentChannel=LOGICAL_CHANNEL; + phy_PIB.phyChannelsSupported=INIT_CHANNELSSUPPORTED; + phy_PIB.phyTransmitPower=INIT_TRANSMITPOWER; + phy_PIB.phyCcaMode=INIT_CCA_MODE; + */ + + return SUCCESS; + } + + + /***************** SplitControl Commands ****************/ + command error_t SplitControl.start() { + + //arrancar o controlo + + call CC2420Power.startVReg(); + + + return SUCCESS; + + + } + + command error_t SplitControl.stop() { + + return EBUSY; + } + + /***************** Send Commands ****************/ + + + async event void Sendframe.sendDone(error_t error ) + { + + atomic sendErr = error; + post sendDone_task(); + + } + + + + + /**************** Events ****************/ + async event void CC2420Power.startVRegDone() { + call Resource.request(); + + } + + event void Resource.granted() { + call CC2420Power.startOscillator(); + } + + async event void CC2420Power.startOscillatorDone() { + post startDone_task(); + } + + + + /***************** Tasks ****************/ + task void sendDone_task() { + error_t packetErr; + atomic packetErr = sendErr; + + // signal Send.sendDone( m_msg, packetErr ); + } + + task void startDone_task() { + call SubControl.start(); + call CC2420Power.rxOn(); + call Resource.release(); + + signal SplitControl.startDone( SUCCESS ); + } + + task void stopDone_task() { + + signal SplitControl.stopDone( SUCCESS ); + } + + + /***************** Functions ****************/ + /** + * Shut down all sub-components and turn off the radio + */ + void shutdown() { + call SubControl.stop(); + call CC2420Power.stopVReg(); + post stopDone_task(); + } + + /***************** Defaults ***************/ + default event void SplitControl.startDone(error_t error) { + } + + default event void SplitControl.stopDone(error_t error) { + } + + + + async event void Receiveframe.receive(uint8_t* frame, uint8_t rssi) + { + + rxmpdu_ptr=(MPDU*)frame; + + signal PD_DATA.indication(rxmpdu_ptr->length,(uint8_t*)rxmpdu_ptr, rssi); + /* + printfUART("n %i\n", TOS_NODE_ID); + + printfUART("l %i\n", rxmpdu_ptr->length); + printfUART("fc1 %i\n", rxmpdu_ptr->frame_control1); + printfUART("fc2 %i\n", rxmpdu_ptr->frame_control2); + printfUART("seq %i\n", rxmpdu_ptr->seq_num); + + for (i=0;i<120;i++) + { + printfUART("d %i %x\n",i, rxmpdu_ptr->data[i]); + + } + */ + + + } + + + + event void CC2420Config.syncDone( error_t error ) + { + + + + return; + } + + +/*****************************************************************************************************/ +/**************************************PD-DATA********************************************************/ +/*****************************************************************************************************/ + + +async command error_t PD_DATA.request(uint8_t psduLength, uint8_t* psdu) { + + + call Sendframe.send(psdu,psduLength); + + + return SUCCESS; +} + + +/*****************************************************************************************************/ +/********************************************PLME-ED**************************************************/ +/*****************************************************************************************************/ + +command error_t PLME_ED.request(){ + //MAC asking for energy detection + //TODO + + return SUCCESS; +} + +/*****************************************************************************************************/ +/********************************************PLME-CCA*************************************************/ +/*****************************************************************************************************/ + +command error_t PLME_CCA.request(){ +//MAC asking for CCA +//TODO + + + return SUCCESS; +} + +/*****************************************************************************************************/ +/********************************************PLME-GET*************************************************/ +/*****************************************************************************************************/ + +command error_t PLME_GET.request(uint8_t PIBAttribute){ +//MAC asking for PIBAttribute value + switch(PIBAttribute) + { + case PHYCURRENTCHANNEL: + signal PLME_GET.confirm(PHY_SUCCESS, PIBAttribute, phy_PIB.phyCurrentChannel); + break; + + case PHYCHANNELSSUPPORTED: + signal PLME_GET.confirm(PHY_SUCCESS, PIBAttribute, phy_PIB.phyChannelsSupported); + break; + + case PHYTRANSMITPOWER: + signal PLME_GET.confirm(PHY_SUCCESS, PIBAttribute, phy_PIB.phyTransmitPower); + break; + case PHYCCAMODE: + signal PLME_GET.confirm(PHY_SUCCESS, PIBAttribute, phy_PIB.phyCcaMode); + break; + default: + signal PLME_GET.confirm(PHY_UNSUPPORTED_ATTRIBUTE, PIBAttribute, 0x00); + break; + } + + + return SUCCESS; + } + +/*****************************************************************************************************/ +/********************************************PLME-SET*************************************************/ +/*****************************************************************************************************/ +command error_t PLME_SET.request(uint8_t PIBAttribute, uint8_t PIBAttributeValue){ + + + //MAC is demanding for PHY to write the indicated PIB value + switch(PIBAttribute) + { + case PHYCURRENTCHANNEL: + + phy_PIB.phyCurrentChannel = PIBAttributeValue; + + call CC2420Config.setChannel(phy_PIB.phyCurrentChannel); + + call CC2420Config.sync(); + + //TunePreset(phy_PIB.phyCurrentChannel); + signal PLME_SET.confirm(PHY_SUCCESS, PIBAttribute); + break; + + case PHYCHANNELSSUPPORTED: + phy_PIB.phyChannelsSupported = PIBAttributeValue; + signal PLME_SET.confirm(PHY_SUCCESS, PIBAttribute); + break; + + case PHYTRANSMITPOWER: + phy_PIB.phyTransmitPower= PIBAttributeValue; + //SetRFPower(phy_PIB.phyTransmitPower); + signal PLME_SET.confirm(PHY_SUCCESS, PIBAttribute); + break; + case PHYCCAMODE: + phy_PIB.phyCcaMode= PIBAttributeValue; + signal PLME_SET.confirm(PHY_SUCCESS, PIBAttribute); + break; + default: + signal PLME_SET.confirm(PHY_UNSUPPORTED_ATTRIBUTE, PIBAttribute); + break; + } + return SUCCESS; +} + +/*****************************************************************************************************/ +/**********************************PLME_SET_TRX_STATE*************************************************/ +/*****************************************************************************************************/ + + +async command error_t PLME_SET_TRX_STATE.request(uint8_t state){ + + +return SUCCESS; + +} + + + +} + diff --git a/tos/lib/net/zigbee/ieee802154/phy/phy_const.h b/tos/lib/net/zigbee/ieee802154/phy/phy_const.h new file mode 100644 index 00000000..8ac3ced6 --- /dev/null +++ b/tos/lib/net/zigbee/ieee802154/phy/phy_const.h @@ -0,0 +1,32 @@ +/* + * @author IPP HURRAY http://www.hurray.isep.ipp.pt/art-wise + * @author Andre Cunha + */ + + +#ifndef __PHY_CONST__ +#define __PHY_CONST__ + +// The PHY constants are defined here. +#define aMaxPHYPacketSize 127 +#define aTurnaroundTime 12 + +#define INIT_CURRENTCHANNEL 0x15 +#define INIT_CHANNELSSUPPORTED 0x0 +#define INIT_TRANSMITPOWER 15 +#define INIT_CCA_MODE 0 + +#define CCA_IDLE 0 +#define CCA_BUSY 1 + +// PHY PIB attribute and psdu +typedef struct +{ + uint8_t phyCurrentChannel; + uint8_t phyChannelsSupported; + uint8_t phyTransmitPower; + uint8_t phyCcaMode; +} phyPIB; + +#endif + diff --git a/tos/lib/net/zigbee/ieee802154/phy/phy_enumerations.h b/tos/lib/net/zigbee/ieee802154/phy/phy_enumerations.h new file mode 100644 index 00000000..9059bf37 --- /dev/null +++ b/tos/lib/net/zigbee/ieee802154/phy/phy_enumerations.h @@ -0,0 +1,33 @@ +/* + * @author IPP HURRAY http://www.hurray.isep.ipp.pt/art-wise + * @author Andre Cunha + */ + +#ifndef __PHY_ENUMERATIONS__ +#define __PHY_ENUMERATIONS__ + + +//phy status enumerations +enum{ + PHY_BUSY = 0x00, + PHY_BUSY_RX = 0x01, + PHY_BUSY_TX = 0x02, + PHY_FORCE_TRX_OFF = 0x03, + PHY_IDLE = 0x04, + PHY_INVALID_PARAMETER = 0x05, + PHY_RX_ON = 0x06, + PHY_SUCCESS = 0x07, + PHY_TRX_OFF = 0x08, + PHY_TX_ON = 0x09, + PHY_UNSUPPORTED_ATTRIBUTE = 0x0a +}; + +//phy PIB attributes enumerations +enum{ + PHYCURRENTCHANNEL = 0x00, + PHYCHANNELSSUPPORTED = 0X01, + PHYTRANSMITPOWER = 0X02, + PHYCCAMODE=0X03 +}; + +#endif diff --git a/tos/lib/net/zigbee/ieee802154/timerasync/TimerAsync.nc b/tos/lib/net/zigbee/ieee802154/timerasync/TimerAsync.nc new file mode 100644 index 00000000..7fc36b9f --- /dev/null +++ b/tos/lib/net/zigbee/ieee802154/timerasync/TimerAsync.nc @@ -0,0 +1,74 @@ +/* + * @author IPP HURRAY http://www.hurray.isep.ipp.pt/art-wise + * @author Andre Cunha + * + */ + + interface TimerAsync + { + + async command error_t start(); + + async command error_t stop(); + + async command error_t reset(); + + /***********************************FIRED EVENTS COMMANDS******************************/ + //time before BI + async event error_t before_bi_fired(); + + async event error_t sd_fired(); + + async event error_t bi_fired(); + + //backoff fired + async event error_t backoff_fired(); + + //backoff boundary fired + async event error_t time_slot_fired(); + + async event error_t before_time_slot_fired(); + + async event error_t sfd_fired(); + + /***********************************INIT/RESET COMMANDS******************************/ + + async command error_t set_bi_sd(uint32_t bi_symbols,uint32_t sd_symbols); + + async command error_t set_backoff_symbols(uint8_t symbols); + + async command error_t set_enable_backoffs(bool enable_backoffs); + + async command uint8_t reset_start(uint32_t start_ticks); + + async command error_t reset_process_frame_tick_counter(); + + /*****************************************************************************/ + + async command error_t set_timers_enable(uint8_t timer); + + /***********************************GET COMMANDS******************************/ + async command uint32_t get_total_tick_counter(); + + async command uint32_t get_current_number_backoff(); + + async command uint32_t get_time_slot_backoff_periods(); + + async command uint32_t get_current_time_slot(); + + async command uint32_t get_current_number_backoff_on_time_slot(); + + async command uint32_t get_process_frame_tick_counter(); + + async command uint32_t get_time_slot_ticks(); + + async command uint32_t get_current_ticks(); + + async command uint32_t get_sd_ticks(); + + async command uint32_t get_bi_ticks(); + + async command uint32_t get_backoff_ticks(); + + } + diff --git a/tos/lib/net/zigbee/ieee802154/timerasync/TimerAsyncC.nc b/tos/lib/net/zigbee/ieee802154/timerasync/TimerAsyncC.nc new file mode 100644 index 00000000..32490333 --- /dev/null +++ b/tos/lib/net/zigbee/ieee802154/timerasync/TimerAsyncC.nc @@ -0,0 +1,30 @@ +/* + * @author IPP HURRAY http://www.hurray.isep.ipp.pt/art-wise + * @author Andre Cunha + * + */ + + //TIMER ASYNC TELOSB + + +configuration TimerAsyncC +{ + //provides interface StdControl; + provides interface TimerAsync; +} +implementation +{ + + components LedsC; + components TimerAsyncM; + + components new Alarm32khz32C() as Alarm; + + //StdControl = TimerAsyncM; + TimerAsync = TimerAsyncM; + + TimerAsyncM.Leds -> LedsC; + + TimerAsyncM.AsyncTimer -> Alarm; + +} diff --git a/tos/lib/net/zigbee/ieee802154/timerasync/TimerAsyncM.nc b/tos/lib/net/zigbee/ieee802154/timerasync/TimerAsyncM.nc new file mode 100644 index 00000000..44f23194 --- /dev/null +++ b/tos/lib/net/zigbee/ieee802154/timerasync/TimerAsyncM.nc @@ -0,0 +1,364 @@ +/* + * @author IPP HURRAY http://www.hurray.isep.ipp.pt/art-wise + * @author Andre Cunha + * + */ + +#define BEFORE_BI_INTERVAL 100 +#define BEFORE_BB_INTERVAL 5 + +#define SO_EQUAL_BO_DIFFERENCE 2 + +//#define SYMBOL_DIVISION 4 + +//temporary +#define NUMBER_TIME_SLOTS 16 + +module TimerAsyncM { + + provides interface TimerAsync; + + uses interface Leds; + + uses interface Alarm as AsyncTimer; + + + + +} +implementation +{ + +uint32_t ticks_counter; + +//BEACON INTERVAL VARIABLES +uint32_t bi_ticks; +uint32_t bi_backoff_periods; +uint32_t before_bi_ticks; +uint32_t sd_ticks; + +//number of backoff periods +uint32_t time_slot_backoff_periods; + +//number of ticks in the timeslot +uint32_t time_slot_ticks; +uint32_t before_time_slot_ticks; +uint32_t time_slot_tick_next_fire; + +//BACKOFF VARIABLES +uint32_t backoff_symbols; + +//number of ticks in the backoff +uint32_t backoff_ticks = 5; + +//COUNTER VARIABLES +uint32_t backoff_ticks_counter=0; + +//give the current time slot number +uint8_t current_time_slot=0; +//counts the current number of time slots of each time slot +uint32_t current_number_backoff_on_time_slot=0; +//count the total number of backoffs +uint32_t current_number_backoff = 0; + +//OTHER +bool backoffs=0; +bool enable_backoffs=0; + +uint8_t previous_sfd=0; +uint8_t current_sfd = 0; + +uint32_t process_frame_tick_counter=0; + +uint32_t total_tick_counter=0; + +uint8_t timers_enable=0x01; + + +async command error_t TimerAsync.start() +{ + +call AsyncTimer.start(10); + +return SUCCESS; + +} + +async command error_t TimerAsync.stop() +{ + +return SUCCESS; + +} + +/*RESET the tick counter, */ +async command error_t TimerAsync.reset() +{ + atomic ticks_counter = 0; + call AsyncTimer.start(10); + return SUCCESS; +} + +async command error_t TimerAsync.set_bi_sd(uint32_t bi_symbols,uint32_t sd_symbols) +{ + +atomic{ + time_slot_backoff_periods = (sd_symbols / NUMBER_TIME_SLOTS) / backoff_symbols; + time_slot_ticks = time_slot_backoff_periods * backoff_ticks; + time_slot_tick_next_fire = time_slot_ticks; + before_time_slot_ticks = time_slot_ticks - BEFORE_BB_INTERVAL; + sd_ticks = time_slot_ticks * NUMBER_TIME_SLOTS; + + if (bi_symbols == sd_symbols ) + { + //in order not to have the same time for both BI and SI + sd_ticks = sd_ticks - SO_EQUAL_BO_DIFFERENCE; + } + + bi_backoff_periods = bi_symbols/ backoff_symbols; + bi_ticks = bi_backoff_periods * backoff_ticks; + + before_bi_ticks = bi_ticks - BEFORE_BI_INTERVAL; + + /* + printfUART("bi_ticks %i\n", bi_ticks); + printfUART("sd_ticks %i\n", sd_ticks); + printfUART("time_slot_ticks %i\n", time_slot_ticks); + */ + } +return SUCCESS; +} + + +async command error_t TimerAsync.set_backoff_symbols(uint8_t Backoff_Duration_Symbols) +{ + + atomic + { + backoff_symbols = Backoff_Duration_Symbols; + backoff_ticks = 1; + } + + return SUCCESS; +} + + +async command error_t TimerAsync.set_enable_backoffs(bool enable) +{ + atomic enable_backoffs = enable; + return SUCCESS; +} + + + +async event void AsyncTimer.fired() { + +atomic{ + + if(timers_enable==0x01) + { + + ticks_counter++; + process_frame_tick_counter++; + + total_tick_counter++; + + if (ticks_counter == before_bi_ticks) + { + signal TimerAsync.before_bi_fired(); + } + + if (ticks_counter == bi_ticks) + { + //printfUART("bi%d\n", ticks_counter); + ticks_counter = 0; + current_time_slot=0; + backoff_ticks_counter=0; + time_slot_tick_next_fire=time_slot_ticks; + backoffs=1; + enable_backoffs = 1; + current_number_backoff =0; + signal TimerAsync.bi_fired(); + } + + if(ticks_counter == sd_ticks) + { + backoffs=0; + signal TimerAsync.sd_fired(); + } + + if ((enable_backoffs == 1) && (backoffs == 1)) + { + backoff_ticks_counter++; + + if (backoff_ticks_counter == backoff_ticks) + { + + backoff_ticks_counter=0; + current_number_backoff ++; + current_number_backoff_on_time_slot++; + signal TimerAsync.backoff_fired(); + } + + //before time slot boundary + if(ticks_counter == before_time_slot_ticks) + { + signal TimerAsync.before_time_slot_fired(); + } + + //time slot fired + if (ticks_counter == time_slot_tick_next_fire) + { + time_slot_tick_next_fire = time_slot_tick_next_fire + time_slot_ticks; + before_time_slot_ticks = time_slot_tick_next_fire - BEFORE_BB_INTERVAL; + backoff_ticks_counter=0; + current_number_backoff_on_time_slot=0; + current_time_slot++; + + if ((current_time_slot > 0) && (current_time_slot < 16) ) + signal TimerAsync.time_slot_fired(); + + + + } + } + } + + call AsyncTimer.start(10); + + } +} + + +async command error_t TimerAsync.set_timers_enable(uint8_t timer) +{ + + atomic timers_enable = timer; + //printfUART("te%i\n", timers_enable); + + +return SUCCESS; +} + +async command error_t TimerAsync.reset_process_frame_tick_counter() +{ +atomic process_frame_tick_counter=0; + +return SUCCESS; +} + + + +/*RESET the tick counter, to the start ticks */ + +async command uint8_t TimerAsync.reset_start(uint32_t start_ticks) +{ + //ticks_counter =0; + //ticks_counter = start_ticks; + + current_time_slot = start_ticks / time_slot_ticks; + + if (current_time_slot == 0) + { + time_slot_tick_next_fire= time_slot_ticks; + current_number_backoff = start_ticks / backoff_ticks; + current_number_backoff_on_time_slot = current_number_backoff; + } + else + { + time_slot_tick_next_fire= ((current_time_slot+1) * time_slot_ticks); + current_number_backoff = start_ticks / backoff_ticks; + current_number_backoff_on_time_slot = current_number_backoff - (current_time_slot * time_slot_backoff_periods); + } + + backoff_ticks_counter=0; + backoffs=1; + //on_sync = 1; + + total_tick_counter = total_tick_counter + start_ticks; + ticks_counter = start_ticks; + +/* + printfUART("bi_ticks %i\n", bi_ticks); + printfUART("sd_ticks %i\n", sd_ticks); + printfUART("time_slot_ticks %i\n", time_slot_ticks); + printfUART("total_tick_counter %i\n", total_tick_counter); + printfUART("ticks_counter %i\n", ticks_counter); + printfUART("current_time_slot %i\n", current_time_slot); +*/ + + + + return current_time_slot; + + } + +/***********************************SET COMMANDS******************************/ + +/***********************************GET COMMANDS******************************/ +/*get current clock ticks*/ + +async command uint32_t TimerAsync.get_current_ticks() +{ + return ticks_counter; +} +/*get current sd ticks*/ +async command uint32_t TimerAsync.get_sd_ticks() +{ + return time_slot_ticks * NUMBER_TIME_SLOTS; +} +/*get current clock ticks*/ +async command uint32_t TimerAsync.get_bi_ticks() +{ + return bi_ticks; +} +/*get current backoff ticks*/ +async command uint32_t TimerAsync.get_backoff_ticks() +{ + return backoff_ticks; +} +/*get current time slot ticks*/ +async command uint32_t TimerAsync.get_time_slot_ticks() +{ + return time_slot_ticks; +} + +/*get current backoff ticks*/ +async command uint32_t TimerAsync.get_current_number_backoff() +{ +return current_number_backoff; +} + +async command uint32_t TimerAsync.get_time_slot_backoff_periods() +{ +return time_slot_backoff_periods; +} + +async command uint32_t TimerAsync.get_current_time_slot() +{ +return current_time_slot; +} + + +async command uint32_t TimerAsync.get_current_number_backoff_on_time_slot() +{ + +return current_number_backoff_on_time_slot; + +} + +async command uint32_t TimerAsync.get_total_tick_counter() +{ +return total_tick_counter; +} +async command uint32_t TimerAsync.get_process_frame_tick_counter() +{ + //printfUART("%d\n", process_frame_tick_counter); + +return process_frame_tick_counter; +} + + + + +}