--- /dev/null
+/*
+ * @author IPP HURRAY http://www.hurray.isep.ipp.pt/art-wise
+ * @author Andre Cunha
+ *
+ */
+#include <Timer.h>
+
+#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;
+
+
+}
--- /dev/null
+/*
+ * @author IPP HURRAY http://www.hurray.isep.ipp.pt/art-wise
+ * @author Andre Cunha
+ *
+ */
+#include <Timer.h>
+#include "printfUART.h"
+
+module AssociationExampleM {
+
+ uses interface Boot;
+ uses interface Leds;
+
+ uses interface Timer<TMilli> as Timer0;
+
+ uses interface Timer<TMilli> 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<ResultListSize;i++)
+ {
+ printfUART("ED SCAN %i %i\n", (0x0A + i),EnergyDetectList[i]);
+ }
+ return SUCCESS;
+ }
+
+ for (i=0; i<ResultListSize;i++)
+ { /*
+ printfUART("cord id %i", PANDescriptorList[i].CoordPANId);
+ printfUART("CoordAddress %i", PANDescriptorList[i].CoordAddress);
+ printfUART("LogicalChannel %i", PANDescriptorList[i].LogicalChannel);
+ printfUART("SuperframeSpec %i", PANDescriptorList[i].SuperframeSpec);
+ printfUART("lqi %i\n", PANDescriptorList[i].lqi);
+ */
+ if(max_lqi < PANDescriptorList[i].lqi)
+ {
+ max_lqi =PANDescriptorList[i].lqi;
+ best_pan_index = i;
+ }
+ }
+
+ printfUART("SELECTED cord id %i", PANDescriptorList[best_pan_index].CoordPANId);
+ printfUART("CoordAddress %i", PANDescriptorList[best_pan_index].CoordAddress);
+ printfUART("LogicalChannel %i", PANDescriptorList[best_pan_index].LogicalChannel);
+ printfUART("SuperframeSpec %i", PANDescriptorList[best_pan_index].SuperframeSpec);
+ printfUART("lqi %i\n", PANDescriptorList[best_pan_index].lqi);
+
+ coordinator_addr[0] = 0x00000001;
+
+ coordinator_addr[1] = (uint32_t)PANDescriptorList[best_pan_index].CoordAddress;
+
+ //pan_des = PANDescriptorList[best_pan_index];
+
+
+ //BUILD the PAN descriptor of the COORDINATOR
+ //assuming that the adress is short
+ pan_des.CoordAddrMode = SHORT_ADDRESS;
+ pan_des.CoordPANId = PANDescriptorList[best_pan_index].CoordAddress;
+ pan_des.CoordAddress0=0x00000000;
+ pan_des.CoordAddress1=0x00000000;
+ pan_des.LogicalChannel=PANDescriptorList[best_pan_index].LogicalChannel;
+ //superframe specification field
+ pan_des.SuperframeSpec = PANDescriptorList[best_pan_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;
+ //enables the TimerAsync events, in order to enable the synchronization with the PAN coordinator
+ call MLME_SYNC.request(PANDescriptorList[best_pan_index].LogicalChannel,0);
+
+
+
+ return SUCCESS;
+}
+
+/*****************************************************************************************************/
+/**************************************MLME-ORPHAN****************************************************/
+/*****************************************************************************************************/
+event error_t MLME_ORPHAN.indication(uint32_t OrphanAddress[1], uint8_t SecurityUse, uint8_t ACLEntry)
+{
+
+ uint16_t assigned_address;
+
+ assigned_address = search_associated_devices(OrphanAddress[0],OrphanAddress[1]);
+
+ if (assigned_address == 0x0000)
+ {
+ printfUART("not my child\n","");
+ }
+ else
+ {
+ //printfUART("my child\n","");
+ call MLME_ORPHAN.response(OrphanAddress,assigned_address,0x01, 0x00);
+ }
+
+ return SUCCESS;
+}
+
+ uint16_t search_associated_devices(uint32_t ext1, uint32_t ext2)
+ {
+ int i;
+
+ for(i=0;i<4;i++)
+ {
+ //printfUART("ad %i %i %i\n",associated_devices[i].extended1,associated_devices[i].extended2,associated_devices[i].assigned_short);
+ if(associated_devices[i].extended1 == ext1 && associated_devices[i].extended2 == ext2 )
+ {
+
+ return associated_devices[i].assigned_short;
+ }
+
+ }
+
+ return 0x0000;
+ }
+
+/*****************************************************************************************************/
+/**************************************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)
+{
+ printfUART("SL\n","");
+
+ call MLME_SCAN.request(ORPHAN_SCAN,0xFFFFFFFF,7);
+
+
+ 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[])
+{
+
+ if (go_associate==1)
+ {
+ received_beacon_count++;
+
+ printfUART("bn %i\n", received_beacon_count);
+
+ if (received_beacon_count==5)
+ {
+ printfUART("sa \n", "");
+ go_associate=0;
+ call MLME_ASSOCIATE.request(pan_des.LogicalChannel,SHORT_ADDRESS,pan_des.CoordPANId,coordinator_addr,0x00,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)
+{
+ //the coordinator device receives the association request and assigns the device with a short address
+ address_poll ++;
+ number_associations++;
+
+ printfUART("address pool: %i %i\n", address_poll,number_associations);
+
+ call MLME_ASSOCIATE.response(DeviceAddress,address_poll, CMD_RESP_ASSOCIATION_SUCCESSFUL, 0);
+ return SUCCESS;
+}
+
+event error_t MLME_ASSOCIATE.confirm(uint16_t AssocShortAddress, uint8_t status)
+{
+
+//the end device receives the association confirm and activates the data frame send timer
+ uint8_t v_temp[2];
+
+ printfUART("MLME_ASSOCIATE.confirm\n", "");
+
+ printfUART("Short: %x\n", AssocShortAddress);
+ printfUART("Status: %i\n", status);
+
+ if (AssocShortAddress == 0x0000)
+ {
+ //call Timer0.startOneShot(8000);
+
+ }
+ else
+ {
+
+ my_short_address = AssocShortAddress;
+
+ v_temp[0] = (my_short_address >> 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;
+}
+
+}
+
--- /dev/null
+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)
+
--- /dev/null
+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;
+
+
--- /dev/null
+/**
+ * @author IPP HURRAY http://www.hurray.isep.ipp.pt/art-wise
+ * @author Andre Cunha
+ */
+#include <Timer.h>
+
+#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;
+
+
+}
+
--- /dev/null
+/*
+ *
+ * @author IPP HURRAY http://www.hurray.isep.ipp.pt/art-wise
+ * @author Andre Cunha
+ *
+ */
+
+#include <Timer.h>
+#include "printfUART.h"
+
+module DataSendExampleM {
+
+ uses interface Boot;
+ uses interface Leds;
+
+ uses interface Timer<TMilli> as Timer0;
+
+ uses interface Timer<TMilli> 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;
+}
+
+
+}
+
--- /dev/null
+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)
--- /dev/null
+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
+
+
--- /dev/null
+/**
+ * @author IPP HURRAY http://www.hurray.isep.ipp.pt/art-wise
+ * @author Andre Cunha
+ */
+#include <Timer.h>
+
+#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;
+
+
+}
+
--- /dev/null
+/*
+ *
+ * @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 <Timer.h>
+#include "printfUART.h"
+
+module GTSManagementExampleM {
+
+ uses interface Boot;
+ uses interface Leds;
+
+ uses interface Timer<TMilli> as Timer0;
+
+ uses interface Timer<TMilli> 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;
+}
+
+
+}
+
--- /dev/null
+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
--- /dev/null
+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
+
--- /dev/null
+#-*-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
--- /dev/null
+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
--- /dev/null
+/**
+ * @author IPP HURRAY http://www.hurray.isep.ipp.pt/art-wise
+ * @author Andre Cunha
+ */
+#include <Timer.h>
+
+#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;
+
+
+}
+
--- /dev/null
+/*
+ *
+ * @author IPP HURRAY http://www.hurray.isep.ipp.pt/art-wise
+ * @author Andre Cunha
+ *
+ */
+
+#include <Timer.h>
+#include "printfUART.h"
+
+module SimpleRoutingExampleM {
+
+ uses interface Boot;
+ uses interface Leds;
+
+ uses interface Timer<TMilli> as Timer0;
+
+ uses interface Timer<TMilli> 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;
+}
+
+
+}
+
--- /dev/null
+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
+
+
--- /dev/null
+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)
+
--- /dev/null
+/*
+ * @author IPP HURRAY http://www.hurray.isep.ipp.pt/art-wise
+ * @author Andre Cunha
+ *
+ */
+#include <Timer.h>
+
+#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;
+}
+
--- /dev/null
+/*
+ * @author IPP HURRAY http://www.hurray.isep.ipp.pt/art-wise
+ * @author Andre Cunha
+ *
+ */
+#include <Timer.h>
+#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<TMilli> as T_init;
+
+ uses interface Timer<TMilli> as T_test;
+
+ uses interface Timer<TMilli> as T_schedule;
+
+//user button
+ uses interface Get<button_state_t>;
+ uses interface Notify<button_state_t>;
+
+}
+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);
+
+ }
+
+}
+
+
+
+}
+
--- /dev/null
+/*
+ * 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!
+ * <p>
+ * 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: <code>PRINTFUART_ENABLED</code>.
+
+ * <p> <pre>
+ * 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);
+ * </pre>
+ * <pre>URL: http://www.eecs.harvard.edu/~konrad/projects/motetrack</pre>
+ * @author Konrad Lorincz
+ * @version 2.0, January 5, 2005
+ */
+#ifndef PRINTFUART_H
+#define PRINTFUART_H
+#include <stdarg.h>
+//#include <stdio.h>
+
+// 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 <code>exit(1)</code>
+ * 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<<U2X),UCSR0A); // Set UART double speed
+ outp(((1 << UCSZ1) | (1 << UCSZ0)) , UCSR0C); // Set frame format: 8 data-bits, 1 stop-bit
+ inp(UDR0);
+ outp((1 << TXEN) ,UCSR0B); // Enable uart reciever and transmitter
+
+ #else
+ #if defined(PLATFORM_MICA2DOT)
+ // 19.2K baud
+ outp(0,UBRR0H); // Set baudrate to 19.2 KBps
+ outp(12, UBRR0L);
+ outp(0,UCSR0A); // Disable U2X and MPCM
+ outp(((1 << UCSZ1) | (1 << UCSZ0)) , UCSR0C);
+ inp(UDR0);
+ outp((1 << TXEN) ,UCSR0B);
+
+ #else // assume TelosA, TelosB, etc.
+ //9.6K baud
+ uint16_t l_br = 0;
+ uint8_t l_mctl = 0;
+ uint8_t l_ssel = 0;
+
+
+ TOSH_SEL_UTXD1_MODFUNC();
+ TOSH_SEL_URXD1_MODFUNC();
+
+
+ UCTL1 = SWRST;
+ UCTL1 |= CHAR; // 8-bit char, UART-mode
+
+ U1RCTL &= ~URXEIE; // even erroneous characters trigger interrupts
+
+ UCTL1 = SWRST;
+ UCTL1 |= CHAR; // 8-bit char, UART-mode
+
+ if (l_ssel & 0x80) {
+ U1TCTL &= ~(SSEL_0 | SSEL_1 | SSEL_2 | SSEL_3);
+ U1TCTL |= (l_ssel & 0x7F);
+ }
+ else {
+ U1TCTL &= ~(SSEL_0 | SSEL_1 | SSEL_2 | SSEL_3);
+ U1TCTL |= SSEL_ACLK; // use ACLK, assuming 32khz
+ }
+
+ if ((l_mctl != 0) || (l_br != 0)) {
+ U1BR0 = l_br & 0x0FF;
+ U1BR1 = (l_br >> 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
+
--- /dev/null
+/*
+ * @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
+
--- /dev/null
+/*
+ * @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
+
--- /dev/null
+/*
+ * @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
--- /dev/null
+/**
+ * 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);
+
+}
--- /dev/null
+/**
+ * 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);
+
+}
--- /dev/null
+/**
+ * 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);
+
+}
--- /dev/null
+/*
+ * 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[]);
+
+}
--- /dev/null
+/*
+ * 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);
+
+}
--- /dev/null
+/**
+ * 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);
+
+}
--- /dev/null
+/**
+ * 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[]);
+
+}
--- /dev/null
+/**
+ * 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);
+}
--- /dev/null
+/**
+ * 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);
+
+}
--- /dev/null
+/**
+ * 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);
+
+}
--- /dev/null
+/**
+ * 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);
+
+
+
+}
--- /dev/null
+/**
+ * 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);
+
+
+
+}
--- /dev/null
+/**
+ * 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
+ }
--- /dev/null
+/**
+ * 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);
+
+}
--- /dev/null
+/**
+ * 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);
+
+}
--- /dev/null
+/**
+ * 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);
+
+}
--- /dev/null
+/**
+ * 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);
+}
--- /dev/null
+/**
+ * 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);
+}
--- /dev/null
+/**
+ * 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);
+
+}
--- /dev/null
+/**
+ * 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);
+
+}
--- /dev/null
+/**
+ * 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);
+
+}
--- /dev/null
+/**
+ * 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);
+
+}
--- /dev/null
+/**
+ * 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);
+
+}
--- /dev/null
+/*
+ * 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);
+
+}
--- /dev/null
+/*
+ * 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);
+
+}
--- /dev/null
+/**
+ * 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);
+
+}
--- /dev/null
+/**
+ * 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);
+
+}
--- /dev/null
+/**
+ * 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);
+
+}
--- /dev/null
+/**
+ * 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);
+
+}
--- /dev/null
+/**
+ * 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);
+
+}
--- /dev/null
+/**
+ * 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 <phy_enumerations.h>
+
+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);
+
+}
--- /dev/null
+/**
+ * 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);
+
+}
--- /dev/null
+/**
+ * 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);
+
+}
--- /dev/null
+/**
+ * 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);
+
+}
--- /dev/null
+/**
+ * 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);
+
+}
--- /dev/null
+/**
+ * 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);
+
+}
--- /dev/null
+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
--- /dev/null
+/*
+ * @author IPP HURRAY http://www.hurray.isep.ipp.pt/art-wise
+ * @author Andre Cunha
+ *
+ */
+
+#include <Timer.h>
+
+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;
+
+
+
+
+
+}
+
--- /dev/null
+/*
+ * @author IPP HURRAY http://www.hurray.isep.ipp.pt/art-wise
+ * @author Andre Cunha
+ *
+ */
+
+#include <Timer.h>
+
+#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<TMilli> as T_ackwait;
+
+ uses interface Timer<TMilli> as T_ResponseWaitTime;
+
+ uses interface Timer<TMilli> 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<INDIRECT_BUFFER_SIZE;i++)
+ {
+ if (indirect_trans_queue[i].handler > 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<INDIRECT_BUFFER_SIZE;i++)
+ {
+ if (indirect_trans_queue[i].handler > 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<INDIRECT_BUFFER_SIZE;i_indirect_trans++)
+ {
+ if (indirect_trans_queue[i_indirect_trans].handler == 0x00)
+ {
+ frame_pkt = (MPDU *) &indirect_trans_queue[i_indirect_trans].frame;
+ break;
+ }
+ }
+
+
+ }
+ else
+ {
+ //CREATE NORMAL TRANSMISSION PACKET POINTER
+ //////printfUART("sb %i\n", send_buffer_count);
+ atomic{
+ 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
+ {
+ //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;i<INDIRECT_BUFFER_SIZE;i++)
+ {
+ if (indirect_trans_queue[i].handler == 0x00)
+ {
+ //memcpy(&indirect_trans_queue[i].frame,frame_ptr,sizeof(MPDU));
+ frame_pkt = (MPDU *) &indirect_trans_queue[i].frame;
+ //printfUART("found slot","");
+ break;
+ }
+ }
+
+ //creation of a pointer to the association response structure
+ dest_long_ptr = (dest_long *) &frame_pkt->data[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<INDIRECT_BUFFER_SIZE;i++)
+ {
+ indirect_trans_queue[i].handler = 0x00;
+ indirect_trans_count=0;
+ }
+
+return;
+}
+
+
+error_t remove_indirect_trans(uint8_t handler)
+{
+
+ int i;
+ uint8_t removed_ok=0;
+ for(i=0;i<INDIRECT_BUFFER_SIZE;i++)
+ {
+ if (indirect_trans_queue[i].handler == handler)
+ {
+ indirect_trans_queue[i].handler = 0x00;
+ removed_ok = 1;
+ indirect_trans_count--;
+ break;
+ }
+ }
+
+ if (removed_ok == 0)
+ {
+ return MAC_INVALID_HANDLE;
+ }
+ else
+ {
+ return SUCCESS;
+ }
+}
+
+
+void increment_indirect_trans()
+{
+ int i;
+ for(i=0;i<INDIRECT_BUFFER_SIZE;i++)
+ {
+ if (indirect_trans_queue[i].handler != 0x00)
+ {
+ indirect_trans_queue[i].transaction_persistent_time++;
+ if (indirect_trans_queue[i].transaction_persistent_time == mac_PIB.macTransactionPersistenceTime )
+ remove_indirect_trans(indirect_trans_queue[i].handler);
+ }
+ }
+
+return;
+}
+
+void send_ind_trans_addr(uint32_t DeviceAddress[])
+{
+
+ uint8_t destination_address=0;
+
+ dest_short *dest_short_ptr =0;
+ dest_long *dest_long_ptr=0;
+
+ int i=0;
+ MPDU *frame_ptr=0;
+
+ ////printfUART("send_ind_trans_addr DeviceAddress0: %y DeviceAddress1: %y \n",DeviceAddress[0],DeviceAddress[1]);
+
+ //list_indirect_trans_buffer();
+
+ for(i=0;i<INDIRECT_BUFFER_SIZE;i++)
+ {
+ if (indirect_trans_queue[i].handler > 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);
+ }
+
+}
+
+*/
+
+
+}
+
--- /dev/null
+/*
+ * @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
--- /dev/null
+/*
+ * @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
+
--- /dev/null
+/*
+ * @author IPP HURRAY http://www.hurray.isep.ipp.pt/art-wise
+ * @author Andre Cunha
+ *
+ */
+
+#include <Timer.h>
+
+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;
+
+
+
+
+
+}
+
--- /dev/null
+/*
+ * @author IPP HURRAY http://www.hurray.isep.ipp.pt/art-wise
+ * @author Andre Cunha
+ *
+ */
+
+#include <Timer.h>
+
+#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<TMilli> as T_ackwait;
+
+ uses interface Timer<TMilli> as T_ResponseWaitTime;
+
+ uses interface Timer<TMilli> 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<INDIRECT_BUFFER_SIZE;i++)
+ {
+ if (indirect_trans_queue[i].handler > 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<INDIRECT_BUFFER_SIZE;i++)
+ {
+ if (indirect_trans_queue[i].handler > 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<INDIRECT_BUFFER_SIZE;i_indirect_trans++)
+ {
+ if (indirect_trans_queue[i_indirect_trans].handler == 0x00)
+ {
+ frame_pkt = (MPDU *) &indirect_trans_queue[i_indirect_trans].frame;
+ break;
+ }
+ }
+
+
+ }
+ else
+ {
+ //CREATE NORMAL TRANSMISSION PACKET POINTER
+ ////printfUART("sb %i\n", send_buffer_count);
+ atomic{
+
+ //TDBS Implementation
+ if (get_txoptions_upstream_buffer(TxOptions) == 1)
+ {
+ ////printfUART("sel up\n", "");
+
+ if (upstream_buffer_count > 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;i<INDIRECT_BUFFER_SIZE;i++)
+ {
+ if (indirect_trans_queue[i].handler == 0x00)
+ {
+ //memcpy(&indirect_trans_queue[i].frame,frame_ptr,sizeof(MPDU));
+ frame_pkt = (MPDU *) &indirect_trans_queue[i].frame;
+ printfUART("found slot","");
+ break;
+ }
+ }
+
+ //creation of a pointer to the association response structure
+ dest_long_ptr = (dest_long *) &frame_pkt->data[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<INDIRECT_BUFFER_SIZE;i++)
+ {
+ indirect_trans_queue[i].handler = 0x00;
+ indirect_trans_count=0;
+ }
+
+return;
+}
+
+
+error_t remove_indirect_trans(uint8_t handler)
+{
+
+ int i;
+ uint8_t removed_ok=0;
+ for(i=0;i<INDIRECT_BUFFER_SIZE;i++)
+ {
+ if (indirect_trans_queue[i].handler == handler)
+ {
+ indirect_trans_queue[i].handler = 0x00;
+ removed_ok = 1;
+ indirect_trans_count--;
+ break;
+ }
+ }
+
+ if (removed_ok == 0)
+ {
+ return MAC_INVALID_HANDLE;
+ }
+ else
+ {
+ return SUCCESS;
+ }
+}
+
+
+void increment_indirect_trans()
+{
+ int i;
+ for(i=0;i<INDIRECT_BUFFER_SIZE;i++)
+ {
+ if (indirect_trans_queue[i].handler != 0x00)
+ {
+ indirect_trans_queue[i].transaction_persistent_time++;
+ if (indirect_trans_queue[i].transaction_persistent_time == mac_PIB.macTransactionPersistenceTime )
+ remove_indirect_trans(indirect_trans_queue[i].handler);
+ }
+ }
+
+return;
+}
+
+void send_ind_trans_addr(uint32_t DeviceAddress[])
+{
+
+ uint8_t destination_address=0;
+
+ dest_short *dest_short_ptr =0;
+ dest_long *dest_long_ptr=0;
+
+ int i=0;
+ MPDU *frame_ptr=0;
+
+ //printfUART("send_ind_trans_addr DeviceAddress0: %y DeviceAddress1: %y \n",DeviceAddress[0],DeviceAddress[1]);
+
+ //list_indirect_trans_buffer();
+
+ for(i=0;i<INDIRECT_BUFFER_SIZE;i++)
+ {
+ if (indirect_trans_queue[i].handler > 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);
+ }
+
+}
+
+*/
+
+
+}
+
--- /dev/null
+/*
+ * @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
--- /dev/null
+/*
+ * @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
+
--- /dev/null
+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)
+
--- /dev/null
+/*
+ * @author IPP HURRAY http://www.hurray.isep.ipp.pt/art-wise
+ * @author Andre Cunha
+ *
+ */
+#include <Timer.h>
+
+#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;
+
+
+}
--- /dev/null
+/*
+ * @author IPP HURRAY http://www.hurray.isep.ipp.pt/art-wise
+ * @author Andre Cunha
+ *
+ */
+#include <Timer.h>
+#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<ResultListSize;i++)
+ {
+ printfUART("ED SCAN %i %i\n", (0x0A + i),EnergyDetectList[i]);
+ }
+ return SUCCESS;
+ }
+
+ for (i=0; i<ResultListSize;i++)
+ { /*
+ printfUART("cord id %i", PANDescriptorList[i].CoordPANId);
+ printfUART("CoordAddress %i", PANDescriptorList[i].CoordAddress);
+ printfUART("LogicalChannel %i", PANDescriptorList[i].LogicalChannel);
+ printfUART("SuperframeSpec %i", PANDescriptorList[i].SuperframeSpec);
+ printfUART("lqi %i\n", PANDescriptorList[i].lqi);
+ */
+ if(max_lqi < PANDescriptorList[i].lqi)
+ {
+ max_lqi =PANDescriptorList[i].lqi;
+ best_pan_index = i;
+ }
+ }
+
+ printfUART("SELECTED cord id %i", PANDescriptorList[best_pan_index].CoordPANId);
+ printfUART("CoordAddress %i", PANDescriptorList[best_pan_index].CoordAddress);
+ printfUART("LogicalChannel %i", PANDescriptorList[best_pan_index].LogicalChannel);
+ printfUART("SuperframeSpec %i", PANDescriptorList[best_pan_index].SuperframeSpec);
+ printfUART("lqi %i\n", PANDescriptorList[best_pan_index].lqi);
+
+
+
+ /*
+
+ coordinator_addr[0] = 0x00000001;
+
+ coordinator_addr[1] = (uint32_t)PANDescriptorList[best_pan_index].CoordAddress;
+
+ //pan_des = PANDescriptorList[best_pan_index];
+
+
+ //BUILD the PAN descriptor of the COORDINATOR
+ //assuming that the adress is short
+ pan_des.CoordAddrMode = SHORT_ADDRESS;
+ pan_des.CoordPANId = PANDescriptorList[best_pan_index].CoordAddress;
+ pan_des.CoordAddress0=0x00000000;
+ pan_des.CoordAddress1=0x00000000;
+ pan_des.LogicalChannel=PANDescriptorList[best_pan_index].LogicalChannel;
+ //superframe specification field
+ pan_des.SuperframeSpec = PANDescriptorList[best_pan_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;
+
+ */
+
+
+
+ printfUART("5 en sync %x \n", PANDescriptorList[best_pan_index].LogicalChannel);
+ // the sync enables the TimerAsync events, in order to enable the synchronization with the PAN coordinator
+ call MLME_SYNC.request(PANDescriptorList[best_pan_index].LogicalChannel,0);
+
+
+
+ //The networkdescriptorlist must contain information about every network that was heard
+
+ //make NetworkDescriptorList out of the PanDescriptorList
+
+
+ printfUART("6 add neigh\n", "");
+
+ networkdescriptorlist[0].PANId=PANDescriptorList[best_pan_index].CoordPANId;
+ 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;
+
+ add_neighbortableentry(networkdescriptorlist[0].PANId,0x00000000,0x00000000,PANDescriptorList[best_pan_index].CoordAddress,COORDINATOR,NEIGHBOR_IS_PARENT);
+
+ signal NLME_NETWORK_DISCOVERY.confirm(1,networkdescriptorlist, NWK_SUCCESS);
+
+
+
+ return SUCCESS;
+}
+
+/*****************************************************************************************************/
+/**************************************MLME-ORPHAN****************************************************/
+/*****************************************************************************************************/
+event error_t MLME_ORPHAN.indication(uint32_t OrphanAddress[1], uint8_t SecurityUse, uint8_t ACLEntry)
+{
+
+
+
+ return 0x0000;
+ }
+
+/*****************************************************************************************************/
+/**************************************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)
+{
+ ////printfUART("MLME_SYNC_LOSS.indication\n", "");
+ sync_loss = 1;
+ syncwait=1;
+ //signal NLME_SYNC.indication();
+/*
+
+printfUART("SL\n","");
+
+ call MLME_SCAN.request(ORPHAN_SCAN,0xFFFFFFFF,7);
+*/
+ 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[])
+{
+
+ uint32_t destinaddress[2];
+ printfUART("BN\n", "");
+
+
+ if (go_associate==1)
+ {
+ received_beacon_count++;
+
+ printfUART("bn %i\n", received_beacon_count);
+
+ if (received_beacon_count==5)
+ {
+ printfUART("sa \n", "");
+
+ go_associate=0;
+ //call MLME_ASSOCIATE.request(pan_des.LogicalChannel,SHORT_ADDRESS,pan_des.CoordPANId,coordinator_addr,0x00,0x00);
+
+ destinaddress[0]=0x00000000;
+ destinaddress[1]=0x00000000;
+
+
+ call MLME_ASSOCIATE.request(LOGICAL_CHANNEL,SHORT_ADDRESS,0x1234,destinaddress, set_capability_information(0x00,0x00,0x00,0x00,0x00,0x01),0);
+
+ }
+
+ }
+
+ return SUCCESS;
+}
+/*****************************************************************************************************/
+/**************************************MLME-START*****************************************************/
+/*****************************************************************************************************/
+event error_t MLME_START.confirm(uint8_t status)
+{
+ ////printfUART("MLME_START.confirm\n", "");
+ if (device_type==COORDINATOR)
+ {
+ signal NLME_NETWORK_FORMATION.confirm(status);
+ joined=1;
+ }
+ else
+ {
+ signal NLME_START_ROUTER.confirm(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)
+{
+
+ //notification that an other device wants to associate
+ //THIS DEVICE IS EITHER A COORDINATOR OR A ROUTER
+
+ uint8_t cindex=0;
+
+atomic{
+
+ //check the neighbour table
+ cindex = check_neighbortableentry(LONG_ADDRESS,DeviceAddress[0] , DeviceAddress[1]);
+
+
+ if( cindex > 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<neighbour_count; i++)
+ {
+ ////printfUART("compare %x %x\n", neighbortable[i].Extended_Address0, Address0);
+ if( (neighbortable[i].Extended_Address0 == Address0) && (neighbortable[i].Extended_Address1 == Address1))
+ {
+ //printfUART("already present \n", "" );
+ return i+1;
+ }
+ }
+ return 0;
+ }
+
+ return 0;
+ }
+
+ //function user to find a parent in the neighbour table
+ //Return 0:no parent is present
+ //Return i:parent is present and return the index of the entry + 1
+ uint8_t find_suitable_parent()
+ {
+ int i =0;
+ for (i=0; i<neighbour_count; i++)
+ {
+ if(neighbortable[i].Relationship == NEIGHBOR_IS_PARENT)
+ {
+ return i+1;
+ }
+ }
+ return 0;
+ }
+
+
+ //add a neighbortable entry
+ 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)
+ {
+
+ atomic{
+ neighbortable[neighbour_count].PAN_Id=PAN_Id;
+ neighbortable[neighbour_count].Extended_Address0=Extended_Address0;
+ neighbortable[neighbour_count].Extended_Address1=Extended_Address1;
+ neighbortable[neighbour_count].Network_Address=Network_Address;
+ neighbortable[neighbour_count].Device_Type=Device_Type;
+ neighbortable[neighbour_count].Relationship=Relationship;
+
+ neighbour_count++;
+ }
+
+ }
+
+
+
+ //update a neighbourtable entry
+ 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)
+ {
+ //search entry with correct extended address
+ uint8_t nrofEntry=0;
+ nrofEntry = check_neighbortableentry(0x01,Extended_Address0,Extended_Address1) - 1;
+
+ //update every attribute
+ neighbortable[nrofEntry].PAN_Id=PAN_Id;
+ neighbortable[nrofEntry].Extended_Address0=Extended_Address0;
+ neighbortable[nrofEntry].Extended_Address1=Extended_Address1;
+ neighbortable[nrofEntry].Network_Address=Network_Address;
+ neighbortable[nrofEntry].Device_Type=Device_Type;
+ neighbortable[nrofEntry].Relationship=Relationship;
+
+ ////printfUART("updated neighbourtable entry\n", "");
+ }
+
+
+ void list_neighbourtable()
+ {
+ int i;
+ ////printfUART("N List Count: %u\n", neighbour_count);
+
+ for(i=0;i<neighbour_count;i++)
+ {
+ printfUART("Panid %x", neighbortable[i].PAN_Id);
+ printfUART("Extaddr0 %x", neighbortable[i].Extended_Address0);
+ printfUART("Extaddr1 %x", neighbortable[i].Extended_Address1);
+ printfUART("nwkaddr %u", neighbortable[i].Network_Address);
+ printfUART("devtype %u", neighbortable[i].Device_Type);
+ printfUART("relation %u", neighbortable[i].Relationship);
+ printfUART("depth %u\n", neighbortable[i].Depth);
+ }
+ }
+/*************************************************************/
+/*****************Address Assignment functions****************/
+/*************************************************************/
+
+//calculate the size of the address sub-block for a router at depth d
+uint16_t Cskip(uint8_t d)
+{
+ uint8_t skip;
+ uint8_t power;
+ uint8_t x=1;
+ uint8_t Cm = nwk_IB.nwkMaxChildren;
+ uint8_t Rm = nwk_IB.nwkMaxRouters;
+ uint8_t Lm = nwk_IB.nwkMaxDepth;
+ /*////printfUART("nwk_IB.nwkMaxChildren: %i\n", nwk_IB.nwkMaxChildren);
+ ////printfUART("nwk_IB.nwkMaxRouters: %i\n", nwk_IB.nwkMaxRouters);
+ ////printfUART("nwk_IB.nwkMaxDepth: %i\n", nwk_IB.nwkMaxDepth);*/
+ if (Rm == 1)
+ {
+ skip = 1 + Cm * (Lm - d - 1);
+ }
+ else
+ {
+ int i;
+
+ power=(Lm - d - 1);
+ for(i=0;i<power;i++)
+ {
+ x=x*Rm;
+ }
+ skip = (1 + Cm - Rm - (Cm * x))/(1-Rm);
+ }
+ ////printfUART("Cksip function calculated: %i\n", skip);
+ return skip;
+}
+
+//Calculate the nexthopaddress of the appropriate child if route down is required
+uint16_t nexthopaddress(uint16_t destinationaddress,uint8_t d)
+{
+ uint16_t next_hop;
+
+ next_hop=(networkaddress + 1 + ((destinationaddress-(networkaddress+1))/cskip)* cskip);
+
+ ////printfUART("Nexthop address calculated: %i\n", next_hop);
+ return next_hop;
+}
+
+/*************************************************************/
+/*****************Initialization functions********************/
+/*************************************************************/
+ //initialization of the nwk IB
+ void init_nwkIB()
+ {
+ //nwk IB default values p 204-206
+ nwk_IB.nwkPassiveAckTimeout=0x03;
+ nwk_IB.nwkMaxBroadcastRetries=0x03;
+ nwk_IB.nwkMaxChildren=0x07; //number of children a device is allowed to have on its current network
+ nwk_IB.nwkMaxDepth=0x05; //the depth a device can have
+ nwk_IB.nwkMaxRouters=0x02; //number of routers anyone device is allowed to have on its current network
+ //neighbortableentry nwkNeighborTable[];//null set
+ nwk_IB.nwkNetworkBroadcastDeliveryTime=( nwk_IB.nwkPassiveAckTimeout * nwk_IB.nwkMaxBroadcastRetries );
+ nwk_IB.nwkReportConstantCost=0x00;
+ nwk_IB.nwkRouteDiscoveryRetriesPermitted=nwkcDiscoveryRetryLimit;
+ //set? nwkRouteTable;//Null set
+ nwk_IB.nwkSymLink=0;
+ nwk_IB.nwkCapabilityInformation=0x00;
+ nwk_IB.nwkUseTreeAddrAlloc=1;
+ nwk_IB.nwkUseTreeRouting=1;
+ nwk_IB.nwkNextAddress=0x0000;
+ nwk_IB.nwkAvailableAddresses=0x0000;
+ nwk_IB.nwkAddressIncrement=0x0001;
+ nwk_IB.nwkTransactionPersistenceTime=0x01f4;
+ }
+
+
+
+}
+
--- /dev/null
+/*
+ * @author IPP HURRAY http://www.hurray.isep.ipp.pt/art-wise
+ * @author http://www.open-zb.net
+ * @author Andre Cunha
+ */
+#ifndef __NWK_CONST__
+#define __NWK_CONST__
+
+//GLOBAL VARIABLES
+
+#define MAC_PANID 0x1234
+
+//SELECTED DEVICE TYPE
+
+#define TYPE_DEVICE END_DEVICE
+//#define TYPE_DEVICE ROUTER
+//#define TYPE_DEVICE COORDINATOR
+
+//test definitions
+#define DEVICE_DEPTH 0x01
+
+//used to operate in a fixed channel
+#define LOGICAL_CHANNEL 0x15
+
+//PAN VARIABLES
+//conflict error
+//#define PANID 0x1234
+
+#define AVAILABLEADDRESSES 0x04
+#define ADDRESSINCREMENT 0x0001
+#define MAXCHILDREN 0x06
+#define MAXDEPTH 0x03
+#define MAXROUTERS 0x04
+
+#define BEACON_ORDER 8
+#define SUPERFRAME_ORDER 4
+
+//test definitions
+
+//activated when the device depth is 0x01
+#define D1_PAN_EXT0 0x00000001
+#define D1_PAN_EXT1 0x00000001
+#define D1_PAN_SHORT 0x0000
+
+//activated when the device depth is 0x02
+#define D2_PAN_EXT0 0x00000002
+#define D2_PAN_EXT1 0x00000002
+#define D2_PAN_SHORT 0x0001
+
+//activated when the device depth is 0x03
+#define D3_PAN_EXT0 0x00000003
+#define D3_PAN_EXT1 0x00000003
+#define D3_PAN_SHORT 0x0002
+
+//activated when the device depth is 0x04
+#define D4_PAN_EXT0 0x00000006
+#define D4_PAN_EXT1 0x00000006
+#define D4_PAN_SHORT 0x0022
+
+
+
+// The Network layer constants are defined in here.
+//page 202
+//#define nwkcCoordinatorCapable //set at build time
+//#define nwkcDefaultSecurityLevel ENC-MIC-64
+
+#define nwkcDiscoveryRetryLimit 0x03
+#define nwkcMaxDepth 0x0f
+#define nwkcMinHeaderOverhead 0x08
+#define nwkcProtocolVersion 0x01
+#define nwkcRepairThreshold 0x03
+#define nwkcRouteDiscoveryTime 0x2710
+#define nwkcMaxBroadcastJitter 0x40
+#define nwkcInitialRREQRetries 0x03
+#define nwkcRREQRetries 0x02
+#define nwkcRREQRetryInterval 0xfe
+#define nwkcMinRReQJitter 0x01
+#define nwkcMaxRReQJitter 0x40
+
+
+// The NWK IB attributes are defined in here.
+typedef struct
+{
+//page 204
+ uint8_t nwkSequenceNumber;
+ uint8_t nwkPassiveAckTimeout;
+ uint8_t nwkMaxBroadcastRetries;
+ uint8_t nwkMaxChildren;
+ uint8_t nwkMaxDepth;
+ uint8_t nwkMaxRouters;
+//neighbortableentry nwkNeighborTable[];
+ uint8_t nwkNetworkBroadcastDeliveryTime;
+ uint8_t nwkReportConstantCost;
+ uint8_t nwkRouteDiscoveryRetriesPermitted;
+//set? nwkRouteTable;
+ uint8_t nwkSymLink;
+ uint8_t nwkCapabilityInformation;
+ uint8_t nwkUseTreeAddrAlloc;
+ uint8_t nwkUseTreeRouting;
+ uint16_t nwkNextAddress;
+ uint16_t nwkAvailableAddresses;
+ uint16_t nwkAddressIncrement;
+ uint16_t nwkTransactionPersistenceTime;
+
+} nwkIB;
+
+
+//NWK layer NeighborTableEntry
+typedef struct
+{
+//page 218
+ uint16_t PAN_Id;
+ uint32_t Extended_Address0;
+ uint32_t Extended_Address1;
+ uint16_t Network_Address;
+ uint8_t Device_Type;
+ uint8_t Relationship;
+
+ //optional fields
+ //we choose to exclude this fields due to memory limitation
+
+ //bool RxOnWhenIdle;
+ uint8_t Depth;
+ uint8_t Permit_Joining;
+ uint8_t Logical_Channel;
+ uint8_t Potential_Parent;
+ /*
+ uint8_t Beacon_Order;
+
+ uint8_t Transmit_Failure;
+ uint8_t Potential_Parent;
+ uint8_t LQI;
+ uint8_t Logical_Channel;
+ uint32_t Incoming_Beacon_Timestamp;
+ uint32_t Beacon_Transmission_Time_Offset;
+*/
+} neighbortableentry;
+
+// NWK layer NetworkDescriptor
+typedef struct
+{
+//page 166
+ uint16_t PANId;
+ uint8_t LogicalChannel;
+ uint8_t StackProfile;
+ uint8_t ZigBeeVersion;
+ uint8_t BeaconOrder;
+ uint8_t SuperframeOrder;
+ uint8_t PermitJoining;
+
+} networkdescriptor;
+
+//NEIGhBOUR TABLE COUNT
+#define NEIGHBOUR_TABLE_SIZE 7
+
+//beacon scheduling mechanims
+typedef struct
+{
+ uint8_t request_type;
+ uint8_t beacon_order;
+ uint8_t superframe_order;
+ uint8_t transmission_offset[3];
+
+}beacon_scheduling;
+
+#define SCHEDULING_REQUEST 0x01
+#define SCHEDULING_ACCEPT 0x02
+#define SCHEDULING_DENY 0x03
+
+#endif
--- /dev/null
+/*
+ * @author IPP HURRAY http://www.hurray.isep.ipp.pt/art-wise
+ * @author open-zb http://www.open-zb.net
+ * @author Andre Cunha
+ */
+
+#ifndef __NWK_ENUMERATIONS__
+#define __NWK_ENUMERATIONS__
+
+//NWK layer status values
+//page 243
+enum {
+ NWK_SUCCESS = 0x00,
+ NWK_INVALID_PARAMETER = 0xc1,
+ NWK_INVALID_REQUEST = 0xc2,
+ NWK_NOT_PERMITTED = 0xc3,
+ NWK_STARTUP_FAILURE = 0xc4,
+ NWK_ALREADY_PRESENT = 0xc5,
+ NWK_SYNC_FAILURE = 0xc6,
+ NWK_TABLE_FULL = 0xc7,
+ NWK_UNKNOWN_DEVICE = 0xc8,
+ NWK_UNSUPPORTED_ATTRIBUTE = 0xc9,
+ NWK_NO_NETWORKS = 0xca,
+ NWK_LEAVE_UNCONFIRMED = 0xcb,
+ NWK_MAX_FRM_CNTR = 0xcc,
+ NWK_NO_KEY = 0xcd,
+ NWK_BAD_CCM_OUTPUT = 0xce
+ };
+
+//NWK layer device types
+//page 342
+enum {
+ COORDINATOR = 0x00,
+ ROUTER =0x01,
+ END_DEVICE = 0x02
+ };
+
+
+//NWK layer Relationship
+//page 342
+enum {
+ NEIGHBOR_IS_PARENT = 0x00,
+ NEIGHBOR_IS_CHILD = 0x01,
+ NEIGHBOR_IS_SIBLING = 0x02,
+ NEIGHBOR_IS_NON = 0x03,
+ NEIGHBOR_IS_PREVIOUS_CHILD = 0x04,
+ };
+
+
+//NWK layer PIB attributs ennumerations
+//PAG 317
+enum{
+ NWKSEQUENCENUMBER = 0x81,
+ NWKPASSIVEACKTIMEOUT = 0x82,
+ NWKMAXBROADCASTRETRIES = 0x83,
+ NWKMAXCHILDREN = 0x84,
+ NWKMAXDEPTH = 0x85,
+ NWKMAXROUTERS = 0x86,
+ //NWKNEIGHBORTABLE = 0x87
+ NWKMETWORKBROADCASTDELIVERYTIME = 0x88,
+ NWKREPORTCONSTANTCOST = 0x89,
+ NWKROUTEDISCOVERYRETRIESPERMITED = 0x8a,
+ //NWKROUTETABLE
+ NWKSYMLINK = 0x8e,
+ NWKCAPABILITYINFORMATION = 0x8f,
+ NWKUSETREEADDRALLOC = 0x90,
+ NWKUSETREEROUTING = 0x91,
+ NWKNEXTADDRESS = 0x92,
+ NWKAVAILABLEADDRESSES = 0x93,
+ NWKADDRESSINCREMENT = 0x94,
+ NWKTRANSACTIONPERSISTENCETIME = 0x95
+};
+
+#endif
--- /dev/null
+/*
+ * @author IPP HURRAY http://www.hurray.isep.ipp.pt/art-wise
+ * @author Andre Cunha
+ *
+ */
+
+#include "CC2420.h"
+#include "IEEE802154.h"
+
+configuration Phy {
+
+ 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;
+
+}
+
+implementation {
+
+ components PhyM;
+
+ components MainC;
+ MainC.SoftwareInit -> 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;
+}
--- /dev/null
+/*
+ * @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;
+
+}
+
+
+
+}
+
--- /dev/null
+/*
+ * @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
+
--- /dev/null
+/*
+ * @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
--- /dev/null
+/*
+ * @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();
+
+ }
+
--- /dev/null
+/*
+ * @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;
+
+}
--- /dev/null
+/*
+ * @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<T32khz,uint32_t> 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;
+}
+
+
+
+
+}