speckmacdp.nc
来自「tinyos-2.x.rar」· NC 代码 · 共 1,172 行 · 第 1/3 页
NC
1,172 行
if(call RssiAdcResource.isOwner()) {
(getMetadata(m))->strength = call ChannelMonitorData.readSnr();
}
else {
(getMetadata(m))->strength = 1;
}
}
}
bool prepareRepetition() {
bool repeat;
atomic {
if(isFlagSet(&flags, CANCEL_SEND)) {
repeat = txMacHdr->repetitionCounter = 0;
}
else {
repeat = txMacHdr->repetitionCounter;
txMacHdr->repetitionCounter--;
}
}
return repeat;
}
void signalSendDone(error_t error) {
message_t *m;
error_t e = error;
atomic {
m = txBufPtr;
txBufPtr = NULL;
txLen = 0;
#ifdef SPECKMAC_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);
}
signal MacSend.sendDone(m, e);
#ifdef SPECKMAC_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) {
signalSendDone(FAIL);
}
}
}
void updateLongRetryCounters() {
atomic {
clearFlag(&flags, MESSAGE_PREPARED);
longRetryCounter++;
shortRetryCounter = 1;
if(longRetryCounter > MAX_LONG_RETRY) {
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 SPECKMAC_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) {
return rxTime - m->time - TIME_CORRECTION;
}
/**************** 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;
if(MIN_BACKOFF_MASK < 0x3ff) MIN_BACKOFF_MASK=0x3ff;
}
#ifdef SPECKMAC_DEBUG
call SerialDebug.putShortDesc("SpeckMacP");
#endif
return SUCCESS;
}
/**************** SplitControl *****************/
task void StartDoneTask() {
atomic {
call SampleTimer.start(localSleeptime);
macState = SLEEP;
sdDebug(60);
}
signal SplitControl.startDone(SUCCESS);
}
command error_t SplitControl.start() {
call CcaStdControl.start();
atomic {
macState = INIT;
setRxMode();
}
sdDebug(10);
return SUCCESS;
}
task void StopDoneTask() {
call Init.init();
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;
}
else {
macState = STOP;
setSleepMode();
}
}
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);
}
else if(macState == RX_P) {
if(call RssiAdcResource.isOwner()) call ChannelMonitorData.getSnr();
}
else if(macState == RX_ACK) {
// if(call RssiAdcResource.isOwner()) call ChannelMonitor.start();
}
else if(macState == RX_ACK_P) {
}
else if(macState == INIT) {
if(call RssiAdcResource.isOwner()) {
sdDebug(20);
call ChannelMonitorControl.updateNoiseFloor();
} else {
sdDebug(21);
call RssiAdcResource.request();
}
}
else if(macState == STOP) {
}
else {
}
}
async event void RadioModes.RxModeDone() {
atomic {
clearFlag(&flags, SWITCHING);
if((macState == RX) || (macState == RX_ACK) || (macState == CCA) ||
(macState == INIT) || (macState == STOP)) {
if(macState != RX_ACK) requestAdc();
}
else {
}
}
}
async event void RadioModes.TxModeDone() {
atomic {
clearFlag(&flags, SWITCHING);
if(macState == TX) {
setFlag(&flags, ACTION_DETECTED);
if(call PacketSend.send(txBufPtr, txLen) == SUCCESS) {
}
else {
}
}
else if(macState == TX_ACK) {
if(call PacketSend.send(&ackMsg, 0) == SUCCESS) {
} else {
}
}
else {
}
}
}
async event void RadioModes.SleepModeDone() {
atomic {
clearFlag(&flags, SWITCHING);
if(isFlagSet(&flags, ACTION_DETECTED)) {
if(congestionLevel < 5) congestionLevel++;
} else {
if(congestionLevel > 0) congestionLevel--;
}
if(macState == SLEEP) {
if(!call Timer.isRunning()) {
if(isFlagSet(&flags, RESUME_BACKOFF)) {
clearFlag(&flags, RESUME_BACKOFF);
call Timer.start(restLaufzeit);
restLaufzeit = 0;
}
else {
checkSend();
}
}
}
else if(macState == STOP) {
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);
shortRetryCounter = 1;
longRetryCounter = 1;
txBufPtr = msg;
txLen = len + sizeof(red_mac_header_t);
seqNo++;
if(seqNo >= TOKEN_ACK_FLAG) seqNo = 1;
#ifdef SPECKMAC_PERFORMANCE
txStat.payloadLength = txLen;
txStat.interfaceTime = call LocalTime32kHz.get();
#endif
}
else {
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) {
setFlag(&flags, CANCEL_SEND);
shortRetryCounter = MAX_SHORT_RETRY + 2;
longRetryCounter = MAX_LONG_RETRY + 2;
if(macState == SLEEP) {
signalSendDone(ECANCEL);
}
else {
}
err = SUCCESS;
}
else {
}
}
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 SPECKMAC_PERFORMANCE
call Performance.macDetectedOnCca();
#endif
}
if(macState != RX_ACK) {
macState = RX_P;
} else {
macState = RX_ACK_P;
}
}
else if(macState == INIT) {
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;
bool isCnt;
#ifdef SPECKMAC_PERFORMANCE
rxStat.duplicate = PERF_UNKNOWN;
rxStat.repCounter = 0xff;
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?