示例#1
0
/**
    @brief The macsixlowpanDataRequest function is used to send a frame over
    the air to another node.  Any node type can call this function.

    @param addr Short address of the destination node.

    @param len The length of the packet in bytes.

    @param data Pointer to the data to be sent.

    @param type Type of frame to be sent
 */
static void macDataRequestInt(u16 addr, u8 len, u8 * data, u8 type)
{
   u8 rpSent; // Was a routing packet sent?

   // Don't send to self
   if (addr == macConfig.shortAddress || addr == BROADCASTADDR)
   {
      return;
   }

   // This node has no short address
   if (!macConfig.associated)
   {
      return;
   }

   uint8_t* pFrame = bmm_buffer_alloc();

   if(pFrame != NULL)
   {
      // Create a struct pointer to the global variable...
      //ftData *data_frame = (ftData*)(mac_buffer_tx+1);

      ftData *data_frame = (ftData*)(((rx_frame_t*)pFrame)->data);

      // Build the frame.
      data_frame->fcf = FCF_DATA;
      data_frame->seq = macConfig.dsn++;
      data_frame->panid = macConfig.panId;
      data_frame->srcAddr = macConfig.shortAddress;
      data_frame->finalDestAddr = addr;
      data_frame->originAddr = macConfig.shortAddress;

      // send a routing packet if necessary
      rpSent = macSendRoutingPacket(addr);

      if (NODETYPE == COORD)
      {
         // Find the child node that can route this packet
         u16 child = addr;
         u16 parent = macGetParent(child);
         while (parent != DEFAULT_COORD_ADDR)
         {
            child = parent;
            parent = macGetParent(child);
         }
         // send to child node that can route this packet
         data_frame->destAddr = child;
      }
      else
         // All data is send to parent, unless this is a wakeup frame
         if (type == WAKE_NODE)
            data_frame->destAddr = addr;
         else
            data_frame->destAddr = macConfig.parentShortAddress;

      // Frame type is data
      if (macConfig.sleeping && NODETYPE == ENDDEVICE && RUMSLEEP)
      {
         type |= 0x80; // Set high bit of type if we're sleeping
      }

      data_frame->type = type;

      // Copy the payload data to frame. (note: this creates smaller code than using memcpy!!)
      u8 i;
      for(i=0; i<len; i++){
         ((u8*)&data_frame->payload)[i] = *data++;
      }

      // Check addresses again - addr will be different now -> Don't send to self
      if (data_frame->destAddr == macConfig.shortAddress || data_frame->destAddr == BROADCASTADDR)
      {
         bmm_buffer_free(pFrame);
         return;
      }

      ((rx_frame_t*)pFrame)->length = len + ftDataHeaderSize; // save length away

      if (NODETYPE == COORD)
      {
         // See if the child is sleeping (only the coord sends directly to a child node)
         if (RUMSLEEP && macIsChild(addr) && macIsChildSleeping(addr) && VLP) // Send it later, after child is awake
         {
            macHoldFrame(addr, pFrame);
            // buffer is freed inside macHoldFrame()
         }
         else // Node is not sleeping child, send it now.
         {
            event_object_t event;
            event.event = MAC_EVENT_SEND;
            event.data = pFrame;
            event.callback = 0;

            // save Event
            mac_put_event(&event);
         }
      }
      else
      {
         event_object_t event;
         event.event = MAC_EVENT_SEND;
         event.data = pFrame;
         event.callback = 0;

         // save Event
         mac_put_event(&event);
      }
      macConfig.busy = true;
   }
}
示例#2
0
/**
      The macsixlowpanDataRequest function is used to send a frame over
    the air to another node.  Any node type can call this function.

    param:  addr Short address of the destination node.

    param:  len The length of the packet in bytes.

    param:  data Pointer to the data to be sent.

    param:  type Type of frame to be sent
*/
static void
macDataRequestInt(u16 addr, u8 len, u8 * data, u8 type)
{
    // Create a struct pointer to the global variable...
    ftData *data_frame = (ftData*)(mac_buffer_tx+1);
    u8 rpSent; // Was a routing packet sent?


    if (addr == macConfig.shortAddress || addr == BROADCASTADDR)
    {
        // Don't send to self
    	debugMsgStr("\r\nSelf addressed or Brodcast: nothing sent!");
        return;
    }
    if (!macConfig.associated)
        // This node has no short address
        return;
#if DEBUG==2
    debugMsgStr("\r\nmacDataRequest->");
#endif
    // Build the frame.
    data_frame->fcf = FCF_DATA;
    data_frame->seq = macConfig.dsn++;
    data_frame->panid = macConfig.panId;
    data_frame->srcAddr = macConfig.shortAddress;
    data_frame->finalDestAddr = addr;
    data_frame->originAddr = macConfig.shortAddress;

    // send a routing packet if necessary
    rpSent = macSendRoutingPacket(addr);

#if (NODE_TYPE == COORD)
    {
        // Find the child node that can route this packet
        u16 child = addr;
        u16 parent = macGetParent(child);
        while (parent != DEFAULT_COORD_ADDR)
        {
            child = parent;
            parent = macGetParent(child);
        }
        // send to child node that can route this packet
        data_frame->destAddr = child;
    }
#   else
    {
        // All data is send to parent, unless this is a wakeup frame
        if (type == WAKE_NODE)
            data_frame->destAddr = addr;
        else
        	data_frame->destAddr = macConfig.parentShortAddress;
    }
#endif
    // Frame type is data
    data_frame->type = type;

    // Set high bit of type if we're sleeping
    if (macConfig.sleeping && NODE_TYPE == ENDDEVICE && NODE_SLEEP)
       	data_frame->type |= 0x80;  // Indicate that this ENDdevice is sleeping

    // Copy the payload data to frame. (note: this creates smaller code than using memcpy!!)
    u8 i;
    for(i=0; i<len; i++)
        ((u8*)&data_frame->payload)[i] = *data++;

    // Check addresses again - addr will be different now
    if (data_frame->destAddr == macConfig.shortAddress ||
        data_frame->destAddr == BROADCASTADDR)
        // Don't send to self
        return;

    // send data to radio, after some time delay
    *mac_buffer_tx = len + ftDataHeaderSize; // save length away
#if (NODE_TYPE == COORD)
    {
        // See if the child is sleeping (only the coord sends directly to a child node)
        if (NODE_SLEEP && macIsChild(addr) && macIsChildSleeping(addr) )
            // Send it later, after child is awake
            macHoldFrame(addr, (u8*)data_frame, (u8)*mac_buffer_tx);
        else
        {
            // Node is not sleeping child, send it now.
#if DEBUG==2
        	debugMsgStr("-- macSetAlarm set");
#endif
        	macSetAlarm(rpSent ? MAC_RP_DELAY : MAC_DATA_DELAY, mdr_timer);
        }
    }
#  else
        macSetAlarm((type==WAKE_NODE || type == DEBUG_FRAME) ? 0 : MAC_DATA_DELAY, mdr_timer);
#endif
    macConfig.busy = true;
}