/*************************************************************************//** *****************************************************************************/ static void nwkRouteSendRouteError(uint16_t src, uint16_t dst, uint8_t multicast) { NwkFrame_t *frame; NwkCommandRouteError_t *command; if (NULL == (frame = nwkFrameAlloc())) { return; } nwkFrameCommandInit(frame); frame->size += sizeof(NwkCommandRouteError_t); frame->tx.confirm = NULL; frame->header.nwkDstAddr = src; command = (NwkCommandRouteError_t *)frame->payload; command->id = NWK_COMMAND_ROUTE_ERROR; command->srcAddr = src; command->dstAddr = dst; command->multicast = multicast; nwkTxFrame(frame); }
/*************************************************************************//** *****************************************************************************/ static void nwkRouteDiscoverySendReply(NwkRouteDiscoveryTableEntry_t *entry, uint8_t flq, uint8_t rlq) { NwkFrame_t *req; NwkCommandRouteReply_t *command; if (NULL == (req = nwkFrameAlloc())) return; nwkFrameCommandInit(req); req->size += sizeof(NwkCommandRouteReply_t); req->tx.confirm = NULL; req->tx.control = NWK_TX_CONTROL_DIRECT_LINK; req->header.nwkDstAddr = entry->senderAddr; command = (NwkCommandRouteReply_t *)req->payload; command->id = NWK_COMMAND_ROUTE_REPLY; command->srcAddr = entry->srcAddr; command->dstAddr = entry->dstAddr; command->multicast = entry->multicast; command->forwardLinkQuality = flq; command->reverseLinkQuality = rlq; nwkTxFrame(req); }
/*************************************************************************//** *****************************************************************************/ static bool nwkRouteDiscoverySendRequest(NwkRouteDiscoveryTableEntry_t *entry, uint8_t lq) { NwkFrame_t *req; NwkCommandRouteRequest_t *command; if (NULL == (req = nwkFrameAlloc())) return false; nwkFrameCommandInit(req); req->size += sizeof(NwkCommandRouteRequest_t); req->tx.confirm = NULL; req->header.nwkFcf.linkLocal = 1; req->header.nwkDstAddr = NWK_BROADCAST_ADDR; command = (NwkCommandRouteRequest_t *)req->payload; command->id = NWK_COMMAND_ROUTE_REQUEST; command->srcAddr = entry->srcAddr; command->dstAddr = entry->dstAddr; command->multicast = entry->multicast; command->linkQuality = lq; nwkTxFrame(req); return true; }
/*************************************************************************//** * @brief Prepares and send outgoing frame based on the request @a req * parameters * @param[in] req Pointer to the request parameters *****************************************************************************/ static void nwkDataReqSendFrame(NWK_DataReq_t *req) { NwkFrame_t *frame; if (NULL == (frame = nwkFrameAlloc())) { req->state = NWK_DATA_REQ_STATE_CONFIRM; req->status = NWK_OUT_OF_MEMORY_STATUS; return; } req->frame = frame; req->state = NWK_DATA_REQ_STATE_WAIT_CONF; frame->tx.confirm = nwkDataReqTxConf; frame->tx.control = req->options & NWK_OPT_BROADCAST_PAN_ID ? NWK_TX_CONTROL_BROADCAST_PAN_ID : 0; frame->header.nwkFcf.ackRequest = req->options & NWK_OPT_ACK_REQUEST ? 1 : 0; frame->header.nwkFcf.linkLocal = req->options & NWK_OPT_LINK_LOCAL ? 1 : 0; #ifdef NWK_ENABLE_SECURITY frame->header.nwkFcf.security = req->options & NWK_OPT_ENABLE_SECURITY ? 1 : 0; #endif #ifdef NWK_ENABLE_MULTICAST frame->header.nwkFcf.multicast = req->options & NWK_OPT_MULTICAST ? 1 : 0; if (frame->header.nwkFcf.multicast) { NwkFrameMulticastHeader_t *mcHeader = (NwkFrameMulticastHeader_t *)frame->payload; mcHeader->memberRadius = req->memberRadius; mcHeader->maxMemberRadius = req->memberRadius; mcHeader->nonMemberRadius = req->nonMemberRadius; mcHeader->maxNonMemberRadius = req->nonMemberRadius; frame->payload += sizeof(NwkFrameMulticastHeader_t); frame->size += sizeof(NwkFrameMulticastHeader_t); } #endif frame->header.nwkSeq = ++nwkIb.nwkSeqNum; frame->header.nwkSrcAddr = nwkIb.addr; frame->header.nwkDstAddr = req->dstAddr; frame->header.nwkSrcEndpoint = req->srcEndpoint; frame->header.nwkDstEndpoint = req->dstEndpoint; memcpy(frame->payload, req->data, req->size); frame->size += req->size; nwkTxFrame(frame); }
/*************************************************************************//** *****************************************************************************/ void nwkRouteFrame(NwkFrame_t *frame) { NwkFrameHeader_t *header = &frame->header; if (NWK_ROUTE_UNKNOWN != NWK_RouteNextHop(header->nwkDstAddr, header->nwkFcf.multicast)) { frame->tx.confirm = NULL; frame->tx.control = NWK_TX_CONTROL_ROUTING; nwkTxFrame(frame); } else { nwkRouteSendRouteError(header->nwkSrcAddr, header->nwkDstAddr, header->nwkFcf.multicast); nwkFrameFree(frame); } }
/*************************************************************************//** *****************************************************************************/ static void nwkRouteDiscoveryDone(NwkRouteDiscoveryTableEntry_t *entry, bool status) { NwkFrame_t *frame = NULL; while (NULL != (frame = nwkFrameNext(frame))) { if (NWK_RD_STATE_WAIT_FOR_ROUTE != frame->state) continue; if (entry->dstAddr != frame->header.nwkDstAddr || entry->multicast != frame->header.nwkFcf.multicast) continue; if (status) nwkTxFrame(frame); else nwkTxConfirm(frame, NWK_NO_ROUTE_STATUS); } }
static void nwkDataReqSendFrame(NWK_DataReq_t *req) { NwkFrame_t *frame; uint8_t size = req->size; #ifdef NWK_ENABLE_SECURITY if (req->options & NWK_OPT_ENABLE_SECURITY) size += NWK_SECURITY_MIC_SIZE; #endif if (NULL == (frame = nwkFrameAlloc(size))) { req->state = NWK_DATA_REQ_STATE_CONFIRM; req->status = NWK_OUT_OF_MEMORY_STATUS; return; } req->frame = frame; req->state = NWK_DATA_REQ_STATE_WAIT_CONF; frame->tx.confirm = nwkDataReqTxConf; frame->tx.control = req->options & NWK_OPT_BROADCAST_PAN_ID ? NWK_TX_CONTROL_BROADCAST_PAN_ID : 0; frame->data.header.nwkFcf.ackRequest = req->options & NWK_OPT_ACK_REQUEST ? 1 : 0; #ifdef NWK_ENABLE_SECURITY frame->data.header.nwkFcf.securityEnabled = req->options & NWK_OPT_ENABLE_SECURITY ? 1 : 0; #endif frame->data.header.nwkFcf.linkLocal = req->options & NWK_OPT_LINK_LOCAL ? 1 : 0; frame->data.header.nwkFcf.reserved = 0; frame->data.header.nwkSeq = ++nwkIb.nwkSeqNum; frame->data.header.nwkSrcAddr = nwkIb.addr; frame->data.header.nwkDstAddr = req->dstAddr; frame->data.header.nwkSrcEndpoint = req->srcEndpoint; frame->data.header.nwkDstEndpoint = req->dstEndpoint; memcpy(frame->data.payload, req->data, req->size); nwkTxFrame(frame); }
/*************************************************************************//** *****************************************************************************/ static void nwkRxSendAck(NwkFrame_t *frame) { NwkFrame_t *ack; NwkCommandAck_t *command; if (NULL == (ack = nwkFrameAlloc())) return; nwkFrameCommandInit(ack); ack->size += sizeof(NwkCommandAck_t); ack->tx.confirm = NULL; ack->header.nwkFcf.security = frame->header.nwkFcf.security; ack->header.nwkDstAddr = frame->header.nwkSrcAddr; command = (NwkCommandAck_t *)ack->payload; command->id = NWK_COMMAND_ACK; command->control = nwkRxAckControl; command->seq = frame->header.nwkSeq; nwkTxFrame(ack); }