/** @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; } }
/** 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; }