redmacp.nc
来自「tinyos-2.x.rar」· NC 代码 · 共 1,354 行 · 第 1/3 页
NC
1,354 行
message_t *m;
error_t e = error;
// sdDebug(50);
atomic {
m = txBufPtr;
txBufPtr = NULL;
txLen = 0;
#ifdef REDMAC_PERFORMANCE
txStat.repCounter = txMacHdr->repetitionCounter;
txStat.longRetry = longRetryCounter;
txStat.shortRetry = shortRetryCounter;
#endif
longRetryCounter = 0;
shortRetryCounter = 0;
storeStrength(m);
if(isFlagSet(&flags, CANCEL_SEND)) {
e = ECANCEL;
}
clearFlag(&flags, MESSAGE_PREPARED);
clearFlag(&flags, CANCEL_SEND);
}
// sdDebug(3000 + e);
// sdDebug(4000 + getHeader(m)->type);
signal MacSend.sendDone(m, e);
#ifdef REDMAC_PERFORMANCE
txStat.success = e;
txStat.strength = getMetadata(m)->strength;
call Performance.macTxMsgStats(&txStat);
#endif
}
void updateRetryCounters() {
shortRetryCounter++;
if(shortRetryCounter > MAX_SHORT_RETRY) {
longRetryCounter++;
shortRetryCounter = 1;
if(longRetryCounter > MAX_LONG_RETRY) {
// sdDebug(60);
signalSendDone(FAIL);
}
}
}
void updateLongRetryCounters() {
atomic {
clearFlag(&flags, MESSAGE_PREPARED);
longRetryCounter++;
shortRetryCounter = 1;
if(longRetryCounter > MAX_LONG_RETRY) {
// sdDebug(70);
signalSendDone(FAIL);
} else {
post PrepareMsgTask();
}
}
}
bool ackIsForMe(message_t* msg) {
uint8_t localToken = seqNo;
setFlag(&localToken, TOKEN_ACK_FLAG);
if((getHeader(msg)->dest == call amAddress()) && (localToken == getHeader(msg)->token)) return TRUE;
return FALSE;
}
void interruptBackoffTimer() {
if(call Timer.isRunning()) {
restLaufzeit = call TimeDiff16.computeDelta(call Timer.getAlarm(), call Timer.getNow());
call Timer.stop();
if(restLaufzeit > MIN_BACKOFF_MASK << MAX_LONG_RETRY) {
restLaufzeit = call Random.rand16() & ZERO_BACKOFF_MASK;
}
setFlag(&flags, RESUME_BACKOFF);
}
}
void computeBackoff() {
if(!isFlagSet(&flags, RESUME_BACKOFF)) {
setFlag(&flags, RESUME_BACKOFF);
restLaufzeit = backoff(longRetryCounter);
updateRetryCounters();
}
}
bool msgIsForMe(message_t* msg) {
if(getHeader(msg)->dest == AM_BROADCAST_ADDR) return TRUE;
if(getHeader(msg)->dest == call amAddress()) return TRUE;
if(getHeader(msg)->dest >= RELIABLE_MCAST_MIN_ADDR) return TRUE;
return FALSE;
}
bool isControl(message_t* m) {
uint8_t token = getHeader(m)->token;
return isFlagSet(&token, TOKEN_ACK_FLAG);
}
bool isNewMsg(message_t* msg) {
return call Duplicate.isNew(getHeader(msg)->src,
getHeader(msg)->dest,
(getHeader(msg)->token) & TOKEN_ACK_MASK);
}
void rememberMsg(message_t* msg) {
call Duplicate.remember(getHeader(msg)->src, getHeader(msg)->dest,
(getHeader(msg)->token) & TOKEN_ACK_MASK);
}
void prepareAck(message_t* msg) {
uint8_t rToken = getHeader(msg)->token & TOKEN_ACK_MASK;
setFlag(&rToken, TOKEN_ACK_FLAG);
getHeader(&ackMsg)->token = rToken;
getHeader(&ackMsg)->src = call amAddress();
getHeader(&ackMsg)->dest = getHeader(msg)->src;
getHeader(&ackMsg)->type = getHeader(msg)->type;
#ifdef REDMAC_DEBUG
repCounter = ((red_mac_header_t *)
call SubPacket.getPayload(msg, sizeof(red_mac_header_t)))->repetitionCounter;
#endif
}
uint32_t calcGeneratedTime(red_mac_header_t *m) {
uint32_t lt = rxTime - m->time - TIME_CORRECTION;
#ifdef DELTATIMEDEBUG
dTrace.now = rxTime;
dTrace.msgTime = lt;
dTrace.delta = m->time;
call DeltaTrace.traceRx(&dTrace);
#endif
return lt;
}
/**************** Init ************************/
command error_t Init.init(){
atomic {
macState = INIT;
seqNo = call Random.rand16() % TOKEN_ACK_FLAG;
for(MIN_BACKOFF_MASK = 1; MIN_BACKOFF_MASK < networkSleeptime; ) {
MIN_BACKOFF_MASK = (MIN_BACKOFF_MASK << 1) + 1;
}
MIN_BACKOFF_MASK >>= 2;
}
#ifdef REDMAC_DEBUG
call SerialDebug.putShortDesc("RedMacP");
#endif
return SUCCESS;
}
/**************** SplitControl *****************/
task void StartDoneTask() {
// sdDebug(90);
atomic {
call SampleTimer.start(localSleeptime);
macState = SLEEP;
setFlag(&flags, TEAMGEIST_ACTIVE);
teamgeistType = signal Teamgeist.observedAMType();
}
signal SplitControl.startDone(SUCCESS);
}
command error_t SplitControl.start() {
call CcaStdControl.start();
atomic {
macState = INIT;
setRxMode();
// sdDebug(100);
}
return SUCCESS;
}
task void StopDoneTask() {
call Init.init();
// sdDebug(110);
signal SplitControl.stopDone(SUCCESS);
}
command error_t SplitControl.stop() {
call CcaStdControl.stop();
call Timer.stop();
call SampleTimer.stop();
atomic {
if((macState == SLEEP) && isFlagSet(&flags, SWITCHING)) {
macState = STOP;
// sdDebug(120);
}
else {
macState = STOP;
setSleepMode();
// sdDebug(121);
}
}
return SUCCESS;
}
/****** Packet interface ********************/
command void Packet.clear(message_t* msg) {
call SubPacket.clear(msg);
}
command uint8_t Packet.payloadLength(message_t* msg) {
return call SubPacket.payloadLength(msg) - sizeof(red_mac_header_t);
}
command void Packet.setPayloadLength(message_t* msg, uint8_t len) {
call SubPacket.setPayloadLength(msg,len + sizeof(red_mac_header_t));
}
command uint8_t Packet.maxPayloadLength() {
return call SubPacket.maxPayloadLength() - sizeof(red_mac_header_t);
}
command void* Packet.getPayload(message_t* msg, uint8_t len) {
nx_uint8_t *payload = (nx_uint8_t *)call SubPacket.getPayload(msg, len + sizeof(red_mac_header_t));
return (void*)(payload + sizeof(red_mac_header_t));
}
/****** Radio(Mode) events *************************/
async event void RadioModes.RssiStable() {
setFlag(&flags, RSSI_STABLE);
if((macState == RX) || (macState == CCA)) {
call Timer.start(DATA_DETECT_TIME);
// sdDebug(130);
}
else if(macState == RX_P) {
// sdDebug(131);
if(call RssiAdcResource.isOwner()) call ChannelMonitorData.getSnr();
}
else if(macState == RX_ACK) {
}
else if(macState == RX_ACK_P) {
}
else if(macState == INIT) {
// sdDebug(133);
if(call RssiAdcResource.isOwner()) {
call ChannelMonitorControl.updateNoiseFloor();
} else {
call RssiAdcResource.request();
}
}
else if(macState == STOP) {
// sdDebug(134);
}
else {
// sdDebug(135);
}
}
async event void RadioModes.RxModeDone() {
atomic {
clearFlag(&flags, SWITCHING);
if((macState == RX) || (macState == RX_ACK) || (macState == CCA) ||
(macState == INIT) || (macState == STOP)) {
// sdDebug(140);
if(macState != RX_ACK) requestAdc();
}
else {
// sdDebug(141);
}
}
}
async event void RadioModes.TxModeDone() {
// sdDebug(150);
atomic {
clearFlag(&flags, SWITCHING);
if(macState == TX) {
setFlag(&flags, ACTION_DETECTED);
if(call PacketSend.send(txBufPtr, txLen) == SUCCESS) {
// sdDebug(151);
}
else {
// sdDebug(152);
}
}
else if(macState == TX_ACK) {
if(call PacketSend.send(&ackMsg, 0) == SUCCESS) {
// sdDebug(153);
} else {
// sdDebug(154);
}
}
else {
// sdDebug(155);
}
}
}
async event void RadioModes.SleepModeDone() {
// sdDebug(160);
atomic {
clearFlag(&flags, SWITCHING);
if(isFlagSet(&flags, ACTION_DETECTED)) {
if(congestionLevel < 5) congestionLevel++;
} else {
if(congestionLevel > 0) congestionLevel--;
}
// if(congestionLevel > 3) // sdDebug(2000 + congestionLevel);
if(macState == SLEEP) {
// sdDebug(161);
if(!call Timer.isRunning()) {
// sdDebug(162);
if(isFlagSet(&flags, RESUME_BACKOFF)) {
// sdDebug(164);
clearFlag(&flags, RESUME_BACKOFF);
call Timer.start(restLaufzeit);
restLaufzeit = 0;
}
else {
// sdDebug(165);
checkSend();
}
}
}
else if(macState == STOP) {
// sdDebug(168);
post StopDoneTask();
}
signal ChannelCongestion.congestionEvent(congestionLevel);
}
}
/****** MacSend events *************************/
async command error_t MacSend.send(message_t* msg, uint8_t len) {
error_t err = SUCCESS;
atomic {
if((shortRetryCounter == 0) && (txBufPtr == NULL)) {
clearFlag(&flags, MESSAGE_PREPARED);
// sdDebug(5000 + getHeader(msg)->type);
shortRetryCounter = 1;
longRetryCounter = 1;
txBufPtr = msg;
txLen = len + sizeof(red_mac_header_t);
seqNo++;
if(seqNo >= TOKEN_ACK_FLAG) seqNo = 1;
#ifdef REDMAC_PERFORMANCE
txStat.payloadLength = txLen;
txStat.interfaceTime = call LocalTime32kHz.get();
#endif
}
else {
// sdDebug(171);
err = EBUSY;
}
}
if(err == SUCCESS) {
post PrepareMsgTask();
}
return err;
}
async command error_t MacSend.cancel(message_t* msg) {
error_t err = FAIL;
atomic {
if(msg == txBufPtr) {
// sdDebug(320);
setFlag(&flags, CANCEL_SEND);
shortRetryCounter = MAX_SHORT_RETRY + 2;
longRetryCounter = MAX_LONG_RETRY + 2;
if(macState == SLEEP) {
// sdDebug(321);
signalSendDone(ECANCEL);
}
else {
// sdDebug(322);
}
// sdDebug(1000 + macState);
err = SUCCESS;
}
else {
// sdDebug(323);
// sdDebug(1100 + macState);
}
}
return err;
}
/****** PacketSerializer events **********************/
async event void PacketReceive.receiveDetected() {
rssiValue = INVALID_SNR;
setFlag(&flags, ACTION_DETECTED);
call ChannelMonitor.rxSuccess();
if(macState <= CCA_ACK) {
if(macState == CCA) {
computeBackoff();
#ifdef REDMAC_PERFORMANCE
call Performance.macDetectedOnCca();
#endif
}
if(macState != RX_ACK) {
macState = RX_P;
} else {
macState = RX_ACK_P;
}
}
else if(macState == INIT) {
// sdDebug(180);
setFlag(&flags, UNHANDLED_PACKET);
}
}
async event message_t* PacketReceive.receiveDone(message_t* msg, void* payload, uint8_t len, error_t error) {
message_t *m = msg;
macState_t action = STOP;
uint32_t nav = 0;
uint8_t level = 0;
bool isCnt;
#ifdef REDMAC_PERFORMANCE
rxStat.duplicate = PERF_UNKNOWN;
rxStat.repCounter = 0xff;
#endif
// sdDebug(190);
if(macState == RX_P) {
// sdDebug(191);
if(error == SUCCESS) {
// sdDebug(192);
isCnt = isControl(msg);
if(msgIsForMe(msg)) {
if(!isCnt) {
// sdDebug(193);
if(isNewMsg(msg)) {
#ifdef REDMAC_PERFORMANCE
rxStat.duplicate = PERF_NEW_MSG;
#endif
// sdDebug(194);
storeStrength(msg);
#ifdef DELTATIMEDEBUG
dTrace.sender = getHeader(msg)->src;
#endif
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) {
// sdDebug(195);
rememberMsg(msg);
} else {
// sdDebug(196);
action = RX;
#ifdef REDMAC_PERFORMANCE
call Performance.macQueueFull();
#endif
}
}
else {
#ifdef REDMAC_PERFORMANCE
rxStat.duplicate = PERF_REPEATED_MSG;
#endif
}
if(needsAckRx(msg, &level) && (action != RX)) {
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?