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 + -
显示快捷键?