void loop(void) { // Call mesh.update to keep the network updated mesh.update(); #if NODE_ID == 0 // In addition, keep the 'DHCP service' running on the master node so addresses will // be assigned to the sensor nodes mesh.DHCP(); #endif // Check for incoming data from the sensors while (network.available()) { RF24NetworkHeader header; uint8_t payload[40]; //network.peek(header); boolean ok = network.read(header, &payload, sizeof(payload)); if (ok) { for (int i = 0; i < taskCount; ++i) { ok |= tasks[i]->receiveMessage(header, payload); } if (!ok) { printf_P(PSTR("Received unknown message: %s\r\n"), header.toString()); } } else { printf_P(PSTR("Error reading network.")); } } for (int i = 0; i < taskCount; ++i) { tasks[i]->updateState(); } }
void RF24Mesh::handlePacket() { int count=0; // Is there anything ready for us? while ( available() ) { IF_SERIAL_DEBUG(printf_P(PSTR("There are available received message %d \n\r"),count++)); // If so, take a look at it RF24NetworkHeader header; peek(header); // Dispatch the message to the correct handler. switch (header.type) { case 'J': handle_JoinMessage(header); break; case 'W': handle_WelcomeMessage(header); break; case 'D': handle_DataMessage(header); break; case 'F': handle_ForwardData(header); break; case 'U': handle_UpdateWeightMessage(header); break; default: printf_P(PSTR("*** WARNING *** Unknown message type %s\n\r"),header.toString()); read(header,0,0); break; }; } }
int RF24Mesh::write() { IF_SERIAL_DEBUG(printf_P(PSTR("%lu: write to air \n\r"),rTable.getMillis())); bool result = false; if ( send_available() ) { shiftleft(send_queue, frame_size, frame_buffer, send_frame_p); // Move the pointer back one in the queue send_frame_p -= frame_size; RF24NetworkHeader h; // Copy the next available frame from the queue into the provided buffer memcpy(&h,frame_buffer,sizeof(RF24NetworkHeader)); result = write(rTable.getMac(h.to_node)); rTable.sentData(h); IF_SERIAL_DEBUG(printf_P(PSTR("%lu: NET *RF24*Mesh::sent to Air to mac: %lx (%s)\n\r"),rTable.getMillis(), rTable.getMac(h.to_node), h.toString())); } return result; }
uint8_t RF24Network::update(void) { // if there is data ready uint8_t pipe_num; uint8_t returnVal = 0; // If bypass is enabled, continue although incoming user data may be dropped // Allows system payloads to be read while user cache is full // Incoming Hold prevents data from being read from the radio, preventing incoming payloads from being acked #if !defined (RF24_LINUX) if(!(networkFlags & FLAG_BYPASS_HOLDS)){ if( (networkFlags & FLAG_HOLD_INCOMING) || (next_frame-frame_queue) + 34 > MAIN_BUFFER_SIZE ){ if(!available()){ networkFlags &= ~FLAG_HOLD_INCOMING; }else{ return 0; } } } #endif while ( radio.isValid() && radio.available(&pipe_num) ){ #if defined (ENABLE_DYNAMIC_PAYLOADS) if( (frame_size = radio.getDynamicPayloadSize() ) < sizeof(RF24NetworkHeader)){ delay(10); continue; } #else frame_size=32; #endif // Dump the payloads until we've gotten everything // Fetch the payload, and see if this was the last one. radio.read( frame_buffer, frame_size ); // Read the beginning of the frame as the header RF24NetworkHeader *header = (RF24NetworkHeader*)(&frame_buffer); #if defined (RF24_LINUX) IF_SERIAL_DEBUG(printf_P("%u: MAC Received on %u %s\n\r",millis(),pipe_num,header->toString())); if (frame_size) { IF_SERIAL_DEBUG_FRAGMENTATION_L2(printf("%u: FRG Rcv frame size %i\n",millis(),frame_size);); IF_SERIAL_DEBUG_FRAGMENTATION_L2(printf("%u: FRG Rcv frame ",millis()); const char* charPtr = reinterpret_cast<const char*>(frame_buffer); for (uint16_t i = 0; i < frame_size; i++) { printf("%02X ", charPtr[i]); }; printf("\n\r")); } #else IF_SERIAL_DEBUG(printf_P(PSTR("%lu: MAC Received on %u %s\n\r"),millis(),pipe_num,header->toString())); IF_SERIAL_DEBUG(const uint16_t* i = reinterpret_cast<const uint16_t*>(frame_buffer + sizeof(RF24NetworkHeader));printf_P(PSTR("%lu: NET message %04x\n\r"),millis(),*i)); #endif // Throw it away if it's not a valid address if ( !is_valid_address(header->to_node) ){ continue; } uint8_t returnVal = header->type; // Is this for us? if ( header->to_node == node_address ){ if(header->type == NETWORK_PING){ continue; } if(header->type == NETWORK_ADDR_RESPONSE ){ uint16_t requester = 04444; if(requester != node_address){ header->to_node = requester; write(header->to_node,USER_TX_TO_PHYSICAL_ADDRESS); delay(10); write(header->to_node,USER_TX_TO_PHYSICAL_ADDRESS); //printf("Fwd add response to 0%o\n",requester); continue; } } if(header->type == NETWORK_REQ_ADDRESS && node_address){ //printf("Fwd add req to 0\n"); header->from_node = node_address; header->to_node = 0; write(header->to_node,TX_NORMAL); continue; } if( (returnSysMsgs && header->type > 127) || header->type == NETWORK_ACK ){ IF_SERIAL_DEBUG_ROUTING( printf_P(PSTR("%lu MAC: System payload rcvd %d\n"),millis(),returnVal); ); //if( (header->type < 148 || header->type > 150) && header->type != NETWORK_MORE_FRAGMENTS_NACK && header->type != EXTERNAL_DATA_TYPE && header->type!= NETWORK_LAST_FRAGMENT){ if( header->type != NETWORK_FIRST_FRAGMENT && header->type != NETWORK_MORE_FRAGMENTS && header->type != NETWORK_MORE_FRAGMENTS_NACK && header->type != EXTERNAL_DATA_TYPE && header->type!= NETWORK_LAST_FRAGMENT){ return returnVal; } }
uint8_t RF24Network::update(void) { // if there is data ready uint8_t pipe_num; uint8_t returnVal = 0; while ( radio.isValid() && radio.available(&pipe_num) ) { if( (frame_size = radio.getDynamicPayloadSize() ) < sizeof(RF24NetworkHeader)){ delay(10); continue; } // Dump the payloads until we've gotten everything // Fetch the payload, and see if this was the last one. //radio.read( frame_buffer, sizeof(frame_buffer) ); radio.read( frame_buffer, frame_size ); // Read the beginning of the frame as the header //RF24NetworkHeader& header = reinterpret_cast<RF24NetworkHeader&>(frame_buffer); RF24NetworkHeader *header = (RF24NetworkHeader*)(&frame_buffer); #if defined (RF24_LINUX) IF_SERIAL_DEBUG(printf_P("%u: MAC Received on %u %s\n\r",millis(),pipe_num,header->toString())); if (frame_size) { IF_SERIAL_DEBUG_FRAGMENTATION_L2(printf("%u: FRG Rcv frame size %i\n",millis(),frame_size);); IF_SERIAL_DEBUG_FRAGMENTATION_L2(printf("%u: FRG Rcv frame ",millis()); const char* charPtr = reinterpret_cast<const char*>(frame_buffer); for (size_t i = 0; i < frame_size; i++) { printf("%02X ", charPtr[i]); }; printf("\n\r")); } #else IF_SERIAL_DEBUG(printf_P(PSTR("%lu: MAC Received on %u %s\n\r"),millis(),pipe_num,header->toString())); IF_SERIAL_DEBUG(const uint16_t* i = reinterpret_cast<const uint16_t*>(frame_buffer + sizeof(RF24NetworkHeader));printf_P(PSTR("%lu: NET message %04x\n\r"),millis(),*i)); #endif // Throw it away if it's not a valid address if ( !is_valid_address(header->to_node) ){ continue; } /* #if defined (RF24_LINUX) RF24NetworkFrame frame = RF24NetworkFrame(*header,frame_buffer+sizeof(RF24NetworkHeader),frame_size-sizeof(RF24NetworkHeader)); #else RF24NetworkFrame frame = RF24NetworkFrame(*header,frame_size-sizeof(RF24NetworkHeader)); frame.message_buffer = frame_buffer+sizeof(RF24NetworkHeader); #endif*/ uint8_t returnVal = header->type; //printf("got\n"); // Is this for us? if ( header->to_node == node_address ){ if(header->type == NETWORK_PING){ continue; } if(header->type == NETWORK_ADDR_RESPONSE ){ uint16_t requester = frame_buffer[8]; requester |= frame_buffer[9] << 8; if(requester != node_address){ header->to_node = requester; write(header->to_node,USER_TX_TO_PHYSICAL_ADDRESS); delay(15); write(header->to_node,USER_TX_TO_PHYSICAL_ADDRESS); //printf("Fwd add response to 0%o\n",requester); continue; } } if(header->type == NETWORK_REQ_ADDRESS && node_address){ //printf("Fwd add req to 0\n"); header->from_node = node_address; header->to_node = 0; write(header->to_node,TX_NORMAL); continue; } if( (returnSysMsgs && header->type > 127) || header->type == NETWORK_ACK ){ IF_SERIAL_DEBUG_ROUTING( printf_P(PSTR("%lu MAC: System payload rcvd %d\n"),millis(),returnVal); ); //if( (header->type < 148 || header->type > 150) && header->type != NETWORK_MORE_FRAGMENTS_NACK && header->type != EXTERNAL_DATA_TYPE && header->type!= NETWORK_LAST_FRAGMENT){ if( header->type != NETWORK_FIRST_FRAGMENT && header->type != NETWORK_MORE_FRAGMENTS && header->type != NETWORK_MORE_FRAGMENTS_NACK && header->type != EXTERNAL_DATA_TYPE && header->type!= NETWORK_LAST_FRAGMENT){ return returnVal; } }
std::string toString_wrap(RF24NetworkHeader& ref) { return std::string(ref.toString()); }
void StatusCallback::incomingData(RF24NetworkHeader packet) { receivedPacket++; printf_P(PSTR("%lu: Callback %dth data received (%s)\n\r"),rTable.getMillis(),receivedPacket, packet.toString()); }
void RF24Mesh::handle_ForwardData(RF24NetworkHeader& header) { uint64_t message; read(header,NULL,0); if(header.from_node == rTable.getCurrentNode().ip) IF_SERIAL_DEBUG(printf_P(PSTR("%lu: handle_DataMessage APP I got my own data omitting. (%s)\n\r"),rTable.getMillis(),header.toString())); else { callback.incomingData(header); T_IP ip = rTable.getShortestRouteNode().ip; unsigned char type = 'D'; header.source_data.weight++; header.prev_node = header.from_node; header.from_node = rTable.getCurrentNode().ip; header.to_node = ip; if (ip != rTable.getMasterNode().ip) { type = 'F'; printf_P(PSTR("%lu: APP handle_ForwardData short ip: %d masterip: %d"),rTable.getMillis(),ip,rTable.getMasterNode().ip); } header.type = type; write(header); } }
/** * Handle an 'N' message, the active node list */ void RF24Mesh::handle_DataMessage(RF24NetworkHeader& header) { //uint64_t message; read(header,NULL,0); if(header.from_node == rTable.getCurrentNode().ip) IF_SERIAL_DEBUG(printf_P(PSTR("%lu: handle_DataMessage APP I got my own data omitting.(%s)\n\r"),rTable.getMillis(), header.toString())); else { callback.incomingData(header); } }
/** * Handle a 'T' message * * Add the node to the list of active nodes */ void RF24Mesh::handle_WelcomeMessage(RF24NetworkHeader& header) { //IP_MAC message; read(header,0,0); IF_SERIAL_DEBUG(printf_P(PSTR("%lu: handle_WelcomeMessage (%s) \n\r"),rTable.getMillis(),header.toString())); // if(isState(SENDJOIN) || isState(JOINED)) { // If this message is from ourselves or the base, don't bother adding it to the active nodes. if ( header.from_node != this->node_address) if(rTable.addNearNode(header.source_data)) { rTable.setMillis(header.payload); IF_SERIAL_DEBUG(printf_P(PSTR("%lu: handle_WelcomeMessage, update join status\n\r"),rTable.getMillis())); setState(NEW_JOINED); } rTable.printTable(); } // else { // IF_SERIAL_DEBUG(printf_P(PSTR("%lu: OMITTING WelcomeMessage (%s) \n\r"),rTable.getMillis(),header.toString())); } }
void RF24Mesh::handle_UpdateWeightMessage(RF24NetworkHeader& header) { read(header,0,0); IF_SERIAL_DEBUG(printf_P(PSTR("%lu: handle_UpdateWeightMessage (%s) \n\r"),rTable.getMillis(),header.toString())); if(isState(JOINED)) { // If this message is from ourselves or the base, don't bother adding it to the active nodes. if (header.from_node != rTable.getShortestRouteNode().ip && header.prev_node != getMyIP()) { IF_SERIAL_DEBUG(printf_P(PSTR("%lu: handle_U farkli node kaydet ve cevap ver\n\r"),rTable.getMillis())); bool shortenedPath = rTable.addNearNode(header.source_data); if(shortenedPath) { send_UpdateWeight(); } } else //msg came from my child about me; omit the msg { } rTable.printTable(); } else if(isState(NJOINED)) { IF_SERIAL_DEBUG(printf_P(PSTR("%lu: handle_U farkli node kaydet ve cevap ver\n\r"),rTable.getMillis())); bool shortenedPath = rTable.addNearNode(header.source_data); if(shortenedPath) { setState(JOINED); last_join_time = millis(); send_UpdateWeight(); } } }
/** * Handle a 'J' message * * Add the node to the list of active nodes */ void RF24Mesh::handle_JoinMessage(RF24NetworkHeader& header) { read(header,0,0); IF_SERIAL_DEBUG(printf_P(PSTR("%lu: handle_JoinMessage (%s) \n\r"),rTable.getMillis(),header.toString())); if(state == JOINED) { // If this message is from ourselves or the base, don't bother adding it to the active nodes. if ( header.from_node != rTable.getShortestRouteNode().ip ) { send_WelcomeMessage(header.source_data.ip); } else //benim bagli oldugum node'dan join mesaji gelmis { IF_SERIAL_DEBUG(printf_P(PSTR("%lu: bagli oldugum node Join mesaji gonderdi. Demekki hattan dustum.**********\n\r"),rTable.getMillis())); setState(NJOINED); rTable.cleanTable(); } rTable.printTable(); } // if(available()) printf_P(PSTR("%lu: there are more messages \n\r"),rTable.getMillis()); // else printf_P(PSTR("%lu: there is not more message \n\r"),rTable.getMillis()); }
bool RF24Mesh::write(RF24NetworkHeader& header) { // Fill out the header header.from_node = rTable.getCurrentNode().ip; IF_SERIAL_DEBUG(printf_P(PSTR("%lu: NET 2 Sending message(%s) \n\r"),rTable.getMillis(),header.toString())); // Build the full frame to send memcpy(frame_buffer,&header,sizeof(RF24NetworkHeader)); // If the user is trying to send it to himself if ( header.to_node == rTable.getCurrentNode().ip ) // Just queue it in the received queue return enqueue(); else // Otherwise send it out over the air return send_enqueue(); //write(mac); return write(rTable.getMac(header.to_node)); }
size_t RF24Mesh::read(RF24NetworkHeader& header,void* message, size_t maxlen) { size_t bufsize = 0; if ( available() ) { // Move the pointer back one in the queue receive_frame -= frame_size; uint8_t* frame = receive_frame; // How much buffer size should we actually copy? bufsize = min(maxlen,frame_size-sizeof(RF24NetworkHeader)); // Copy the next available frame from the queue into the provided buffer memcpy(&header,frame,sizeof(RF24NetworkHeader)); memcpy(message,frame+sizeof(RF24NetworkHeader),bufsize); IF_SERIAL_DEBUG(printf_P(PSTR("%lu: *****NET _RF24Mesh::read Received (%s)\n\r"),rTable.getMillis(),header.toString())); } return bufsize; }