无线传感网络中的SMAC编程代码.docx
《无线传感网络中的SMAC编程代码.docx》由会员分享,可在线阅读,更多相关《无线传感网络中的SMAC编程代码.docx(94页珍藏版)》请在冰豆网上搜索。
无线传感网络中的SMAC编程代码
/*
*smac.cc
*Copyright(C)2000bytheUniversityofSouthernCalifornia
*$Id:
smac.cc,v1.182005/12/1017:
57:
13liyuanExp$
*
*Thisprogramisfreesoftware;youcanredistributeitand/or
*modifyitunderthetermsoftheGNUGeneralPublicLicense,
*version2,aspublishedbytheFreeSoftwareFoundation.
*
*Thisprogramisdistributedinthehopethatitwillbeuseful,
*butWITHOUTANYWARRANTY;withouteventheimpliedwarrantyof
*MERCHANTABILITYorFITNESSFORAPARTICULARPURPOSE.Seethe
*GNUGeneralPublicLicenseformoredetails.
*
*YoushouldhavereceivedacopyoftheGNUGeneralPublicLicensealong
*withthisprogram;ifnot,writetotheFreeSoftwareFoundation,Inc.,
*59TemplePlace,Suite330,Boston,MA02111-1307,USA.
*
*
*Thecopyrightofthismoduleincludesthefollowing
*linking-with-specific-other-licensesaddition:
*
*Inaddition,asaspecialexception,thecopyrightholdersof
*thismodulegiveyoupermissiontocombine(viastaticor
*dynamiclinking)thismodulewithfreesoftwareprogramsor
*librariesthatarereleasedundertheGNULGPLandwithcode
*includedinthestandardreleaseofns-2undertheApache2.0
*licenseorunderotherwise-compatiblelicenseswithadvertising
*requirements(ormodifiedversionsofsuchcode,withunchanged
*license).Youmaycopyanddistributesuchasystemfollowingthe
*termsoftheGNUGPLforthismoduleandthelicensesofthe
*othercodeconcerned,providedthatyouincludethesourcecodeof
*thatothercodewhenandastheGNUGPLrequiresdistributionof
*sourcecode.
*
*Notethatpeoplewhomakemodifiedversionsofthismodule
*arenotobligatedtograntthisspecialexceptionfortheir
*modifiedversions;itistheirchoicewhethertodoso.TheGNU
*GeneralPublicLicensegivespermissiontoreleaseamodified
*versionwithoutthisexception;thisexceptionalsomakesit
*possibletoreleaseamodifiedversionwhichcarriesforwardthis
*exception.
*
*/
//smacisdesignedanddevelopedbyWeiYe(SCADDS/ISI)
//andisre-writtenfornsbyPadmaHaldar(CONSER/ISI).
//Contributors:
YuanLi
//ThismoduleimplementsSensor-MAC
//http:
//www.isi.edu/scadds/papers/smac_report.pdf
//
//Ithasthefollowingfunctions.
//1)Bothvirtualandphysicalcarriersense
//2)RTS/CTSforhiddenterminalproblem
//3)Backoffandretry
//4)BroadcastpacketsaresentdirectlywithoutusingRTS/CTS/ACK.
//5)AlongunicastmessageisdividedintomultipleTOS_MSG(byupper
//layer).TheRTS/CTSreservesthemediumfortheentiremessage.
//ACKisusedforeachTOS_MSGforimmediateerrorrecovery.
//6)Nodegoestosleepwhenitsneighboriscommunicatingwithanother
//node.
//7)Eachnodefollowsaperiodiclisten/sleepschedule
//8.1)AtbootuptimeeachnodelistensforafixedSYNCPERIODandthen
//triestosendoutasyncpacket.Itsuppressessendingoutofsyncpkt
//ifithappenstoreceiveasyncpktfromaneighborandfollowsthe
//neighbor'sschedule.
//8.2)Oranodecanchooseitsownscheculeinsteadoffollowingothers,the
//schedulestarttimeisuserconfigurable
//9)NeighborDiscovery:
inordertopreventthattwoneighborscannot
//findeachotherduetofollowingcompletedifferentschedules,each
//nodeperiodicallylistenforawholeperiodoftheSYNCPERIOD
//10)Dutycycleisuserconfigurable
//Newfeaturesincludingadaptivelisten
//Seehttp:
//www.isi.edu/~weiye/pub/smac_ton.pdf
#include"wireless-phy.h"
#include"smac.h"
staticclassMacSmacClass:
publicTclClass{
public:
MacSmacClass():
TclClass("Mac/SMAC"){}
TclObject*create(int,constchar*const*){
return(newSMAC());
}
}class_macSMAC;//创建MacSmacClass:
publicTclClass
//Timerscallonexpiration
intSmacTimer:
:
busy()
{
if(status_!
=TIMER_PENDING)
return0;
else
return1;
}//定义busy()
#ifdefJOURNAL_PAPER
voidSmacUpdateNeighbTimer:
:
expire(Event*e){
a_->handleUpdateNeighbTimer();
}//用于阶段更新邻居表的定时器
voidSmacAdaptiveListenTimer:
:
expire(Event*e){
a_->handleAdaptiveListenTimer();
}
#endif//在自适应侦听后用于让节点进入睡眠的定时器
voidSmacGeneTimer:
:
expire(Event*e){
a_->handleGeneTimer();
}//一般的时间用于sync,CTSandACK的超时设定
voidSmacRecvTimer:
:
expire(Event*e){
stime_=rtime_=0;
a_->handleRecvTimer();
}//用于接收数据包的接收定时器中的超时设定
voidSmacRecvTimer:
:
sched(doubletime){
TimerHandler:
:
sched(time);
stime_=Scheduler:
:
instance().clock();
rtime_=time;
}//用于接收数据包的接收定时器中的接收时间段
voidSmacRecvTimer:
:
resched(doubletime){
TimerHandler:
:
resched(time);
stime_=Scheduler:
:
instance().clock();
rtime_=time;
}//用于接收数据包的接收定时器中的二次接收时间段
doubleSmacRecvTimer:
:
timeToExpire(){
return((stime_+rtime_)-Scheduler:
:
instance().clock());
}//用于接收数据包的接收定时器中的剩余接收时间定时器
voidSmacSendTimer:
:
expire(Event*e){
a_->handleSendTimer();
}//用于发送数据包的发送定时器中的超时设定
voidSmacNavTimer:
:
expire(Event*e){
a_->handleNavTimer();
}//用于NAV的定时器设定
voidSmacNeighNavTimer:
:
sched(doubletime){
TimerHandler:
:
sched(time);
stime_=Scheduler:
:
instance().clock();
rtime_=time;
}//用于显示邻居节点信道的NAV定时器的时间段
voidSmacNeighNavTimer:
:
expire(Event*e){
stime_=rtime_=0;
a_->handleNeighNavTimer();
}//用于邻居节点NAV定时器的超时设定
doubleSmacNeighNavTimer:
:
timeToExpire(){
return((stime_+rtime_)-Scheduler:
:
instance().clock());
}//用于邻居节点NAV定时器的剩余到期设定
voidSmacCsTimer:
:
expire(Event*e){
a_->handleCsTimer();
}//用于载波侦听的定时器
//ifpending,canceltimer
voidSmacCsTimer:
:
checkToCancel(){
if(status_==TIMER_PENDING)
cancel();
}
//voidSmacChkSendTimer:
:
expire(Event*e){
//a_->handleChkSendTimer();
//}
//同步定时器,用于控制睡眠/唤醒周期
voidSmacCounterTimer:
:
sched(doubletime){
//thecycletimerassumesthatalltimeshallbescheduledwithtime"lefttosleep"
//andnottheabsolutetimeforagivenstate(sleep,syncordata).Thusinorder
//toscheduleforasleepstate,needtoschedulewithaggregatetimeCYCLETIME
//(sleeptime+synctime+dadatime).
//Similarlyforsyncstate,schedulewithlistenTime_(synctime+datattime)
//Thisisimplementedtobeinstepwiththecounterusedinactualsmac.
//周期时间设定所有的时间器应该用进入睡眠剩余时间定义,而不是确定状态下的绝对时间(睡眠,同步,数据)。
因此为了对睡眠状态进行预订,需要
//确定周期(sleeptime+synctime+dadatime)的和。
//同样对于同步状态也是如此,这样做是为了SMAC中节点的计数器一致。
tts_=time;//timebeforeitgoestosleepagain
stime_=Scheduler:
:
instance().clock();
if(time<=CLKTICK2SEC(cycleTime_)&&time>CLKTICK2SEC(listenTime_)){//insleepstate
value_=sleepTime_;
if(status_==TIMER_IDLE)
TimerHandler:
:
sched(time-CLKTICK2SEC(listenTime_));
else
TimerHandler:
:
resched(time-CLKTICK2SEC(listenTime_));对sched和resched理解不清楚
}elseif(time<=CLKTICK2SEC(listenTime_)&&time>CLKTICK2SEC(dataTime_)){//insyncstate
value_=syncTime_;
if(status_==TIMER_IDLE)
TimerHandler:
:
sched(time-CLKTICK2SEC(dataTime_));
else
TimerHandler:
:
resched(time-CLKTICK2SEC(dataTime_));
}else{//indatastate
assert(time<=CLKTICK2SEC(dataTime_));//其作用是如果它的条件返回错误,则终止程序执行,原型定义
value_=dataTime_;
if(status_==TIMER_IDLE)
TimerHandler:
:
sched(time);
else
TimerHandler:
:
resched(time);
}
}
doubleSmacCounterTimer:
:
timeToSleep(){
return((stime_+tts_)-Scheduler:
:
instance().clock());
}//进入睡眠的剩余时间定时器
voidSmacCounterTimer:
:
expire(Event*e){
tts_=stime_=0;
a_->handleCounterTimer(index_);
}//同步定时器超时设定
#ifdefJOURNAL_PAPER
SMAC:
:
SMAC():
Mac(),mhUpdateNeighb_(this),mhNav_(this),mhNeighNav_(this),mhSend_(this),mhRecv_(this),mhGene_(this),mhCS_(this),mhAdap_(this),syncFlag_(0){
inti;
#else
SMAC:
:
SMAC():
Mac(),mhNav_(this),mhNeighNav_(this),mhSend_(this),mhRecv_(this),mhGene_(this),mhCS_(this),syncFlag_(0){
#endif
state_=IDLE;
radioState_=RADIO_IDLE;
tx_active_=0;
mac_collision_=0;
sendAddr_=-1;
recvAddr_=-1;
nav_=0;
neighNav_=0;
numRetry_=0;
numExtend_=0;
lastRxFrag_=-3;//since-1,-2and0couldbevalidpktuid's
//numFrags_=0;
//succFrags_=0;
#ifdefJOURNAL_PAPER
numFrags_=0;
succFrags_=0;
dataSched_=0;
syncSched_=0;
globalSchedule_=0;//Donottestglobalschedule
//globalSchedule_=1;//Testglobalschedule
updateNeighbList_=0;
sendSYNCFlag_=0;
sendAddr=-1;
adapSend_=0;
txRequest_=0;
adaptiveListen_=0;
#endif
dataPkt_=0;
pktRx_=0;
pktTx_=0;
/*setupinternalmacandphysicalparameters
----------------------------------------------
byte_tx_time_:
timetotransmitabyte,inms.Derivedfrombandwidth
slotTime_:
timeofeachslotincontentionwindow.Itshouldbelarge
enoughtoreceivethewholestartsymbolbutcannotbesmallerthanclock
resolution.inmsec
slotTime_sec_:
slottimeinsec
difs_:
DCFinterframespace(from802.11),inms.Itisusedatthebeginning
ofeachcontentionwindow.It'stheminmumtimetowaittostartanew
transmission.(DistributedCoordinationFunction)
sifs_:
shortinterframespace(f
/rom802.11),inms.Itisusedbeforesending
anCTSorACKpacket.Ittakescareoftheprocessingdelayofeachpkt.
eifs_:
Entendedinterfranespace(from802.11)inms.Usedforbackingoff
incaseofacollision.
guardTime_:
guardtimeattheendofeachlisteninterval,inms.
*/
byte_tx_time_=8.0/BANDWIDTH;
doublestart_symbol=byte_tx_time_*2.5;//timetotx20bits
slotTime_=CLOCKRES>=start_symbol?
CLOCKRES:
start_symbol;//inmsec
slotTime_sec_=slotTime_/1.0e3;//insec
difs_=10.0*slotTime_;
sifs_=5.0*slotTime_;
eifs_=50.0*slotTime_;
guardTime_=4.0*slotTime_;
//calculatepacketduration.Followingequationsassume4b/6bcod