/*
* 802.15.4 stack , Mac layer - 0.1
*
* Copyright (C) 2005 Srinivas Naga Vutukuri <cheluvi@users.sourceforge.net>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of
* the License, or (at your option) any later version.
*
*/
#include <linux/types.h>
#include "mac.h"
/* message types. */
#define assoc 1
#define gtsreq 2
#define datareq 3
#define BEACON_LOST 1 /* TO CHECK */
#define TRX_OFF 0
#define RX_ON 1
/* Globals */
uint8_t Device;
uint8_t find_acoordinator_realignment;
uint8_t message;
uint8_t missed_beacons;
uint8_t LossReason;
uint8_t GTS_db[GTS_LIST_SIZE];
uint8_t request_type;
uint8_t current_state;
uint8_t original_state;
uint8_t will_fit;
uint8_t PHY_In_TX;
uint8_t phystate;
extern uint8_t key_found;
extern uint8_t sec_proc;
extern uint8_t NB;
extern uint8_t iPANcoordinator; /*Not PAN coordinator.*/
extern uint8_t beacon_enabled_PAN;
extern uint8_t too_long;
extern uint8_t GTSId; /*GTS Id. */
extern uint16_t txo;
extern struct mac_pib MacPIB;
/* Function Prototypes. */
extern void mac_init(void);
extern void init_for_scan(void);
extern uint8_t select_channel(void);
extern uint8_t get_MacPIB(uint8_t PIBattr, uint64_t PIBval);
extern uint8_t set_MacPIB(uint8_t PIBattr, uint64_t PIBval);
extern void apply_security(void);
extern void init_CSMA_CA(void);
extern void set_beacon_search_period (void);
extern void create_GTS_allocation (void);
extern void create_GTS_request (void);
extern void create_data_request_cm (void);
//extern void check_entry_msduHandle (void);
extern void delete_entry(void);
extern void set_rxon_interval (void);
//extern void plme_set_trx_state_request (void);
extern void set_defer_interval (void);
#ifdef TODO
void init (void)
{
init_mac_pib ();
mac_init ();
}
#endif
uint8_t mlme_scan_request (uint8_t scantype, uint16_t channel_list, uint16_t scan_duration)
{
uint8_t status = SUCCESS;
uint8_t original_state, current_state;
uint8_t current_channel, original_channel;
original_state = W;
init_for_scan ();
switch (scantype){
case W_ed :
/* Energy Detect */
if (Device == FFD)
{
select_channel ();
#ifdef TODO
plme_set_request (phyCurrentChannel, current_channel);
#endif
current_state = W_ed; /* Energy Detection. */
}
else
{
current_channel = original_channel;
if (original_state == A)
current_state = A;
else
current_state = W;
}
break;
case W_as :
/* Active Scan */
if (Device == FFD)
{
select_channel ();
#ifdef TODO
plme_set_request (phyCurrentChannel, current_channel);
#endif
current_state = X_as;
}
else
{
current_channel = original_channel;
if (original_state == A)
current_state = A;
else
current_state = W;
}
break;
case W_ps :
/* Passive Scan */
select_channel ();
#ifdef TODO
plme_set_request (phyCurrentChannel, current_channel);
#endif
current_state = X_as;
break;
case W_os :
/* Orphan Scan */
error ("must be associated");
find_acoordinator_realignment = FALSE;
select_channel ();
#ifdef TODO
plme_set_request (phyCurrentChannel, current_channel);
#endif
current_state = X_os;
break;
}
return status;
}
uint8_t mlme_associate_request (uint16_t clc,uint16_t cam, uint16_t cpid,union ADDRESS caddr,uint16_t CapabilityInformation, uint8_t SecurityEnable)
{
uint8_t status = SUCCESS;
uint8_t original_state, current_state;
if (SecurityEnable == TRUE)
{
apply_security ();
if (key_found == TRUE && sec_proc == TRUE)
{
goto Zp_cac;
}
else if (key_found == FALSE)
{
Zp_cac_unkey:
status = UNAVAILABLE_KEY;
/*MLME_ASSOCIATE_confirm (AssocDevAddr, status) */
current_state = Zp;
}
else if (key_found == TRUE && sec_proc == FALSE)
{
Zp_cac_fsc:
status = FAILED_SECURITY_CHECK;
/* MLME_ASSOCIATE_confirm (AssocDevAddr,status); */
current_state = Zp;
}
}
else
{
Zp_cac:
#ifdef TODO
create_assoc_cmd (fcf,msdu,psdu,s_length);
#endif
message = assoc;
original_state = Zp;
txo = 1;
/* Set the PhyCurrentChannel value. */
#ifdef TODO
plme_set_request (phyCurrentChannel, clc);
#endif
NB = 0;
init_CSMA_CA ();
current_state = B;
}
return status;
}
uint8_t mlme_start_request (uint16_t BPID,uint8_t *xchannel,uint16_t beaconOrder,uint16_t superframeOrder,uint8_t PANCoordinator, uint16_t ble, uint16_t co_re, uint8_t SecurityEnable)
{
uint8_t status = SUCCESS;
uint8_t current_state;
if (MacPIB.macShortAddress != 255)
{
MacPIB.macBeaconOrder = beaconOrder;
MacPIB.macSuperframeOrder = superframeOrder;
if (Device == PANCOORDINATOR)
{
MacPIB.macPANId = BPID;
/* PLME_SET_request (phyCurrentChannel, xchannel[i])*/
#ifdef TODO
plme_set_request (phyCurrentChannel, xchannel[i]);
#endif
iPANcoordinator = 1;
current_state = Ya;
}
else
{
/* TODO: goto Ya_failed; */
}
}
else
{
status = NO_SHORT_ADDRESS;
/* MLME_START_confirm (status) */
current_state = Ya;
}
return status;
}
uint8_t mlme_sync_request (uint8_t TrackBeacon)
{
uint8_t status = SUCCESS;
uint8_t current_state;
if (beacon_enabled_PAN == TRUE)
{
/* PLME_SET_TRX_STATE_request (RX_ON)*/
set_beacon_search_period ();
Tracking_Beacon:
#ifdef TODO
SET (NOW+ totaltime, T_scan_duration);
T_scan_duration ();
#endif
if (TrackBeacon == TRUE)
{
missed_beacons = missed_beacons + 1;
if (missed_beacons != aMaxLostBeacons)
{
set_beacon_search_period ();
#ifdef TODO
SET (NOW+ totaltime, T_scan_duration);
#endif
goto Tracking_Beacon;
}
}
LossReason = BEACON_LOST;
/* MLME_SYNC_LOSS_indication (LossReason) */
current_state = W;
}
else
{
error ("Only allowed on a beacon enabled PAN");
}
return status;
}
/* Data Request */
uint8_t mcps_data_request (uint16_t sam,uint16_t spid,union ADDRESS src, uint16_t dam, uint16_t dpid, union ADDRESS dst, uint16_t ml, uint16_t *m /* To Check */, uint16_t msduHandle, uint16_t txo)
{
uint8_t status = SUCCESS;
uint8_t current_state;
if (txo == 8 || txo == 9 || txo == 10 || txo == 11 || txo == 12 || txo == 13 || txo == 14 || txo == 15)
{
apply_security ();
if (!key_found)
{
status = UNAVAILABLE_KEY;
/* MCPS_DATA_confirm (msduHandle,status) */
current_state = A;
}
else
{
if (!too_long)
{
if (!sec_proc)
{
status = FAILED_SECURITY_CHECK;
/* MCPS_DATA_confirm (msduHandle, status) */
current_state = A;
}
else
{
//goto t_gts;
}
}
else
{
status = FRAME_TOO_LONG;
/* MCPS_DATA_confirm (msduHandle, status) */
current_state = A;
}
}
}
return status;
}
uint8_t mlme_gts_request (char GTSChar, uint8_t SecurityEnable)
{
uint8_t status = SUCCESS;
uint8_t current_state;
if (SecurityEnable == TRUE)
{
apply_security ();
if (key_found == FALSE)
{
status = UNAVAILABLE_KEY;
/* MLME_GTS_confirm (GTSChar, status);*/
}
else
{
if (sec_proc == FALSE)
{
status = FAILED_SECURITY_CHECK;
/* MLME_GTS_Confirm (GTSCh