speckmacdp.nc
来自「tinyos-2.x.rar」· NC 代码 · 共 1,172 行 · 第 1/3 页
NC
1,172 行
#endif
if(macState == RX_P) {
if(error == SUCCESS) {
isCnt = isControl(msg);
if(msgIsForMe(msg)) {
if(!isCnt) {
if(isNewMsg(msg)) {
#ifdef SPECKMAC_PERFORMANCE
rxStat.duplicate = PERF_NEW_MSG;
#endif
storeStrength(msg);
getMetadata(msg)->sfdtime = rxTime;
getMetadata(msg)->time = calcGeneratedTime((red_mac_header_t*) payload);
getMetadata(msg)->ack = WAS_NOT_ACKED;
m = signal MacReceive.receiveDone(msg);
// assume a buffer swap -- if buffer is not swapped, assume that the
// message was not successfully delivered to upper layers
if(m != msg) {
rememberMsg(msg);
} else {
action = RX;
#ifdef SPECKMAC_PERFORMANCE
call Performance.macQueueFull();
#endif
}
}
#ifdef SPECKMAC_PERFORMANCE
else {
rxStat.duplicate = PERF_REPEATED_MSG;
}
#endif
if(needsAckRx(msg) && (action != RX)) {
if(((red_mac_header_t*)payload)->repetitionCounter == 0) {
action = CCA_ACK;
}
else {
action = RX;
}
}
else {
if(action != RX) {
nav = ((red_mac_header_t*)payload)->repetitionCounter *
(SUB_HEADER_TIME + getHeader(msg)->length*BYTE_TIME +
SUB_FOOTER_TIME) + RX_ACK_TIMEOUT + TX_SETUP_TIME + ACK_DURATION;
action = SLEEP;
}
}
}
else {
action = RX;
}
}
else {
action = SLEEP;
if(!isCnt) {
nav = ((red_mac_header_t*)payload)->repetitionCounter *
(SUB_HEADER_TIME + getHeader(msg)->length*BYTE_TIME +
SUB_FOOTER_TIME) + RX_ACK_TIMEOUT + TX_SETUP_TIME + ACK_DURATION;
}
}
}
else {
action = SLEEP;
}
}
else if(macState == RX_ACK_P) {
if(error == SUCCESS) {
if(ackIsForMe(msg)) {
storeStrength(msg);
getMetadata(txBufPtr)->ack = WAS_ACKED;
getMetadata(txBufPtr)->repetitions = txMacHdr->repetitionCounter;
signalSendDone(SUCCESS);
action = SLEEP;
}
else {
updateLongRetryCounters(); // this will eventually schedule the right backoff
macState = SLEEP; // so much traffic is going on -- take a nap
setSleepMode();
action = INIT; // a difficult way to say: do nothing
}
}
else {
if(call Timer.isRunning()) {
action = RX_ACK;
}
else {
updateLongRetryCounters();
action = RX;
}
}
}
else {
action = INIT;
}
if(action == CCA_ACK) {
macState = TX_ACK;
call Timer.start(RX_SETUP_TIME - TX_SETUP_TIME + 16);
prepareAck(msg);
}
else if(action == RX_ACK) {
macState = RX_ACK;
}
else if(action == RX) {
macState = RX;
checkCounter = 0;
call Timer.start(DATA_DETECT_TIME);
}
else if(action == SLEEP) {
macState = SLEEP;
if(isFlagSet(&flags, RESUME_BACKOFF)) {
if(nav > restLaufzeit) {
if(nav > restLaufzeit) restLaufzeit += ((uint32_t)ADD_NAV*nav/NAV_FACTOR);
}
}
else {
setFlag(&flags, RESUME_BACKOFF);
restLaufzeit = call Random.rand16() & ZERO_BACKOFF_MASK;
}
setSleepMode();
}
else if(action == INIT) {
clearFlag(&flags, UNHANDLED_PACKET);
}
else {
}
#ifdef SPECKMAC_PERFORMANCE
if(error == SUCCESS) {
rxStat.type = getHeader(msg)->type;
rxStat.from = getHeader(msg)->src;
rxStat.to = getHeader(msg)->dest;
rxStat.token = getHeader(msg)->token;
if(!isControl(msg)) rxStat.repCounter = ((red_mac_header_t*)payload)->repetitionCounter;
rxStat.payloadLength = len;
rxStat.strength = rssiValue;
rxStat.creationTime = getMetadata(msg)->time;
call Performance.macRxStats(&rxStat);
}
#endif
return m;
}
async event void PacketSend.sendDone(message_t* msg, error_t error) {
if(macState == TX) {
if(prepareRepetition()) {
call PacketSend.send(txBufPtr, txLen);
}
else {
macState = RX_ACK;
setRxMode();
call Timer.start(RX_ACK_TIMEOUT);
checkCounter = 0;
}
}
else if(macState == TX_ACK) {
checkCounter = 0;
macState = RX;
setRxMode();
#ifdef SPECKMAC_DEBUG
#endif
}
}
/***** TimeStamping stuff **************************/
async event void RadioTimeStamping.receivedSFD( uint16_t time ) {
if(call RssiAdcResource.isOwner()) call ChannelMonitorData.getSnr();
if(macState == RX_P) {
rxTime = call LocalTime32kHz.get();
call ChannelMonitor.rxSuccess();
}
}
async event void RadioTimeStamping.transmittedSFD(uint16_t time, message_t* p_msg ) {
if((macState == TX) && (p_msg == txBufPtr)) {
getMetadata(p_msg)->sfdtime = call LocalTime32kHz.get();
txMacHdr->time =
call TimeDiff32.computeDelta(getMetadata(p_msg)->sfdtime,
getMetadata(p_msg)->time);
}
}
/****** Timer ******************************/
void checkOnBusy() {
setFlag(&flags, ACTION_DETECTED);
if((macState == RX) || (macState == CCA) || (macState == CCA_ACK)) {
if(macState == CCA) {
computeBackoff();
#ifdef SPECKMAC_PERFORMANCE
call Performance.macBusyOnCca();
#endif
}
requestAdc();
macState = RX;
checkCounter = 0;
call Timer.start(TX_GAP_TIME>>1);
}
}
void checkOnIdle() {
if(macState == RX) {
checkCounter++;
if(checkCounter < 2) {
call Timer.start(DATA_DETECT_TIME);
requestAdc();
} else {
macState = SLEEP;
setSleepMode();
}
}
else if(macState == CCA) {
checkCounter++;
if(checkCounter < 3) {
call Timer.start(TX_GAP_TIME >> 1);
requestAdc();
}
else {
macState = TX;
setTxMode();
#ifdef SPECKMAC_PERFORMANCE
call Performance.macIdleOnCca();
txStat.txModeTime = call LocalTime32kHz.get();
#endif
}
}
}
async event void Timer.fired() {
if((macState == RX) || (macState == CCA) || (macState == CCA_ACK)) {
if((!call RssiAdcResource.isOwner()) || (call ChannelMonitor.start() != SUCCESS)) {
if(call UartPhyControl.isBusy()) {
checkOnBusy();
}
else {
checkOnIdle();
}
}
}
else if(macState == RX_ACK) {
if(needsAckTx(txBufPtr)) {
#ifdef SPECKMAC_PERFORMANCE
call Performance.macAckTimeout();
#endif
updateLongRetryCounters();
}
else {
signalSendDone(SUCCESS);
}
macState = SLEEP;
setSleepMode();
}
else if(macState == TX_ACK) {
setTxMode();
}
else if(macState == SLEEP) {
if(isFlagSet(&flags, SWITCHING)) {
call Timer.start(call Random.rand16() & 0x0f);
}
else {
if(isFlagSet(&flags, RESUME_BACKOFF)) {
clearFlag(&flags, RESUME_BACKOFF);
call Timer.start(restLaufzeit);
restLaufzeit = 0;
}
else {
checkSend();
}
}
}
else if((macState == RX_ACK_P) || (macState == RX_P)) {
}
else if(macState == INIT) {
post StartDoneTask();
sdDebug(50);
}
else {
}
}
/****** SampleTimer ******************************/
async event void SampleTimer.fired() {
call SampleTimer.start(localSleeptime);
if((macState == SLEEP) && (!isFlagSet(&flags, SWITCHING))) {
clearFlag(&flags, ACTION_DETECTED);
interruptBackoffTimer();
macState = RX;
setRxMode();
call Timer.stop();
}
}
/***** Sleeptime **********************************/
async command void Sleeptime.setLocalSleeptime(uint16_t sT) {
atomic localSleeptime = sT;
}
async command uint16_t Sleeptime.getLocalSleeptime() {
uint16_t st;
atomic st = localSleeptime;
return st;
}
async command void Sleeptime.setNetworkSleeptime(uint16_t sT) {
atomic {
networkSleeptime = sT;
for(MIN_BACKOFF_MASK = 1; MIN_BACKOFF_MASK < sT; ) {
MIN_BACKOFF_MASK = (MIN_BACKOFF_MASK << 1) + 1;
}
MIN_BACKOFF_MASK >>= 3;
}
}
async command uint16_t Sleeptime.getNetworkSleeptime() {
uint16_t st;
atomic st = networkSleeptime;
return st;
}
/****** ChannelMonitor events *********************/
async event void ChannelMonitor.channelBusy() {
checkOnBusy();
}
async event void ChannelMonitor.channelIdle() {
checkOnIdle();
}
/****** ChannelMonitorControl events **************/
event void ChannelMonitorControl.updateNoiseFloorDone() {
if(macState == INIT) {
call Timer.start(call Random.rand16() % localSleeptime);
setSleepMode();
sdDebug(40);
} else {
}
}
/***** ChannelMonitorData events ******************/
async event void ChannelMonitorData.getSnrDone(int16_t data) {
atomic if((macState == RX_P) || (macState == RX_ACK_P)) rssiValue = data;
}
/***** Rssi Resource events ******************/
event void RssiAdcResource.granted() {
macState_t ms;
atomic ms = macState;
if(ms < SLEEP) {
}
else if(ms == INIT) {
sdDebug(30);
call ChannelMonitorControl.updateNoiseFloor();
}
else {
post ReleaseAdcTask();
}
}
/***** Mac Eval *******************************************/
#ifdef MAC_EVAL
async command void MacEval.setBackoffMask(uint16_t mask) {
atomic MIN_BACKOFF_MASK = mask;
}
async command void MacEval.increaseBackoff(bool value) {
atomic INCREASE_BACKOFF = value;
}
async command void MacEval.addNav(bool value) {
atomic ADD_NAV = value;
}
async command void MacEval.setLongRetry(uint8_t lr) {
atomic MAX_LONG_RETRY = lr;
}
async command void MacEval.setShortRetry(uint8_t sr) {
atomic MAX_SHORT_RETRY = sr;
}
#endif
/***** unused events **************************/
default async event void ChannelCongestion.congestionEvent(uint8_t level) {}
/***** unused Radio Modes events **************************/
async event void RadioModes.TimerModeDone() {}
async event void RadioModes.SelfPollingModeDone() {}
async event void RadioModes.PWDDDInterrupt() {}
}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?