// 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); }
/** Send a ping packet (either request or response) to another node. param: pingTypeArg Which type of ping to send, either PING_REQ_FRAME or PING_RSP_FRAME. param: addr Short address of node to send ping */ void macPing(u8 pingTypeArg, u16 addr) { if (addr == macConfig.shortAddress) // Don't send to self return; if (!macConfig.associated) // Broadcast addr return; pingAddr = addr; pingType = pingTypeArg; debugMsgStr("\r\nmacPing to: "); debugMsgInt(pingAddr); debugMsgStr(" type: "); debugMsgInt(pingType); // 2 == request 3== response debugMsgStr("\r\n"); # if (NODE_TYPE == COORD) { u8 rpSent; rpSent = macSendRoutingPacket(addr); // First send a routing packet #if DEBUG==2 debugMsgStr("\r\nsetting up Alarm for ping response"); #endif macSetAlarm(rpSent ? MAC_RP_DELAY : 0, macDoPingRequest); // Then send the Ping (response) macConfig.busy = true; } # else { // End/router nodes macDoPingRequest(); macConfig.busy = true; } # endif }
/** This function is called when the MAC receives a packet that is addressed to this node. The packet is dispatched according to its contents. */ void macDataIndication(uint8_t* pFrame) { // Sort out the different types of data packets. ftData *frame = (ftData*)(((rx_frame_t*)pFrame)->data); /* #if (__arm__) volatile s16 queue; if(fnGetTCP_state(host_socket) == TCP_STATE_ESTABLISHED) { if( (frame->fcf != FCF_BEACONREQ) && (frame->fcf != FCF_ASSOC_REQ_DIRECT) && (frame->fcf != FCF_ASSOC_REQ_IND) ) { // ACK handling should occur in the tcpListener function in // rumtask.c. // fnSendBufTCP returns the number of bytes buffered if successful... queue = fnSendBufTCP(host_socket, (u8 *)"WIRELESSD", 9, TCP_BUF_SEND); if(telPrintReading && (queue > 0)) fnDebugMsg("\r\nWIRELESSD buffered for TCP"); else fnDebugMsg("\r\nWIRELESSD buffer problem"); queue = fnSendBufTCP(host_socket, mac_buffer_rx, mac_buffer_rx[0]+1, TCP_BUF_SEND); if(telPrintReading && (queue > 0)) fnDebugMsg("\r\nData indication buffered for TCP"); else fnDebugMsg("\r\nData indication buffer problem"); } } #endif */ switch (frame->type & 0x7f) // Mask high bit just in case it was somehow missed { case DATA_FRAME: // Plain old data, send it up the chain appDataIndication(); break; case DEBUG_FRAME: // Frame containing debug message, print it on coord if (NODETYPE == COORD && OTA_DEBUG && DEBUG) { debugMsgStr("\r\nNode "); debugMsgInt(frame->originAddr); debugMsgStr(": "); // Remove leading cr/lf's from string u8 *p = frame->payload; while (*p) { if (*p > ' ') break; p++; } debugMsgStr((char *)p); } break; case WAKE_NODE: // Wake up the end node. if (NODETYPE == ROUTER) { u8 addr = ((ftWake*)frame)->addr; // See if this is from parent or child if ((((ftWake*)frame)->srcAddr) == macConfig.parentShortAddress) // Set the flag to wake up the end node when it sends a packet macWakeChildNode(addr); } if (NODETYPE == ENDDEVICE) { // Wake yourself up now macConfig.sleeping = false; // Send parent a confirmation that we are awake macDataRequestInt(macConfig.parentShortAddress, 2, (u8*)&macConfig.shortAddress, WAKE_NODE); debugMsgStr("\r\nAwake"); } break; case PING_REQ_FRAME: // We got a ping request, let the app handle that appPingReq(frame->originAddr); break; case PING_RSP_FRAME: // We got a ping response, app will handle it appPingRsp(frame->originAddr); break; case DROP_CHILD_FRAME: // Coordinator is telling us to drop a child if (NODETYPE == ROUTER) macRemoveChild(*(u16*)(&frame->payload)); break; case DATA_FRAME_6LOWPAN: //6lowpan data indication if (IPV6LOWPAN == 1) //sixlowpan_DataIndication(frame, *mac_buffer_rx - 16); sixlowpan_DataIndication(frame, (((rx_frame_t*)pFrame)->length) - 16); break; default: break; } }
/** This function is called when the MAC receives a packet that is addressed to this node. The packet is dispatched according to its contents. */ void macDataIndication(u16 dest) { // Sort out the different types of data packets. ftData *frame = (ftData*)(mac_buffer_rx+1); u8 pl_len = *mac_buffer_rx - 16; #if DEBUG==2 debugMsgStr("\r\nmacDataIndication<-"); #endif switch (frame->type & 0x7f) // Mask high bit just in case it was somehow missed { case DATA_FRAME: // Data, send it up the chain appDataIndication(frame->payload, pl_len, (dest == BROADCASTADDR)); break; case DEBUG_FRAME: // Frame containing debug message, print it on coord if (NODE_TYPE == COORD && OTA_DEBUG && DEBUG) { debugMsgStr("\r\nNode "); debugMsgInt(frame->originAddr); debugMsgStr(": "); // Remove leading cr/lf's from string u8 *p = frame->payload; while (*p) { if (*p > ' ') break; p++; } debugMsgStr_d((char *)p); } break; case WAKE_NODE: // Wake up the end node. #if (NODE_TYPE == ROUTER) { u8 addr = ((ftWake*)frame)->addr; // See if this is from parent or child if ((((ftWake*)frame)->srcAddr) == macConfig.parentShortAddress) // Set the flag to wake up the end node when it sends a packet macWakeChildNode(addr); } #endif #if (NODE_TYPE == ENDDEVICE) /* also include BC_ENDDEVICE ?*/ { // Wake yourself up now macConfig.sleeping = false; // Send parent a confirmation that we are awake macDataRequestInt(macConfig.parentShortAddress,2, (u8*)&macConfig.shortAddress,WAKE_NODE); debugMsgStr("\r\nAwake"); } #endif break; case PING_REQ_FRAME: // We got a ping request, let the app handle that appPingReq((ftPing *) (mac_buffer_rx+1)); break; case PING_RSP_FRAME: // We got a ping response, app will handle it appPingRsp((ftPing *) (mac_buffer_rx+1)); break; #if (NODE_TYPE == ROUTER) case DROP_CHILD_FRAME: // Coordinator is telling us to drop a child macRemoveChild(*(u16*)(&frame->payload)); break; #endif default: break; } }