این فایل fama.cc است فایل fama.h را هم در ادامه می گذارم
[code]extern "C" {
#include <stdlib.h>
#include <stdio.h>
}
#include "fama.h"
#include "underwatersensor/uw_routing/vectorbasedforward.h"
int hdr_FAMA::offset_;
static class FAMA_HeaderClass: public PacketHeaderClass{
public:
FAMA_HeaderClass():PacketHeaderClass("PacketHeader/FAMA",sizeof(hdr_FAMA))
{
bind_offset(&hdr_FAMA::offset_);
}
}class_FAMA_hdr;
static class FAMAClass : public TclClass {
public:
FAMAClass():TclClass("Mac/UnderwaterMac/FAMA") {}
TclObject* create(int, const char*const*) {
return (new FAMA());
}
}class_FAMA;
void FAMA_ND_Timer::expire(Event *e)
{
mac_->sendPkt(mac_->makeND());
nd_times_--;
printf("\n I am in FAMA_ND_Timer::expire function and time is =%f \n",NOW);
if( nd_times_ > 0 )
resched(Random::uniform(mac_->NDPeriod));
}
void FAMA_BackoffTimer::expire(Event *e)
{
printf("\n I am in FAMA_BackoffTimer::expire function and time is =%f \n",NOW);
mac_->sendRTS(2*mac_->MaxPropDelay
+mac_->RTSTxTime+mac_->CTSTxTime+mac_->EstimateError);
}
void FAMA_StatusHandler::handle(Event *e)
{
printf("\n I am in FAMA_StatusHandler::handle function and time is =%f \n",NOW);
mac_->StatusProcess();
}
void FAMA_WaitCTSTimer::expire(Event *e)
{
printf("\n I am in FAMA_WaitCTSTimer::expire function and time is =%f \n",NOW);
mac_->doBackoff();
}
void FAMA_DataSendTimer::expire(Event *e)
{
printf("\n I am in FAMA_DataSendTimer::expire function and time is =%f \n",NOW);
mac_->processDataSendTimer(this);
}
void FAMA_DataBackoffTimer::expire(Event *e)
{
printf("\n I am in FAMA_DataBackoffTimer::expire function and time is =%f \n",NOW);
mac_->processDataBackoffTimer();
}
void FAMA_RemoteTimer::expire(Event* e)
{
printf("\n I am in FAMA_RemoteTimer::expire function and time is =%f \n",NOW);
mac_->processRemoteTimer();
}
void FAMA_CallBackHandler::handle(Event* e)
{
printf("\n I am in FAMA_CallBackHandler::handle function and time is =%f \n",NOW);
mac_->CallbackProcess(e);
}
FAMA::FAMA(): UnderwaterMac(), FAMA_Status(PASSIVE), NDPeriod(4), MaxBurst(1),
DataPktInterval(0.00001), EstimateError(0.001),DataPktSize(1600),
neighbor_id(0), backoff_timer(this), status_handler(this), NDTimer(this),
WaitCTSTimer(this),DataBackoffTimer(this),RemoteTimer(this), CallBack_Handler(this)
{
MaxPropDelay = UnderwaterChannel::Transmit_distance()/1500.0;
RTSTxTime = MaxPropDelay;
CTSTxTime = RTSTxTime + 2*MaxPropDelay;
MaxDataTxTime = DataPktSize/bit_rate_; //1600bits/10kbps
bind("MaxBurst", &MaxBurst);
NDTimer.resched(Random::uniform(NDPeriod)+0.000001);
}
void FAMA::sendPkt(Packet *pkt)
{
hdr_cmn* cmh=HDR_CMN(pkt);
//hdr_FAMA* FAMAh = hdr_FAMA::access(pkt);
printf("\n I am in FAMA::sendPkt function and time is =%f \n",NOW);
cmh->direction() = hdr_cmn::DOWN;
UnderwaterSensorNode* n=(UnderwaterSensorNode*) node_;
double txtime=cmh->txtime();
Scheduler& s=Scheduler::instance();
switch( n->TransmissionStatus() ) {
case SLEEP:
Poweron();
case IDLE:
n->SetTransmissionStatus(SEND);
cmh->timestamp() = NOW;
cmh->direction() = hdr_cmn::DOWN;
sendDown(pkt);
s.schedule(&status_handler,&status_event,txtime);
break;
case RECV:
printf("RECV-SEND Collision!!!!!\n");
Packet::free(pkt);
break;
default:
//status is SEND
printf("node%d send data too fast\n",index_);
Packet::free(pkt);
}
return;
}
void FAMA::StatusProcess()
{
printf("\n I am in FAMA::StatusProcess function and time is =%f \n",NOW);
UnderwaterSensorNode* n=(UnderwaterSensorNode*) node_;
n->SetTransmissionStatus(IDLE);
return;
}
void FAMA::TxProcess(Packet* pkt)
{
Scheduler::instance().schedule(&CallBack_Handler, &callback_event, CALLBACK_DELAY);
printf("\n I am in FAMA::TxProcess function and time is =%f \n",NOW);
if( NeighborList_.empty() ) {
Packet::free(pkt);
return;
}
//figure out how to cache the packet will be sent out!!!!!!!
hdr_cmn* cmh = HDR_CMN(pkt);
hdr_uwvb* vbh = HDR_UWVB(pkt);
hdr_FAMA* FAMAh = hdr_FAMA::access(pkt);
cmh->size() = DataPktSize;
cmh->txtime() = MaxDataTxTime;
cmh->error() = 0;
cmh->direction() = hdr_cmn::DOWN;
UpperLayerPktType = cmh->ptype();
cmh->next_hop() = NeighborList_[neighbor_id];
neighbor_id = (neighbor_id+1)%NeighborList_.size();
cmh->ptype() = PT_FAMA;
vbh->target_id.addr_ = cmh->next_hop();
FAMAh->packet_type = hdr_FAMA::FAMA_DATA;
FAMAh->SA = index_;
FAMAh->DA = cmh->next_hop();
PktQ_.push(pkt);
//fill the next hop when sending out the packet;
if( (PktQ_.size() == 1) /*the pkt is the first one*/
&& FAMA_Status == PASSIVE ) {
if( CarrierDected() ) {
doRemote(2*MaxPropDelay+EstimateError);
}
else{
sendRTS(2*MaxPropDelay+CTSTxTime+RTSTxTime+EstimateError);
}
}
}
void FAMA::RecvProcess(Packet *pkt)
{
hdr_FAMA* FAMAh = hdr_FAMA::access(pkt);
nsaddr_t dst = FAMAh->DA;
//int src = mh->macSA();
hdr_cmn* cmh=HDR_CMN(pkt);
printf("\n I am in FAMA::RecvProcess function and time is =%f \n",NOW);
if( backoff_timer.status() == TIMER_PENDING ) {
backoff_timer.cancel();
doRemote(2*MaxPropDelay+EstimateError);
} else if( RemoteTimer.status() == TIMER_PENDING ) {
RemoteTimer.cancel();
RemoteTimer.ExpiredTime = -1;
}
/*ND is not a part of FAMA. We just want to use it to get next hop
*So we do not care wether it collides with others
*/
if( (cmh->ptype()==PT_FAMA)
&& (FAMAh->packet_type==hdr_FAMA::ND) ) {
processND(pkt);
Packet::free(pkt);
return;
}
if( cmh->error() )
{
//printf("broadcast:node %d gets a corrupted packet at %f\n",index_,NOW);
if(drop_)
drop_->recv(pkt,"Error/Collision");
else
Packet::free(pkt);
doRemote(2*MaxPropDelay+EstimateError);
return;
}
if( WaitCTSTimer.status() == TIMER_PENDING ) {
//printf("%f: node %d receive RTS\n", NOW, index_);
WaitCTSTimer.cancel();
if( (cmh->ptype() == PT_FAMA )
&& (FAMAh->packet_type==hdr_FAMA::CTS)
&& (cmh->next_hop()==index_) ) {
//receiving the CTS
sendDataPkt();
}
else {
doBackoff();
}
Packet::free(pkt);
return;
}
if( cmh->ptype() == PT_FAMA ) {
switch( FAMAh->packet_type ) {
case hdr_FAMA::RTS:
//printf("%f: node %d receive RTS\n", NOW, index_);
if( dst == index_ ) {
processRTS(pkt);
}
doRemote(CTSTxTime+2*MaxPropDelay+EstimateError);
break;
case hdr_FAMA::CTS:
//printf("%f: node %d receive CTS\n", NOW, index_);
// this CTS must be not for this node
doRemote(2*MaxPropDelay+EstimateError);
break;
default:
//printf("%f: node %d receive DATA\n", NOW, index_);
//process Data packet
if( dst == index_ ) {
cmh->ptype() = UpperLayerPktType;
sendUp(pkt);
return;
}
else {
doRemote(MaxPropDelay+EstimateError);
}
}
}
Packet::free(pkt);
}
void FAMA::sendDataPkt()
{
int PktQ_Size = PktQ_.size();
int SentPkt = 0;
Time StartTime = NOW;
nsaddr_t recver = HDR_CMN(PktQ_.front())->next_hop();
Packet* tmp = NULL;
printf("\n I am in FAMA::sendDataPkt function and time is =%f \n",NOW);
for(int i=0; i<PktQ_Size && SentPkt<MaxBurst; i++) {
tmp = PktQ_.front();
PktQ_.pop();
if( HDR_CMN(tmp)->next_hop() == recver ) {
SentPkt++;
FAMA_DataSendTimer* DataSendTimer = new FAMA_DataSendTimer(this);
DataSendTimer->pkt_ = tmp;
DataSendTimer->resched(StartTime-NOW);
DataSendTimerSet.insert(DataSendTimer);
if( !PktQ_.empty() ) {
StartTime += HDR_CMN(PktQ_.front())->txtime() + DataPktInterval;
}
else {
break;
}
}
else{
PktQ_.push(tmp);
}
}
FAMA_Status = WAIT_DATA_FINISH;
DataBackoffTimer.resched(MaxPropDelay+StartTime-NOW);
}
void FAMA::processDataSendTimer(FAMA_DataSendTimer * DataSendTimer)
{
FAMA_DataSendTimer* tmp = DataSendTimer;
sendPkt(DataSendTimer->pkt_);
DataSendTimer->pkt_ = NULL;
DataSendTimerSet.erase(DataSendTimer);
printf("\n I am in FAMA::processDataSendTimer function and time is =%f \n",NOW);
delete tmp;
}
void FAMA::processDataBackoffTimer()
{
printf("\n I am in FAMA::processDataBackoffTimer function and time is =%f \n",NOW);
if( !PktQ_.empty() )
doBackoff();
else
FAMA_Status = PASSIVE;
}
Packet* FAMA::makeND()
{
Packet* pkt = Packet::alloc();
hdr_cmn* cmh = HDR_CMN(pkt);
hdr_FAMA* FAMAh = hdr_FAMA::access(pkt);
printf("\n I am in FAMA::makeND function and time is =%f \n",NOW);
cmh->size() = 2*sizeof(nsaddr_t)+1;
cmh->txtime() = getTxTimebyPktSize(cmh->size());
cmh->error() = 0;
cmh->direction() = hdr_cmn::DOWN;
cmh->ptype() = PT_FAMA;
cmh->next_hop() = MAC_BROADCAST;
FAMAh->packet_type = hdr_FAMA::ND;
FAMAh->SA = index_;
FAMAh->DA = MAC_BROADCAST;
return pkt;
}
void FAMA::processND(Packet *pkt)
{
printf("\n I am in FAMA::processND function and time is =%f \n",NOW);
hdr_FAMA* FAMAh = hdr_FAMA::access(pkt);
NeighborList_.push_back(FAMAh->SA);
return;
}
Packet* FAMA::makeRTS(nsaddr_t Recver)
{
Packet* pkt = Packet::alloc();
hdr_cmn* cmh = HDR_CMN(pkt);
hdr_FAMA* FAMAh = hdr_FAMA::access(pkt);
printf("\n I am in FAMA::makeRTS function and time is =%f \n",NOW);
cmh->size() = getPktSizebyTxTime(RTSTxTime);
cmh->txtime() = RTSTxTime;
cmh->error() = 0;
cmh->direction() = hdr_cmn::DOWN;
cmh->ptype() = PT_FAMA;
cmh->next_hop() = Recver;
FAMAh->packet_type = hdr_FAMA::RTS;
FAMAh->SA = index_;
FAMAh->DA = Recver;
return pkt;
}
void FAMA::sendRTS(Time DeltaTime)
{
printf("\n I am in FAMA::sendRTS function and time is =%f \n",NOW);
hdr_cmn* cmh = HDR_CMN( PktQ_.front() );
sendPkt( makeRTS(cmh->next_hop()) );
FAMA_Status = WAIT_CTS;
WaitCTSTimer.resched(DeltaTime);
}
void FAMA::processRTS(Packet *pkt)
{
printf("\n I am in FAMA::processRTS function and time is =%f \n",NOW);
nsaddr_t RTS_Sender = hdr_FAMA::access(pkt)->SA;
sendPkt(makeCTS(RTS_Sender));
FAMA_Status = WAIT_DATA;
}
Packet* FAMA::makeCTS(nsaddr_t RTS_Sender)
{
Packet* pkt = Packet::alloc();
hdr_cmn* cmh = HDR_CMN(pkt);
hdr_FAMA* FAMAh = hdr_FAMA::access(pkt);
printf("\n I am in FAMA::makeCTS function and time is =%f \n",NOW);
cmh->size() = getPktSizebyTxTime(CTSTxTime);
cmh->txtime() = CTSTxTime;
cmh->error() = 0;
cmh->direction() = hdr_cmn::DOWN;
cmh->ptype() = PT_FAMA;
cmh->next_hop() = RTS_Sender;
FAMAh->packet_type = hdr_FAMA::CTS;
FAMAh->SA = index_;
FAMAh->DA = RTS_Sender;
return pkt;
}
/*PktSize is in byte*/
Time FAMA::getTxTimebyPktSize(int PktSize)
{
printf("\n I am in FAMA::getTxTimebyPktSize function and time is =%f \n",NOW);
return (PktSize*8)*encoding_efficiency_/bit_rate_;
}
int FAMA::getPktSizebyTxTime(Time TxTime)
{
printf("\n I am in FAMA::getPktSizebyTxTime function and time is =%f \n",NOW);
return int((TxTime*bit_rate_)/(8*encoding_efficiency_));
}
bool FAMA::CarrierDected()
{
printf("\n I am in FAMA::CarrierDected function and time is =%f \n",NOW);
UnderwaterSensorNode* n=(UnderwaterSensorNode*) node_;
if( n->TransmissionStatus() == RECV
|| n->TransmissionStatus() == SEND ) {
return true;
}
else {
return false;
}
}
void FAMA::doBackoff()
{
Time BackoffTime = Random::uniform(10*RTSTxTime);
FAMA_Status = BACKOFF;
if( backoff_timer.status() == TIMER_PENDING ) {
backoff_timer.cancel();
}
printf("\n I am in FAMA::doBackoff function and time is =%f \n",NOW);
backoff_timer.resched(BackoffTime);
}
void FAMA::doRemote(Time DeltaTime)
{
FAMA_Status = REMOTE;
printf("\n I am in FAMA::doRemote function and time is =%f \n",NOW);
if( NOW+DeltaTime > RemoteTimer.ExpiredTime ) {
RemoteTimer.ExpiredTime = NOW+DeltaTime;
if( RemoteTimer.status() == TIMER_PENDING ) {
RemoteTimer.cancel();
}
RemoteTimer.resched(DeltaTime);
}
}
void FAMA::processRemoteTimer()
{
printf("\n I am in FAMA::processRemoteTimer function and time is =%f \n",NOW);
if( PktQ_.empty() ) {
FAMA_Status = PASSIVE;
}
else {
doBackoff();
//sendRTS(2*MaxPropDelay+CTSTxTime+RTSTxTime+EstimateError);
}
}
void FAMA::CallbackProcess(Event* e)
{
printf("\n I am in FAMA::CallbackProcess function and time is =%f \n",NOW);
callback_->handle(e);
}
int FAMA::command(int argc, const char *const *argv)
{
if(argc == 3) {
if (strcmp(argv[1], "node_on") == 0) {
Node* n1=(Node*) TclObject::lookup(argv[2]);
if (!n1) return TCL_ERROR;
node_ =n1;
return TCL_OK;
}
}
printf("\n I am in FFAMA::command function and time is =%f \n",NOW);
return UnderwaterMac::command(argc, argv);
}
[/code]
اینم فایل دوم
#ifndef __FAMA_H__
#define __FAMA_H__
#include <packet.h>
#include <random.h>
#include <timer-handler.h>
#include <mac.h>
#include "../underwatermac.h"
#include "../underwaterchannel.h"
#include "../underwaterpropagation.h"
#include <queue>
#include <vector>
#include <set>
using namespace std;
typedef double Time;
#define CALLBACK_DELAY 0.001
class FAMA;
struct hdr_FAMA{
nsaddr_t SA;
nsaddr_t DA;
enum PacketType {
RTS, //the previous forwarder thinks this is DATA-ACK
CTS,
FAMA_DATA,
ND //neighbor discovery. need know neighbors, so it can be used as next hop.
} packet_type;
static int offset_;
inline static int& offset() { return offset_; }
inline static hdr_FAMA* access(const Packet* p) {
return (hdr_FAMA*) p->access(offset_);
}
};
class FAMA_ND_Timer: public TimerHandler{
public:
FAMA_ND_Timer(FAMA* mac): TimerHandler() {
printf("I AM FAMA_ND_Timer: TimerHandler \n");
mac_ = mac;
nd_times_ = 4;
}
protected:
FAMA* mac_;
int nd_times_;
virtual void expire(Event* e);
};
class FAMA_BackoffTimer: public TimerHandler{
public:
FAMA_BackoffTimer(FAMA* mac): TimerHandler() {
printf("I AM FAMA_Backoff_Timer: TimerHandler \n");
mac_ = mac;
}
protected:
FAMA* mac_;
virtual void expire(Event* e);
};
class FAMA_StatusHandler: public Handler{
public:
FAMA_StatusHandler(FAMA* mac): Handler() {
printf("I AM FAMA_StatuseHandler: Handler \n");
mac_ = mac;
}
protected:
FAMA* mac_;
virtual void handle(Event* e);
};
class FAMA_WaitCTSTimer: public TimerHandler{
public:
FAMA_WaitCTSTimer(FAMA* mac): TimerHandler() {
printf("I AM FAMA_WaitCTSTimer TimerHandler \n");
mac_ = mac;
}
protected:
FAMA* mac_;
virtual void expire(Event* e);
};
class FAMA_DataSendTimer: public TimerHandler{
public:
FAMA_DataSendTimer(FAMA* mac): TimerHandler() {
printf("I AM FAMA_DataSendTimer: TimerHandler \n");
mac_ = mac;
}
Packet* pkt_;
protected:
FAMA* mac_;
virtual void expire(Event* e);
};
class FAMA_DataBackoffTimer: public TimerHandler{
public:
FAMA_DataBackoffTimer(FAMA* mac): TimerHandler() {
printf("I AM FAMA_DataBackoffTimer: public TimerHandler \n");
mac_ = mac;
}
protected:
FAMA* mac_;
virtual void expire(Event* e);
};
class FAMA_RemoteTimer: public TimerHandler{
public:
FAMA_RemoteTimer(FAMA* mac): TimerHandler() {
printf("I AM FAMA_RemoteTimer: TimerHandler \n");
mac_ = mac;
ExpiredTime = -1;
}
protected:
FAMA* mac_;
Time ExpiredTime;
virtual void expire(Event* e);
friend class FAMA;
};
class FAMA_CallBackHandler: public Handler{
public:
FAMA_CallBackHandler(FAMA* mac): Handler() {
printf("I AM FAMA_CallBackHandler: Handler \n");
mac_ = mac;
}
protected:
FAMA* mac_;
virtual void handle(Event* e);
};
class FAMA: public UnderwaterMac{
public:
FAMA();
int command(int argc, const char*const* argv);
void TxProcess(Packet* pkt);
void RecvProcess(Packet* pkt);
protected:
enum {
PASSIVE,
BACKOFF,
WAIT_CTS,
WAIT_DATA_FINISH,
WAIT_DATA,
REMOTE /*I don't know what it it means. but
node can only receiving packet in this status*/
}FAMA_Status;
Time NDPeriod;
int MaxBurst; //the maximum number of packet burst. default is 1
Time DataPktInterval; //0.0001??
Time EstimateError; //Error for timeout estimation
int DataPktSize;
int neighbor_id; //use this value to pick the next hop one by one
FAMA_BackoffTimer backoff_timer;
FAMA_StatusHandler status_handler;
FAMA_ND_Timer NDTimer; //periodically send out Neighbor discovery packet for 4 times.
FAMA_WaitCTSTimer WaitCTSTimer;
FAMA_DataBackoffTimer DataBackoffTimer;
FAMA_RemoteTimer RemoteTimer;
FAMA_CallBackHandler CallBack_Handler;
Time MaxPropDelay;
Time RTSTxTime;
Time CTSTxTime;
Time MaxDataTxTime;
queue<Packet*> PktQ_;
vector<nsaddr_t> NeighborList_;
set<FAMA_DataSendTimer*> DataSendTimerSet;
Event status_event;
Event callback_event;
packet_t UpperLayerPktType;
Packet* makeND(); //broadcast
Packet* makeRTS(nsaddr_t Recver);
Packet* makeCTS(nsaddr_t RTS_Sender);
void processND(Packet* pkt);
void processRTS(Packet* pkt);
void sendRTS(Time DeltaTime);
void sendPkt(Packet* pkt);
void sendDataPkt();
void processDataSendTimer(FAMA_DataSendTimer* DataSendTimer);
void processDataBackoffTimer();
void processRemoteTimer();
void StatusProcess();
void backoffProcess();
void CallbackProcess(Event* e);
Time getTxTimebyPktSize(int PktSize);
int getPktSizebyTxTime(Time TxTime);
bool CarrierDected();
void doBackoff();
void doRemote(Time DeltaTime);
friend class FAMA_BackoffTimer;
friend class FAMA_ND_Timer;
friend class FAMA_StatusHandler;
friend class FAMA_WaitCTSTimer;
friend class FAMA_DataSendTimer;
friend class FAMA_DataBackoffTimer;
friend class FAMA_RemoteTimer;
friend class FAMA_CallBackHandler;
};
#endif