forwardingenginep.nc

来自「tinyos-2.0源代码!转载而已!要的尽管拿!」· NC 代码 · 共 861 行 · 第 1/3 页

NC
861
字号
  /*   * Function for preparing a packet for forwarding. Performs   * a buffer swap from the message pool. If there are no free   * message in the pool, it returns the passed message and does not   * put it on the send queue.   */  message_t* forward(message_t* m) {    if (call MessagePool.empty()) {      dbg("Route", "%s cannot forward, message pool empty.\n", __FUNCTION__);      // send a debug message to the uart      call CollectionDebug.logEvent(NET_C_FE_MSG_POOL_EMPTY);    }    else if (call QEntryPool.empty()) {      dbg("Route", "%s cannot forward, queue entry pool empty.\n",           __FUNCTION__);      // send a debug message to the uart      call CollectionDebug.logEvent(NET_C_FE_QENTRY_POOL_EMPTY);    }    else {      message_t* newMsg;      fe_queue_entry_t *qe;      uint16_t gradient;            qe = call QEntryPool.get();      if (qe == NULL) {        call CollectionDebug.logEvent(NET_C_FE_GET_MSGPOOL_ERR);        return m;      }      newMsg = call MessagePool.get();      if (newMsg == NULL) {        call CollectionDebug.logEvent(NET_C_FE_GET_QEPOOL_ERR);        return m;      }      memset(newMsg, 0, sizeof(message_t));      memset(m->metadata, 0, sizeof(message_metadata_t));            qe->msg = m;      qe->client = 0xff;      qe->retries = MAX_RETRIES;            if (call SendQueue.enqueue(qe) == SUCCESS) {        dbg("Forwarder,Route", "%s forwarding packet %p with queue size %hhu\n", __FUNCTION__, m, call SendQueue.size());        // Loop-detection code:        if (call TreeRoutingInspect.getMetric(&gradient) == SUCCESS) {          // We only check for loops if we know our own metric          if (call CollectionPacket.getGradient(m) < gradient) {            // The incoming packet's metric (gradient) is less than our            // own gradient.  Trigger a route update and backoff.            call TreeRoutingInspect.triggerRouteUpdate();            startRetxmitTimer(LOOPY_WINDOW, LOOPY_OFFSET);            call CollectionDebug.logEvent(NET_C_FE_LOOP_DETECTED);          }        }        if (!call RetxmitTimer.isRunning()) {          // sendTask is only immediately posted if we don't detect a          // loop.          post sendTask();        }                // Successful function exit point:        return newMsg;      } else {        // There was a problem enqueuing to the send queue.        if (call MessagePool.put(newMsg) != SUCCESS)          call CollectionDebug.logEvent(NET_C_FE_PUT_MSGPOOL_ERR);        if (call QEntryPool.put(qe) != SUCCESS)          call CollectionDebug.logEvent(NET_C_FE_PUT_QEPOOL_ERR);      }    }    // Resource acquisition problem.  Send a debug message to the    // uart.    call CollectionDebug.logEvent(NET_C_FE_SEND_QUEUE_FULL);    // We'll have to drop the packet on the floor: not enough    // resources available to forward.    return m;  }   /*   * Received a message to forward. Check whether it is a duplicate by   * checking the packets currently in the queue as well as the    * send history cache (in case we recently forwarded this packet).   * The cache is important as nodes immediately forward packets   * but wait a period before retransmitting after an ack failure.   * If this node is a root, signal receive.   */   event message_t*   SubReceive.receive(message_t* msg, void* payload, uint8_t len) {    network_header_t* hdr = getHeader(msg);    uint8_t netlen;    collection_id_t collectid;    uint32_t msg_uid;    bool duplicate = FALSE;    fe_queue_entry_t* qe;    uint8_t i;    msg_uid = call CollectionPacket.getPacketID(msg);    collectid = hdr->collectid;    call CollectionDebug.logEventRoute(NET_C_FE_RCV_MSG,					 call CollectionPacket.getSequenceNumber(msg), 					 call CollectionPacket.getOrigin(msg),                                          call AMPacket.destination(msg));    if (len > call SubSend.maxPayloadLength()) {      return msg;    }    //See if we remember having seen this packet    //We look in the sent cache ...    if (call SentCache.lookup(msg_uid)) {        call CollectionDebug.logEvent(NET_C_FE_DUPLICATE_CACHE);        return msg;    }    //... and in the queue for duplicates    atomic {    	for (i = call SendQueue.size(); --i ;) {        	qe = call SendQueue.element(i);	        if (call CollectionPacket.getPacketID(qe->msg) == msg_uid) {        	    duplicate = TRUE;	            break;        	}	    }    }    if (duplicate) {        call CollectionDebug.logEvent(NET_C_FE_DUPLICATE_QUEUE);        return msg;    }    // If I'm the root, signal receive.     else if (call RootControl.isRoot())      return signal Receive.receive[collectid](msg,                         call Packet.getPayload(msg, &netlen),                         call Packet.payloadLength(msg));    // I'm on the routing path and Intercept indicates that I    // should not forward the packet.    else if (!signal Intercept.forward[collectid](msg,                         call Packet.getPayload(msg, &netlen),                         call Packet.payloadLength(msg)))      return msg;    else {      dbg("Route", "Forwarding packet from %hu.\n", hdr->origin);      return forward(msg);    }  }  command void*   Receive.getPayload[collection_id_t id](message_t* msg, uint8_t* len) {    return call Packet.getPayload(msg, NULL);  }  command uint8_t  Receive.payloadLength[collection_id_t id](message_t *msg) {    return call Packet.payloadLength(msg);  }  command void *  Snoop.getPayload[collection_id_t id](message_t *msg, uint8_t *len) {    return call Packet.getPayload(msg, NULL);  }  command uint8_t Snoop.payloadLength[collection_id_t id](message_t *msg) {    return call Packet.payloadLength(msg);  }  event message_t*   SubSnoop.receive(message_t* msg, void *payload, uint8_t len) {    network_header_t* hdr = getHeader(msg);    return signal Snoop.receive[hdr->collectid] (msg, (void *)(hdr + 1),                                           len - sizeof(network_header_t));  }    event void RetxmitTimer.fired() {    sending = FALSE;    post sendTask();  }    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(network_header_t);  }  command void Packet.setPayloadLength(message_t* msg, uint8_t len) {    call SubPacket.setPayloadLength(msg, len + sizeof(network_header_t));  }    command uint8_t Packet.maxPayloadLength() {    return call SubPacket.maxPayloadLength() - sizeof(network_header_t);  }  command void* Packet.getPayload(message_t* msg, uint8_t* len) {    uint8_t* payload = call SubPacket.getPayload(msg, len);    if (len != NULL) {      *len -= sizeof(network_header_t);    }    return payload + sizeof(network_header_t);  }  command am_addr_t CollectionPacket.getOrigin(message_t* msg) {    return getHeader(msg)->origin;  }  command void CollectionPacket.setOrigin(message_t* msg, am_addr_t addr) {    getHeader(msg)->origin = addr;  }  command uint8_t CollectionPacket.getCollectionID(message_t* msg) {    return getHeader(msg)->collectid;  }    command void CollectionPacket.setCollectionID(message_t* msg, uint8_t id) {    getHeader(msg)->collectid = id;  }  command uint8_t CollectionPacket.getControl(message_t* msg) {    return getHeader(msg)->control;  }    command void CollectionPacket.setControl(message_t* msg, uint8_t control) {    getHeader(msg)->control = control;  }  command uint16_t CollectionPacket.getGradient(message_t* msg) {    return getHeader(msg)->gradient;  }  command void CollectionPacket.setGradient(message_t* msg, uint16_t gradient) {    getHeader(msg)->gradient = gradient;  }  command uint8_t CollectionPacket.getSequenceNumber(message_t* msg) {    return getHeader(msg)->seqno;  }  command void CollectionPacket.setSequenceNumber(message_t* msg, uint8_t _seqno) {    getHeader(msg)->seqno = _seqno;  }  command uint32_t CollectionPacket.getPacketID(message_t* msg) {    return ((uint32_t)(getHeader(msg)->origin) << 16) | (uint32_t)(getHeader(msg)->seqno);    }    default event void  Send.sendDone[uint8_t client](message_t *msg, error_t error) {  }  default event bool  Intercept.forward[collection_id_t collectid](message_t* msg, void* payload,                                                uint16_t len) {    return TRUE;  }  default event message_t *  Receive.receive[collection_id_t collectid](message_t *msg, void *payload,                                             uint8_t len) {    return msg;  }  default event message_t *  Snoop.receive[collection_id_t collectid](message_t *msg, void *payload,                                           uint8_t len) {    return msg;  }  default command collection_id_t CollectionId.fetch[uint8_t client]() {    return 0;  }  static void startRetxmitTimer(uint16_t mask, uint16_t offset) {    uint16_t r = call Random.rand16();    r &= mask;    r += offset;    call RetxmitTimer.startOneShot(r);    dbg("Forwarder", "started rexmit timer in %hu ms\n", r);  }}

⌨️ 快捷键说明

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