Exemplo n.º 1
0
/*************************************************************************//**
*****************************************************************************/
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;
}
Exemplo n.º 3
0
/*************************************************************************//**
*****************************************************************************/
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
  }
}