/*************************************************************************//** *****************************************************************************/ void nwkRoutePrepareTx(NwkFrame_t *frame) { NwkFrameHeader_t *header = &frame->header; if (NWK_BROADCAST_ADDR == header->nwkDstAddr) { header->macDstAddr = NWK_BROADCAST_ADDR; } else if (header->nwkFcf.linkLocal) { header->macDstAddr = header->nwkDstAddr; } #ifdef NWK_ENABLE_MULTICAST else if (header->nwkFcf.multicast && NWK_GroupIsMember(header->nwkDstAddr)) { header->macDstAddr = NWK_BROADCAST_ADDR; header->nwkFcf.linkLocal = 1; } #endif else { header->macDstAddr = NWK_RouteNextHop(header->nwkDstAddr, header->nwkFcf.multicast); #ifdef NWK_ENABLE_ROUTE_DISCOVERY if (NWK_ROUTE_UNKNOWN == header->macDstAddr) { nwkRouteDiscoveryRequest(frame); } #endif } }
/*************************************************************************//** *****************************************************************************/ bool nwkRouteDiscoveryRequestReceived(NWK_DataInd_t *ind) { NwkCommandRouteRequest_t *command = (NwkCommandRouteRequest_t *)ind->data; NwkRouteDiscoveryTableEntry_t *entry; uint8_t linkQuality; bool reply = false; if (sizeof(NwkCommandRouteRequest_t) != ind->size) return false; #ifdef NWK_ENABLE_MULTICAST if (1 == command->multicast && NWK_GroupIsMember(command->dstAddr)) reply = true; #endif if (0 == command->multicast && command->dstAddr == nwkIb.addr) reply = true; if (command->srcAddr == nwkIb.addr) return true; if (false == reply && nwkIb.addr & NWK_ROUTE_NON_ROUTING) return true; linkQuality = nwkRouteDiscoveryUpdateLq(command->linkQuality, ind->lqi); entry = nwkRouteDiscoveryFindEntry(command->srcAddr, command->dstAddr, command->multicast); if (entry) { if (linkQuality <= entry->forwardLinkQuality) return true; } else { if (NULL == (entry = nwkRouteDiscoveryNewEntry())) return true; } entry->srcAddr = command->srcAddr; entry->dstAddr = command->dstAddr; entry->multicast = command->multicast; entry->senderAddr = ind->srcAddr; entry->forwardLinkQuality = linkQuality; if (reply) { nwkRouteUpdateEntry(command->srcAddr, 0, ind->srcAddr, linkQuality); nwkRouteDiscoverySendReply(entry, linkQuality, NWK_ROUTE_DISCOVERY_BEST_LINK_QUALITY); } else { nwkRouteDiscoverySendRequest(entry, linkQuality); } return true; }
/*************************************************************************//** *****************************************************************************/ static void nwkRxHandleReceivedFrame(NwkFrame_t *frame) { NwkFrameHeader_t *header = &frame->header; frame->state = NWK_RX_STATE_FINISH; #ifndef NWK_ENABLE_SECURITY if (header->nwkFcf.security) return; #endif #ifdef NWK_ENABLE_MULTICAST if (header->nwkFcf.multicast && header->nwkFcf.ackRequest) return; #else if (header->nwkFcf.multicast) return; #endif if (NWK_BROADCAST_PANID == header->macDstPanId) { if (nwkIb.addr == header->nwkDstAddr || NWK_BROADCAST_ADDR == header->nwkDstAddr) { #ifdef NWK_ENABLE_SECURITY if (header->nwkFcf.security) frame->state = NWK_RX_STATE_DECRYPT; else #endif frame->state = NWK_RX_STATE_INDICATE; } return; } #ifdef NWK_ENABLE_ADDRESS_FILTER if (!NWK_FilterAddress(header->macSrcAddr, &frame->rx.lqi)) return; #endif if (NWK_BROADCAST_ADDR == header->nwkDstAddr && header->nwkFcf.ackRequest) return; if (nwkIb.addr == header->nwkSrcAddr) return; #ifdef NWK_ENABLE_ROUTING nwkRouteFrameReceived(frame); #endif if (nwkRxRejectDuplicate(header)) return; #ifdef NWK_ENABLE_MULTICAST if (header->nwkFcf.multicast) { NwkFrameMulticastHeader_t *mcHeader = (NwkFrameMulticastHeader_t *)frame->payload; bool member = NWK_GroupIsMember(header->nwkDstAddr); bool broadcast = false; if (NWK_BROADCAST_ADDR == header->macDstAddr) { if (member) { broadcast = mcHeader->memberRadius > 0; mcHeader->memberRadius--; mcHeader->nonMemberRadius = mcHeader->maxNonMemberRadius; } else { broadcast = mcHeader->nonMemberRadius > 0; mcHeader->nonMemberRadius--; mcHeader->memberRadius = mcHeader->maxMemberRadius; } } else { if (member) { broadcast = true; header->nwkFcf.linkLocal = 1; } #ifdef NWK_ENABLE_ROUTING else { frame->state = NWK_RX_STATE_ROUTE; } #endif } if (broadcast) nwkTxBroadcastFrame(frame); if (member) { frame->payload += sizeof(NwkFrameMulticastHeader_t); #ifdef NWK_ENABLE_SECURITY if (header->nwkFcf.security) frame->state = NWK_RX_STATE_DECRYPT; else #endif frame->state = NWK_RX_STATE_INDICATE; } } else #endif // NWK_ENABLE_MULTICAST { if (NWK_BROADCAST_ADDR == header->macDstAddr && nwkIb.addr != header->nwkDstAddr && 0 == header->nwkFcf.linkLocal) nwkTxBroadcastFrame(frame); if (nwkIb.addr == header->nwkDstAddr || NWK_BROADCAST_ADDR == header->nwkDstAddr) { #ifdef NWK_ENABLE_SECURITY if (header->nwkFcf.security) frame->state = NWK_RX_STATE_DECRYPT; else #endif frame->state = NWK_RX_STATE_INDICATE; } #ifdef NWK_ENABLE_ROUTING else if (nwkIb.addr == header->macDstAddr) { frame->state = NWK_RX_STATE_ROUTE; } #endif } }