/*************************************************************************//** *****************************************************************************/ 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; }
/*************************************************************************//** *****************************************************************************/ 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); }
/*************************************************************************//** * @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 PHY_DataInd(PHY_DataInd_t *ind) { NwkFrame_t *frame; if (0x88 != ind->data[1] || (0x61 != ind->data[0] && 0x41 != ind->data[0]) || ind->size < sizeof(NwkFrameHeader_t)) return; if (NULL == (frame = nwkFrameAlloc())) return; frame->state = NWK_RX_STATE_RECEIVED; frame->size = ind->size; frame->rx.lqi = ind->lqi; frame->rx.rssi = ind->rssi; memcpy(frame->data, ind->data, ind->size); }
/*************************************************************************//** *****************************************************************************/ void nwkTxBroadcastFrame(NwkFrame_t *frame) { NwkFrame_t *newFrame; if (NULL == (newFrame = nwkFrameAlloc())) { return; } newFrame->state = NWK_TX_STATE_DELAY; newFrame->size = frame->size; newFrame->tx.status = NWK_SUCCESS_STATUS; newFrame->tx.timeout = (rand() & NWK_TX_DELAY_JITTER_MASK) + 1; newFrame->tx.confirm = NULL; memcpy(newFrame->data, frame->data, frame->size); newFrame->header.macFcf = 0x8841; newFrame->header.macDstAddr = NWK_BROADCAST_ADDR; newFrame->header.macDstPanId = frame->header.macDstPanId; newFrame->header.macSrcAddr = nwkIb.addr; newFrame->header.macSeq = ++nwkIb.macSeqNum; }
void nwkTxBroadcastFrame(NwkFrame_t *frame) { NwkFrame_t *newFrame; if (NULL == (newFrame = nwkFrameAlloc(frame->size - sizeof(NwkFrameHeader_t)))) return; newFrame->tx.confirm = nwkTxBroadcastConf; memcpy((uint8_t *)&newFrame->data, (uint8_t *)&frame->data, frame->size); newFrame->state = NWK_TX_STATE_SEND; newFrame->tx.status = NWK_SUCCESS_STATUS; newFrame->data.header.macFcf = 0x8841; newFrame->data.header.macDstAddr = 0xffff; newFrame->data.header.macDstPanId = nwkIb.panId; newFrame->data.header.macSrcAddr = nwkIb.addr; newFrame->data.header.macSeq = ++nwkIb.macSeqNum; ++nwkTxActiveFrames; }
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); }