logo资料库

SMAC 仿真源代码.doc

第1页 / 共10页
第2页 / 共10页
第3页 / 共10页
第4页 / 共10页
第5页 / 共10页
第6页 / 共10页
第7页 / 共10页
第8页 / 共10页
资料共10页,剩余部分请下载后查看
CHED_STATE_SLEEP)
// 开始竞争
// 开始竞争
13721449590 李燕茹 S-MAC 的实现主要继承于 BasicMac 类,而 BasicMac 主要继承于 cSimpleModule。此外, S-MAC 根据自己的算法,添加了一些与协议有关的函数。S-MAC 类定义如下: class SMac: public BasicMac { //构造,析构,模块 Module_Class_Members(SMac, BasicMac, 0); protected: unsigned int listen_time; unsigned int sleep_time; unsigned int frame_time; ushort sched_table[10]; // 邻居调度表 int sched_count; SchedStates sched_state; ushort time_last_sched; // 节点自身上次调度的时间 ProtoState proto_state; ProtoState proto_next_state; int nav_state; ushort nav_end_time; int must_send_sync; int resync_counter; Packet * tx_msg; int rts_contend_time; int cts_to; ushort cts_nav_end; ushort cts_nav_rcv; ushort cts_nav_t; int ack_to; int ack_serial; int my_serial; void setMySchedule(ushort time); // 产生自己的调度 void evalState(); // 检查状态 void startContending(int time); void sendSync(); void sendRts(); // 竞争,冲突避免 // 发送同步消息
// 接收同步消息 void sendCts(); void sendData(); void sendAck(); void receiveSync(Packet * msg); void receiveRts(Packet * msg); void receiveCts(Packet * msg); void receiveData(Packet * msg); void receiveAck(Packet * msg); void adoptSchedule(int offset); // 其他调度 void calcSchedState(); void setIdle(); // 重新计算调度状态 void protocolTimeout(); void navTimeout(); void schedTimeout(); void setProtocolTimeout(int t); void setNavTimeout(int t); void setSchedTimeout(int t); void updateNav(ushort nav); void txDone(); virtual void endForce(); int isSameSchedule(int time1, int time2); virtual int mustUseCA(Packet * msg); //virtual void incBackoff(); virtual void decBackoff(); virtual void init(); virtual void timeout(int which); virtual void txPacket(Packet * msg); virtual void rxFrame(Packet * msg); virtual void transmitDone(); virtual void rxFailed(); virtual void rxStarted(); virtual int headerLength(); }; S-MAC 协议的主要函数实现如下: 调度函数 void SMac::setMySchedule(ushort time) { // 在时间
assert(time < frame_time); time_last_sched = currentTime() + time - frame_time; // 计算自己的帧的调度时间 must_send_sync = 1; resync_counter = NEW_RESYNC_COUNTER; printf(PRINT_MAC, "schedule: %d", time_last_sched % frame_time); calcSchedState(); } 状态检查函数 void SMac::evalState() { if (proto_state == PROTO_STATE_IDLE && !isReceiving()) { // 空闲 if (nav_state == NAV_STATE_CLEAR && sched_state != CHED_STATE_SLEEP) { // 侦听 / 活动状态 if (must_send_sync) { printf(PRINT_MAC, "preparing to send SYNC %s",tx_msg?"(data pending)":""); // 开始竞争 proto_next_state = PROTO_STATE_SEND_SYNC; startContending(SYNC_CONTEND_TIME); return; } if (tx_msg && sched_state == SCHED_STATE_OWN) { if (mustUseCA(tx_msg)) //冲突避免 { printf(PRINT_MAC, "preparing to send RTS"); // 开始竞争 proto_next_state = PROTO_STATE_SEND_RTS; startContending(rts_contend_time); } else { printf(PRINT_MAC, "preparing to send data"); proto_next_state = PROTO_STATE_SEND_DATA; startContending(RTS_CONTEND_TIME); } return; }
// 只侦听 printf(PRINT_MAC, "idle listening"); setRadioListen(); // 睡眠状态 printf(PRINT_MAC, "idle sleeping"); if (getForce() != FORCE_NOSLEEP) setRadioSleep(); } else { } } } 竞争函数 void SMac::startContending(int time) { assert(proto_next_state >= 0); assert(time >= 5); if (nav_state == NAV_STATE_BUSY) { printf(PRINT_MAC, "contend: skipping because nav is busy"); proto_next_state = PROTO_STATE_INVALID; setIdle(); proto_state = PROTO_STATE_CONTEND; int ctime = (int) intuniform(5, time); printf(PRINT_MAC, "starting contention, will fire in %d", ctime); setRadioListen(); setProtocolTimeout(ctime); } else { } } 接收函数 void SMac::rxFrame(Packet * msg) { assert(msg); if (sched_state == SCHED_STATE_SLEEP && getForce()!=FORCE_NOSLEEP) return; // 睡眠中,放弃 if (proto_state == PROTO_STATE_WFCTS && (PKT_KIND(msg) != KIND_CTS || msg->local_to != nodeId())) {
printf(PRINT_MAC, "received packet, but not cts we want"); cancelTimeout(TIMER_PROTOCOL); proto_state = PROTO_STATE_IDLE; } if (proto_state == PROTO_STATE_WFACK && (PKT_KIND(msg) != KIND_ACK || msg->local_to != nodeId() || PKT_SERIAL(msg) != my_serial)) { } printf(PRINT_MAC, "received packet, but not ack we want"); cancelTimeout(TIMER_PROTOCOL); proto_state = PROTO_STATE_IDLE; assert(sched_state != SCHED_STATE_SLEEP || getForce() == FORCE_NOSLEEP); switch (PKT_KIND(msg)) { case KIND_SYNC: receiveSync(msg); break; case KIND_RTS: receiveRts(msg); break; case KIND_CTS: receiveCts(msg); break; case KIND_DATA: receiveData(msg); break; case KIND_ACK: receiveAck(msg); break; default: assert(false); } evalState(); } 协议超时处理函数 void SMac::protocolTimeout() { int next_state; switch (proto_state) { case PROTO_STATE_CONTEND:
assert(proto_next_state >= 0); assert(!isReceiving()); assert(nav_state == NAV_STATE_CLEAR); // RSSI 是接收信号强度指示 setRadioListen(); // 侦听信号 if(getRssi()>0.5) { // 有信号 printf(PRINT_MAC, "sensed communication, cancelling"); setIdle(); return; } // 启动下个状态 next_state = proto_next_state; proto_next_state = PROTO_STATE_INVALID; switch (next_state) { case PROTO_STATE_SEND_SYNC: sendSync(); break; case PROTO_STATE_SEND_RTS: sendRts(); break; case PROTO_STATE_SEND_CTS: sendCts(); break; case PROTO_STATE_SEND_DATA: sendData(); break; case PROTO_STATE_SEND_ACK: sendAck(); break; default: assert(false); } break; case PROTO_STATE_WFCTS: printf(PRINT_MAC, "wait-for-cts timeout"); setIdle(); break; case PROTO_STATE_WFDATA: printf(PRINT_MAC, "wait-for-data timeout"); setIdle(); break; case PROTO_STATE_WFACK:
printf(PRINT_MAC, "wait-for-ack timeout"); setIdle(); break; default: assert(false); } } 发送同步消息函数 void SMac::sendSync() { printf(PRINT_MAC, "sending sync"); must_send_sync = 0; proto_state = PROTO_STATE_SEND_SYNC; Packet *msg = new Packet("sync"); msg->local_from = nodeId(); msg->local_to = -1; //-1 表示广播 PKT_KIND(msg) = KIND_SYNC; ushort now = currentTime(); unsigned long est = EST_SYNC_TIME; assert(time_last_sched+(int)frame_time > now+EST_SYNC_TIME); unsigned long stime = time_last_sched + frame_time // 下一帧的时间 - now // 发送时延 - est; //- EST_SYNC_TIME; // 下一帧之前的时间 // 发送时延 //assert(now>900); assert(stime>0); stime &= 0xFFFF; assert(stime < frame_time); PKT_SYNC(msg) = stime; msg->setLength(SYNC_SIZE); setRadioTransmit(); reg_tx_overhead(msg); startTransmit(msg); } 接收同步消息函数 void SMac::receiveSync(Packet * msg) { assert(msg); reg_rx_overhead(msg);
ushort stime = (ushort) PKT_SYNC(msg); delete msg; if (sched_state == SCHED_STATE_STARTUP) { cancelTimeout(TIMER_SCHED); printf(PRINT_MAC, "received SYNC, following"); setMySchedule(stime); return; } // 检查偏移 int ftime = (int)currentTime() + stime; if (isSameSchedule(ftime, time_last_sched)) { // 帧启动时间 printf(PRINT_MAC, "received SYNC, my own schedule"); return; } // 检查其他调度 int i; for (i = 0; i < sched_count; i++) { if (isSameSchedule(ftime, time_last_sched + sched_table[i])) { printf(PRINT_MAC, "received SYNC, known schedule"); return; } } // 新的调度 printf(PRINT_MAC, "adopting foreign schedule"); int offset = ftime - time_last_sched; if (offset < 0) offset += 65536; offset %= frame_time; assert(offset > 0); //assert(offset < (int)frame_time); adoptSchedule(offset); } 计算调度状态函数 void SMac::calcSchedState() { ushort t = currentTime(); unsigned in_f = (ushort) (t - time_last_sched); assert(listen_time>0); // 检查是否在自己当前帧的发送时间内
分享到:
收藏