// Target function to timer, sends ping packet after a delay // note that arguments are via static vars due to the indirect nature of the call static void macDoPingRequest(void) { ftPing frame; frame.fcf = FCF_DATA; frame.seq = macConfig.dsn++; frame.panid = macConfig.panId; frame.srcAddr = macConfig.shortAddress; frame.originAddr = macConfig.shortAddress; frame.finalDestAddr = pingAddr; frame.rssi = radioGetSavedRssiValue(); frame.lqi = radioGetSavedLqiValue(); frame.type = pingType; // Set high bit of type if we're sleeping if (macConfig.sleeping && NODE_TYPE == ENDDEVICE && NODE_SLEEP) frame.type |= 0x80; #if (NODE_TYPE == COORD) { #if DEBUG==2 debugMsgStr("\r\nin macDoPingRequest"); #endif // Find the top parentpin u8 addr = macGetTopParent(pingAddr); frame.destAddr = addr; // 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 #if DEBUG==2 debugMsgStr("\r\ncalling macHoldFrame for ping response"); #endif macHoldFrame(addr, (u8*)&frame, sizeof(ftPing)); // Don't send frame right now return; } else { #if DEBUG==2 debugMsgStr("\r\n child: "); debugMsgInt(addr); debugMsgStr(" not sleeping"); #endif } } #else // End/router nodes frame.destAddr = macConfig.parentShortAddress; #endif #if DEBUG==2 debugMsgStr(" sending Ping Response now\n\r"); #endif radioSendData(sizeof(ftPing), (u8*)&frame); }
// Target function to timer, sends ping packet after a delay void mp(void) { uint8_t* pFrame = bmm_buffer_alloc(); if(pFrame != NULL) { ftPing *frame = (ftPing*)(((rx_frame_t*)pFrame)->data); frame->fcf = FCF_DATA; frame->seq = macConfig.dsn++; frame->panid = macConfig.panId; frame->srcAddr = macConfig.shortAddress; frame->originAddr = macConfig.shortAddress; frame->finalDestAddr = pingAddr; frame->type = pingType; frame->rssi = radioGetSavedRssiValue(); frame->lqi = radioGetSavedLqiValue(); ((rx_frame_t*)pFrame)->length = sizeof(ftPing); if (NODETYPE == COORD) { // Find the top parent u8 addr = macGetTopParent(pingAddr); frame->destAddr = addr; // See if the child is sleeping (only the coord sends directly to a child node) if (RUMSLEEP && macIsChild(addr) && macIsChildSleeping(addr)) { // Send it later, after child is awake macHoldFrame(addr, pFrame); // buffer is freed inside macHoldFrame() // Don't send frame right now return; } } else // End/router nodes { frame->destAddr = macConfig.parentShortAddress; } event_object_t event; event.event = MAC_EVENT_SEND; event.data = pFrame; event.callback = 0; // save Event mac_put_event(&event); } }
/** @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; }