⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 networkc.nc

📁 用于传感器网络的节点操作系统 TinyOS 结构设计非常有意思
💻 NC
📖 第 1 页 / 共 3 页
字号:
	  }	}      } return err_MessageSendFailed;    }          /** Called (by TupleRouter) whenever an epoch ends */     command void Network.endOfEpoch() {      //HACK : Parent reselect interval in terms of epochs on all queries       //may not be the best metric as it will cause reselection to happen       //faster for higher epoch rates / more queries       mSendCount++;     }    /* Send a 'query' message -- query messages contain information about       queries that should be sent to neighbors in the network.              REQUIRES:  msg is a message buffer of which the first entry is of       type DbMsgHdr              SIGNALS: TINYDB_NETWORK_SUB_MSG_SEND_DONE after message is sent,       unless an error is returned.              RETURNS: err_NoError if no error       err_UnknownError if transmission fails.    */     command TinyDBError Network.sendQueryMessage(TOS_MsgPtr msg) {      NetworkMessage *nw = (NetworkMessage *)msg->data;      uint8_t rootId = 0;            bool amRoot = checkRoot(msg, &rootId);      mMsg = msg;      mAmId = kQUERY_MESSAGE_ID;        if (!mRadio) {	mRadio = TRUE;	initHeader(&nw->hdr, amRoot, rootId);	mRetryCnt = QUERY_RETRIES;	if (call SendQueryMsg.send(TOS_BCAST_ADDR, kMSG_LEN, msg) == SUCCESS) {	  call Leds.redToggle();	  return err_NoError;	} else {	  mIdx--; //failed to send -- undo counter	  mRadio = FALSE;	  return err_MessageSendFailed;	}      }       return err_MessageSendFailed;           }    /* Send a request for a query message to neighbors       REQUIRES:  msg is a message buffer of which the first entry is of       type DbMsgHdr              SIGNALS: TINYDB_NETWORK_SUB_MSG_SEND_DONE after message is sent,       unless an error is returned.              RETURNS: err_NoError if no error       err_MessageSendFailed if transmission fails.    */     command TinyDBError Network.sendQueryRequest(TOS_MsgPtr msg, uint16_t from) {       NetworkMessage *nw = (NetworkMessage *)msg->data;       uint8_t rootId = 0;              bool amRoot = checkRoot(msg, &rootId);       mMsg = msg;       mAmId = kQUERY_REQUEST_MESSAGE_ID;              if (!mRadio) {	 mRadio = TRUE;	 initHeader(&nw->hdr, amRoot, rootId);	 if (call SendQueryRequest.send(from, kMSG_LEN, msg) == SUCCESS) {	   return err_NoError;	 }  else {	   mRadio = FALSE;	   return err_MessageSendFailed;	 }       }       return err_MessageSendFailed;     }         //write a message out over the uart     command result_t Network.sendUart(char *msg, uint8_t amid) {       if (!mUart /*&& !mRadio*/) {	 mUart = TRUE;	 memcpy(&mDbg.data, msg, kMSG_LEN);	 if (call DebugMsg.send(TOS_UART_ADDR,kMSG_LEN,&mDbg))  {	   return err_NoError;	 } else {	   mUart = FALSE;	   return err_MessageSendFailed;	 }       } else	 return err_MessageSendFailed;     }    /* Called when the network component has finished delivering a message. */     result_t sendDone(TOS_MsgPtr msg) {       dbg(DBG_USR1,"SEND DONE \n");       if (mUart && msg == &mDbg) { //if we finished sending a message over the uart	 mUart = FALSE;       } else if (mRadio) { //might not have been us that send the message!	 mRadio = FALSE;	if (!mLocal && !mWasCommand) { //message sent on behalf of some other component	  signal Network.outputDone(msg, mAmId);	} else if (mWasCommand) { //command message that has been sent, now must be executed	  // XXX, ignore command return value for now	  call CommandUse.invokeMsg(&mDbg, NULL, &errorNo);	  mWasCommand = FALSE;	} else {	  mLocal = FALSE;	}        }        return SUCCESS;     }     event result_t SendQueryMsg.sendDone(TOS_MsgPtr msg, result_t success) {       if ((!success || !msg->ack) && mRetryCnt-- > 0) {	 if (call SendQueryMsg.send(TOS_BCAST_ADDR, kMSG_LEN, msg) != SUCCESS) {	   mRetryCnt = 0;	   return sendDone(msg);	 }       } else {	 mRetryCnt = 0;	 return sendDone(msg);       }       return SUCCESS;     }     event result_t SendDataMsg.sendDone(TOS_MsgPtr msg, result_t success) {       //disabled link degredation for now -- this would be a way to work       //around asymmetric links, but it adds a lot of instability       //if (!msg->ack) degradeLinkQuality(((NetworkMessage *)msg->data)->hdr.parentid);       if ((!success || !msg->ack) && mRetryCnt-- > 0) {	 if (call SendDataMsg.send(TOS_BCAST_ADDR, kMSG_LEN, msg) != SUCCESS) {	   mRetryCnt = 0;	   return sendDone(msg);	 }       } else {	 mRetryCnt = 0;	 return sendDone(msg);       }       return SUCCESS;     }     event result_t SendQueryRequest.sendDone(TOS_MsgPtr msg, result_t success) {	 return sendDone(msg);     }     event result_t DebugMsg.sendDone(TOS_MsgPtr msg, result_t success) {	 return sendDone(msg);     }     event result_t SchemaMsg.sendDone(TOS_MsgPtr msg, result_t success) {	 return sendDone(msg);     }     /* Check a message for CRC and to see if we've already ack'd it...       Return true if the messsage should be rejected.     */     bool filterMessage(TOS_MsgPtr msg, bool checkRecent ) {       if (msg->crc == 0) {	 return TRUE;       }       if (checkRecent) {	 NetworkMessage *nw = (NetworkMessage *)msg->data;  	 long id = (((long)nw->hdr.senderid) << 16) + nw->hdr.idx;	 short i;	 if ( nw->hdr.senderid == TOS_UART_ADDR) return FALSE; //don't filter root messages	 for (i = 0; i < NUM_RECENT_MSGS; i++) {	     	     if (mRecentMsgs[i] == id) {		 return TRUE;	     }	 }	 mRecentMsgs[mNextMsg++] = id;	 	 if (mNextMsg == NUM_RECENT_MSGS) mNextMsg = 0; //circular buffer       }              return FALSE;     }    /* Event that's fired when a query message arrives */     event TOS_MsgPtr RcvQueryMsg.receive(TOS_MsgPtr msg) {      NetworkMessage *nw = (NetworkMessage *)msg->data;        uint8_t rootId = 0;      if (filterMessage(msg,TRUE)) return msg;      checkRoot(msg, &rootId);      if (processHeader(nw->hdr,QUERY_TYPE,rootId)) {	//only log messages we're actually processing	if (!mCentralized) {	  signal Network.querySub(msg);	} else {	  //forward without processing in centralized approach	  call Network.sendDataMessage(msg);	}      }      return msg;    }    /* Event thats fired when a request for a query arrives from a neighbor */     event TOS_MsgPtr RcvRequestMsg.receive(TOS_MsgPtr msg) {      NetworkMessage *nw = (NetworkMessage *)msg->data;      uint8_t rootId = 0;      if (filterMessage(msg,FALSE)) return msg;      checkRoot(msg, &rootId);      processHeader(nw->hdr, QUERY_TYPE,rootId); //ignore return rest -- always handle these        signal Network.queryRequestSub(msg);      return msg;    }    /* Event that's fired when a network data item arrives */     event TOS_MsgPtr RcvDataMsg.receive(TOS_MsgPtr msg) {      NetworkMessage *nw = (NetworkMessage *)msg->data;      uint8_t rootId;      bool amRoot;      if (filterMessage(msg,TRUE)) return msg;      amRoot = checkRoot(msg, &rootId);      if (amRoot && nw->hdr.senderid == TOS_UART_ADDR) { //was this heartbeat from root?	if (!mRadio /*&& !mUart*/) { 	  mRadio = TRUE;	  mLocal = TRUE;	  initHeader(&nw->hdr, TRUE, rootId);	  call Leds.redToggle();	  if (call SendDataMsg.send(TOS_BCAST_ADDR, kMSG_LEN, msg) == FAIL) {	    mIdx--; //reuse this index, since we failed to forward this message	    mRadio = FALSE;	    mLocal = FALSE;	  }	}      }       //root sends data messages heartbeats -- ignore them      if (processHeader(nw->hdr,DATA_TYPE,rootId) && nw->hdr.senderid != mRoots[rootId]) {	signal Network.dataSub(msg);      } else if (nw->hdr.senderid != TOS_UART_ADDR) //give mote a chance to look at it event though it wasn't addressed locally	signal Network.snoopedSub(msg, kDATA_MESSAGE_ID, mParentIx[rootId] != PARENT_UNKNOWN &&				nw->hdr.senderid == mRelatives[mParentIx[rootId]]);      return msg;     }    /* Intercept schema command messages so that they can be forwarded from the root out       to the rest of the nodes    */         event TOS_MsgPtr RcvSchemaMsg.receive(TOS_MsgPtr msg) {      uint8_t rootId;      bool amRoot;      bool shouldResend;      if (filterMessage(msg,FALSE)) return msg;      amRoot = checkRoot(msg, &rootId);      shouldResend = ((struct CommandMsg *)(msg->data))->fromBase;      ((struct CommandMsg *)(msg->data))->fromBase = FALSE;      //forward the message      if ((amRoot || shouldResend)  && !mRadio) {	mWasCommand = TRUE; //note that we'll need to executed the command later	mRadio = TRUE;		if (call SchemaMsg.send(TOS_BCAST_ADDR, kMSG_LEN,  msg) == SUCCESS) {	  memcpy(&mDbg, msg, sizeof(TOS_Msg)); //save off command for later execution.	} else { //failure	  mWasCommand = FALSE;	  mRadio = FALSE;		}      } else {	// XXX ignore command return values for now	  call Leds.greenToggle();	call CommandUse.invokeMsg(msg, NULL, &errorNo);      }      return msg;    }    /* Maintain the local header information */    void initHeader(DbMsgHdr *header, bool amRoot, uint8_t rootId) {      header->senderid = TOS_LOCAL_ADDRESS;      if (!amRoot) {	header->parentid = mRelatives[mParentIx[rootId]];	header->level = myLevel(rootId);      } else {	header->parentid = 0;	header->level = 0;      }      header->idx = mIdx++;      //if (header->idx < 0) // overflow!      //header->idx = mIdx = 0;      //  TOS_CALL_COMMAND(GET_TIME)(&header->sendtime);      }    // handle case where parent is unknown.    // parent becomes the sender of this msg    void tinydbParentInit(DbMsgHdr header, short clockCnt, uint8_t rootId)       {	//  short curtime;	mParentIx[rootId] = 0; // put parent in 1st slot in relatives array	mRelOccupiedBits = 0x1; // 1 slot occupied: slot 0	mRelatives[0] = header.senderid; // sender is parent	mLastIdxRelative[0] = header.idx; 	mCommProb[0] = 0xff; // ignore 1st message in stats	mRelLevel[rootId][0] = header.level;	//synchronize time with new parent (unless parent is root!)	//	if (MY_LEVEL != 1 	//		&& mRelatives[mParentIx] == header.senderid) {	//	  curtime = header.sendtime + TIME_OF_FLIGHT;	// XXXX not sure that time sync works right!	//  TOS_CALL_COMMAND(SET_TIME)(curtime);	//}	dbg(DBG_USR1,"%d: parent is %d\n", TOS_LOCAL_ADDRESS, header.senderid);      }    // loop through all parents (for all roots) and check if the specified index is    // a prent.    bool isParent(uint8_t idx) {      short i;      for (i=0; i < NUM_ROOTS; i++) {	if (mRoots[i] != UNKNOWN_ROOT && mParentIx[mRoots[i]] == idx)	  return TRUE;      }      return FALSE;    }    //make this link look less attractive, as a result of a dropped    //message or a failed ack!    void degradeLinkQuality(short neighborId) {      int i;      for (i = 0; i < NUM_RELATIVES;  i++) {	if (mRelatives[i] == neighborId) {	  mCommProb[i] = mCommProb[i] - (mCommProb[i] >> NACKALPHA);	  break;	}      }

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -