/*************************************************************************//** *****************************************************************************/ void nwkRouteFrameSent(NwkFrame_t *frame) { NWK_RouteTableEntry_t *entry; if (NWK_BROADCAST_ADDR == frame->header.nwkDstAddr) { return; } entry = NWK_RouteFindEntry(frame->header.nwkDstAddr, frame->header.nwkFcf.multicast); if (NULL == entry || entry->fixed) { return; } if (NWK_SUCCESS_STATUS == frame->tx.status) { entry->score = NWK_ROUTE_DEFAULT_SCORE; if (NWK_ROUTE_MAX_RANK == ++entry->rank) { nwkRouteNormalizeRanks(); } } else { if (0 == --entry->score) { NWK_RouteFreeEntry(entry); } } }
/*************************************************************************//** *****************************************************************************/ void nwkRouteRemove(uint16_t dst, uint8_t multicast) { NWK_RouteTableEntry_t *entry; entry = NWK_RouteFindEntry(dst, multicast); if (entry) { NWK_RouteFreeEntry(entry); } }
/*************************************************************************//** *****************************************************************************/ uint16_t NWK_RouteNextHop(uint16_t dst, uint8_t multicast) { NWK_RouteTableEntry_t *entry; entry = NWK_RouteFindEntry(dst, multicast); if (entry) { return entry->nextHopAddr; } return NWK_ROUTE_UNKNOWN; }
/*************************************************************************//** *****************************************************************************/ void nwkRouteUpdateEntry(uint16_t dst, uint8_t multicast, uint16_t nextHop, uint8_t lqi) { NWK_RouteTableEntry_t *entry; entry = NWK_RouteFindEntry(dst, multicast); if (NULL == entry) { entry = NWK_RouteNewEntry(); } entry->dstAddr = dst; entry->nextHopAddr = nextHop; entry->multicast = multicast; entry->score = NWK_ROUTE_DEFAULT_SCORE; entry->rank = NWK_ROUTE_DEFAULT_RANK; entry->lqi = lqi; }
/*- NextHop --------------------------------------------------*/ void networkNextHop_Handler(OPERATION_HEADER_t* operation_header) { if(operation_header->opCode == NextHopRead) { NEXT_HOP_READ_MESSAGE_t* msg = (NEXT_HOP_READ_MESSAGE_t*)(operation_header + 1); NWK_RouteTableEntry_t *rec = NWK_RouteFindEntry(msg->nodeAddress, 0); nextHopResponse.header.sourceAddress = runningConfiguration.topConfiguration.networkConfig.deviceAddress; nextHopResponse.header.destinationAddress = operation_header->sourceAddress; nextHopResponse.response.nodeAddress = msg->nodeAddress; nextHopResponse.response.nextHopeAddress = rec->nextHopAddr; nextHopResponse.response.lqi = rec->lqi; nextHopResponse.response.score = rec->score; OM_ProccessResponseOperation(&nextHopResponse.header); }else if(operation_header->opCode == NextHopReadResponse) { //TODO: SEND NOTIFICATION } }
/*************************************************************************//** *****************************************************************************/ void nwkRouteFrameReceived(NwkFrame_t *frame) { #ifndef NWK_ENABLE_ROUTE_DISCOVERY NwkFrameHeader_t *header = &frame->header; NWK_RouteTableEntry_t *entry; if ((header->macSrcAddr & NWK_ROUTE_NON_ROUTING) && (header->macSrcAddr != header->nwkSrcAddr)) { return; } if (NWK_BROADCAST_PANID == header->macDstPanId) { return; } entry = NWK_RouteFindEntry(header->nwkSrcAddr, false); if (entry) { bool discovery = (NWK_BROADCAST_ADDR == header->macDstAddr && nwkIb.addr == header->nwkDstAddr); if ((entry->nextHopAddr != header->macSrcAddr && frame->rx.lqi > entry->lqi) || discovery) { entry->nextHopAddr = header->macSrcAddr; entry->score = NWK_ROUTE_DEFAULT_SCORE; } } else { entry = NWK_RouteNewEntry(); entry->dstAddr = header->nwkSrcAddr; entry->nextHopAddr = header->macSrcAddr; } entry->lqi = frame->rx.lqi; #else (void)frame; #endif }
/*************************************************************************//** *****************************************************************************/ AppStatus_t appCommandReceived(uint8_t *buf, uint16_t size) { AppReceiveCommand_t *cmd = (AppReceiveCommand_t *)buf; switch (cmd->header.id) { case APP_COMMAND_DUMMY: { } break; case APP_COMMAND_RESET: { /* TODO: reset */ } break; case APP_COMMAND_RANDOMIZE: { srand(cmd->randomize.rnd); } break; #ifdef APP_ENABLE_EVENTS_BUFFER case APP_COMMAND_GET_EVENTS: { appCommandsSendEvents(); } break; #endif case APP_COMMAND_DATA_REQ: { return appProcessDataReq(&cmd->dataReq); } break; case APP_COMMAND_OPEN_ENDPOINT: { appOpenEndpoint(cmd->openEndpoint.index, cmd->openEndpoint.state); } break; case APP_COMMAND_SET_ACK_STATE: { appEndpointAckState[cmd->setAckState.index] = cmd->setAckState.state; } break; case APP_COMMAND_SET_ADDR: { NWK_SetAddr(cmd->setAddr.addr); } break; case APP_COMMAND_SET_PANID: { NWK_SetPanId(cmd->setPanId.panId); } break; case APP_COMMAND_SET_CHANNEL: { PHY_SetChannel(cmd->setChannel.channel); #ifdef PHY_AT86RF212 PHY_SetBand(cmd->setChannel.band); PHY_SetModulation(cmd->setChannel.modulation); #endif } break; case APP_COMMAND_SET_RX_STATE: { PHY_SetRxState(cmd->setRxState.rxState); } break; #ifdef NWK_ENABLE_SECURITY case APP_COMMAND_SET_SECURITY_KEY: { NWK_SetSecurityKey(cmd->setSecurityKey.securityKey); } break; #endif case APP_COMMAND_SET_TX_POWER: { PHY_SetTxPower(cmd->setTxPower.txPower); } break; #ifdef NWK_ENABLE_MULTICAST case APP_COMMAND_GROUP_ADD: { NWK_GroupAdd(cmd->groupAdd.group); } break; case APP_COMMAND_GROUP_REMOVE: { NWK_GroupRemove(cmd->groupRemove.group); } break; #endif #ifdef NWK_ENABLE_ROUTING case APP_COMMAND_ROUTE_ADD: { NWK_RouteTableEntry_t *entry; entry = NWK_RouteNewEntry(); entry->fixed = cmd->routeAdd.fixed; entry->multicast = cmd->routeAdd.multicast; entry->dstAddr = cmd->routeAdd.dstAddr; entry->nextHopAddr = cmd->routeAdd.nextHopAddr; entry->lqi = cmd->routeAdd.lqi; } break; case APP_COMMAND_ROUTE_REMOVE: { NWK_RouteTableEntry_t *entry; entry = NWK_RouteFindEntry(cmd->routeRemove.dstAddr, cmd->routeRemove.multicast); if (entry) { if (cmd->routeRemove.removeFixed) { entry->fixed = 0; } NWK_RouteFreeEntry(entry); } } break; case APP_COMMAND_ROUTE_FLUSH: { NWK_RouteTableEntry_t *entry = NWK_RouteTable(); for (uint16_t i = 0; i < NWK_ROUTE_TABLE_SIZE; i++, entry++) { if (NWK_ROUTE_UNKNOWN == entry->dstAddr) { continue; } if (cmd->routeFlush.removeFixed) { entry->fixed = 0; } NWK_RouteFreeEntry(entry); } } break; case APP_COMMAND_ROUTE_TABLE: { NWK_RouteTableEntry_t *entry = NWK_RouteTable(); for (uint16_t i = 0; i < NWK_ROUTE_TABLE_SIZE; i++, entry++) { if (NWK_ROUTE_UNKNOWN != entry->dstAddr) { appCommandsSendRouteEntry(i, entry); } } } break; #endif #ifdef NWK_ENABLE_ADDRESS_FILTER case APP_COMMAND_FILTER_ADD: { if (!appFilterAdd(cmd->filterAdd.addr, cmd->filterAdd.allow, cmd->filterAdd.setLqi, cmd->filterAdd.lqi)) { return APP_STATUS_TABLE_IS_FULL; } } break; case APP_COMMAND_FILTER_REMOVE: { if (!appFilterRemove(cmd->filterRemove.addr)) { return APP_STATUS_ENTRY_NOT_FOUND; } } break; #endif default: return APP_STATUS_UNKNOWN_COMMAND; } (void)size; return APP_STATUS_SUCESS; }