/** * 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()); }
void RF24Mesh::listenRadio() { long stime = millis(); bool wait = true; while(wait) { // if there is data ready uint8_t pipe_num; while ( radio.available(&pipe_num) ) { IF_SERIAL_DEBUG(printf_P(PSTR("%lu: NET radio available pipe: %x\n\r"),rTable.getMillis(),pipe_num)); // Dump the payloads until we've gotten everything boolean done = false; while (!done) { // Fetch the payload, and see if this was the last one. done = radio.read( frame_buffer, sizeof(frame_buffer) ); IF_SERIAL_DEBUG(printf_P(PSTR("%lu: done is %s"),rTable.getMillis(), (done ? "true":"false"))); // Read the beginning of the frame as the header RF24NetworkHeader& header = * reinterpret_cast<RF24NetworkHeader*>(frame_buffer); IF_SERIAL_DEBUG(printf_P(PSTR("%lu: MAC Received on pipe %u %s\n\r"),rTable.getMillis(),pipe_num,header.toString())); // Is this for us? if ( header.to_node == rTable.getCurrentNode().ip || header.to_node == rTable.getBroadcastNode().ip) { IF_SERIAL_DEBUG(printf_P(PSTR("%lu: MAC Received message for me, enqueuing \n\r"),rTable.getMillis())); // Add it to the buffer of frames for us enqueue(); //goker handlePacket(); } else { printf_P(PSTR("%lu: MAC Received message *****NOT for me**, *WARNING* wrong message not forwarding %d != %d \n\r"), rTable.getMillis(), header.to_node, rTable.getCurrentNode().ip); } } } if(state == SENDJOIN) { wait = (millis() - stime > JOIN_WAIT_WELCOME) ? false : true; } else { //wait = (millis()-stime>1000)?false:true; wait = false; } } }
//------------------------------------------------------------------------------ // //------------------------------------------------------------------------------ int mbus_serial_send_frame(SoftwareSerial *handle, mbus_frame *frame) { uint8_t buff[PACKET_BUFF_SIZE]; int len, ret; IF_SERIAL_DEBUG(printf_P(PSTR("%s: Entered \n"), "mbus_serial_send_frame")); if (handle == NULL || frame == NULL) { return -1; } if ((len = mbus_frame_pack(frame, buff, sizeof(buff))) == -1) { IF_SERIAL_DEBUG(printf_P(PSTR("%s: mbus_frame_pack failed\n"), "mbus_serial_send_frame")); return -1; } //#ifdef MBUS_SERIAL_DEBUG // if debug, dump in HEX form to stdout what we write to the serial port printf_P(PSTR("%s: Dumping M-Bus frame [%d bytes]: "), __PRETTY_FUNCTION__, len); for (int i = 0; i < len; i++) { printf_P(PSTR("%.2X "), buff[i]); } printf_P(PSTR("\n")); //#endif if ((ret = handle->write(buff, len)) == len) { // // call the send event function, if the callback function is registered // if (_mbus_send_event) _mbus_send_event(MBUS_HANDLE_TYPE_SERIAL, buff, len); } else { IF_SERIAL_DEBUG(printf_P(PSTR("%s: Failed to write frame to socket (ret = %d: )\n"), "mbus_serial_send_frame", ret)); return -1; } // // wait until complete frame has been transmitted // handle->flush(); return 0; }
void RF24Mesh::setState(STATES s) { IF_SERIAL_DEBUG(printf_P(PSTR("setState %d\n\r"), s)); state = s; state_time = millis(); }
uint8_t RF24::write_register(uint8_t reg, uint8_t value) { uint8_t status; IF_SERIAL_DEBUG(printf_P(PSTR("write_register(%02x,%02x)\r\n"),reg,value)); #if defined (RF24_LINUX) csn(LOW); uint8_t * prx = spi_rxbuff; uint8_t * ptx = spi_txbuff; *ptx++ = ( W_REGISTER | ( REGISTER_MASK & reg ) ); *ptx = value ; bcm2835_spi_transfernb( (char *) spi_txbuff, (char *) spi_rxbuff, 2); status = *prx++; // status is 1st byte of receive buffer #elif defined (__arm__) && !defined ( CORE_TEENSY ) status = _SPI.transfer(csn_pin, W_REGISTER | ( REGISTER_MASK & reg ), SPI_CONTINUE); _SPI.transfer(csn_pin,value); #else csn(LOW); status = _SPI.transfer( W_REGISTER | ( REGISTER_MASK & reg ) ); _SPI.transfer(value); csn(HIGH); #endif return status; }
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); } }
// This checks the Serial stream for characters, and assembles them into a buffer. // When the terminator character (default '\r') is seen, it starts parsing the // buffer for a prefix command, and calls handlers setup by addCommand() member bool SerialCommand::readSerial() { // If we're using the Hardware port, check it. Otherwise check the user-created SoftwareSerial Port #ifdef SERIALCOMMAND_HARDWAREONLY while (Serial.available() > 0) #else while ((usingSoftwareSerial==0 && Serial.available() > 0) || (usingSoftwareSerial==1 && SoftSerial->available() > 0) ) #endif { if (!usingSoftwareSerial) { // Hardware serial port inChar=Serial.read(); // Read single available character, there may be more waiting } else { #ifndef SERIALCOMMAND_HARDWAREONLY // SoftwareSerial port inChar = SoftSerial->read(); // Read single available character, there may be more waiting #endif } SERIAL("%c", inChar); // Echo back to serial stream if (inChar == '\r' || inChar == '\n') { // Check for the terminator meaning end of command string IF_SERIAL_DEBUG(SERIAL_LN("Received: %s", buffer)); return scanStateMachine(); } else if (isprint(inChar)) { // Only printable characters into the buffer buffer[bufPos++] = inChar; // Put character into buffer if (bufPos > SERIALCOMMANDBUFFER-1) bufPos=0; // wrap buffer around if full } } return true; }
uint8_t RF24::write_register(uint8_t reg, uint8_t value) { uint8_t status; IF_SERIAL_DEBUG(printf_P(PSTR("write_register(%02x,%02x)\r\n"),reg,value)); #if defined (RF24_LINUX) csn(LOW); uint8_t * prx = spi_rxbuff; uint8_t * ptx = spi_txbuff; *ptx++ = ( W_REGISTER | ( REGISTER_MASK & reg ) ); *ptx = value ; _SPI.transfernb( (char *) spi_txbuff, (char *) spi_rxbuff, 2); status = *prx++; // status is 1st byte of receive buffer #else beginTransaction(); status = _SPI.transfer( W_REGISTER | ( REGISTER_MASK & reg ) ); _SPI.transfer(value); endTransaction(); #endif return status; }
/** * Send a 'T' message, the current time */ bool RF24Mesh::send_SensorData(uint8_t data[16]) { if(rTable.amImaster()) { IF_SERIAL_DEBUG(printf_P(PSTR("%lu: send_SensorData, since I am master i do not send to myself ------------\n\r"),rTable.getMillis())); return true; } if(state != JOINED) { printf_P(PSTR("%lu: send_SensorData, I havent joined yet\n\r"),rTable.getMillis()); callback.sendingFailed(0); return false; } T_IP ip = rTable.getShortestRouteNode().ip; unsigned char type = 'D'; if (ip != rTable.getMasterNode().ip) { type = 'F'; IF_SERIAL_DEBUG(printf_P(PSTR("%lu: APP Send_SersorData short ip: %d masterip: %d"),rTable.getMillis(),ip,rTable.getMasterNode().ip)); } RF24NetworkHeader header(ip, type, data ); header.source_data.ip = rTable.getCurrentNode().ip; //source ip header.source_data.weight = 0; //not important IF_SERIAL_DEBUG(printf_P(PSTR("---------------------------------\n\r"))); printf_P(PSTR("%lu: APP Sending send_SensorData %s ...\n\r"),rTable.getMillis(), header.toString()); bool result = write(header); int trycount=0; while (!result) { if(!rTable.removeUnreacheable(rTable.getShortestRouteNode()))//There are no neighbour nodes { setState(NJOINED); return false; } IF_SERIAL_DEBUG(printf_P(PSTR("%lu: APP Repeating failed send_SensorData, (%s)"),rTable.getMillis(),header.toString())); result = write(header); trycount++; if(trycount > 10) return false; } return result; }
/** * Send a 'T' message, the current time */ bool RF24Mesh::send_JoinMessage() { uint64_t data = 0; RF24NetworkHeader header(rTable.getBroadcastNode().ip, 'J', data, rTable.getCurrentNode().ip); header.source_data.ip = rTable.getCurrentNode().ip; header.source_data.weight = rTable.getCurrentNode().weight; IF_SERIAL_DEBUG(printf_P(PSTR("%lu:Sending join message (%s) \n\r"),rTable.getMillis(),header.toString())); return write(header); }
void SerialCommand::SetStateMachine(const StateMachine_t *newSM, int sizeSM, uint8_t initState) { CommandList = newSM; numCommand = sizeSM; currentCommand = 0; currentState = initState; prevState = initState; clearBuffer(); IF_SERIAL_DEBUG(SERIAL_LN("Setup State Machine of %d items with initial state %d", sizeSM, initState)); }
bool SerialCommand::scanStateMachine() { if( !CommandList ) return false; bool bRunCmd = true; boolean matched = false; bufPos = 0; // Reset to start of buffer if( !token ) { token = first(); // Search for command at start of buffer } else { token = next(); } int i = findFirstCommand(currentState); for (; i<numCommand; i++) { if( currentState != (uint8_t)(CommandList[i].state) ) break; // Compare the found event against the list of known events in the same state for a match if (strlen(CommandList[i].event) == 0 || strnicmp(token, CommandList[i].event, SERIALCOMMANDBUFFER) == 0) { currentCommand = i; matched = true; prevState = currentState; currentState = (uint8_t)(CommandList[i].next); // Change to the next state IF_SERIAL_DEBUG(SERIAL_LN("Matched Command: %s in state %d, index=%d", token, currentState, i)); // Execute the stored handler function for the command if( CommandList[i].function ) { bRunCmd = (*CommandList[i].function)(token); } else { bRunCmd = callbackCommand(token); } clearBuffer(); break; } } // No macthed item found if (!matched) { if( defaultHandler ) { bRunCmd = (*defaultHandler)(token); } else { bRunCmd = callbackDefault(token); } clearBuffer(); } return bRunCmd; }
bool RF24Mesh::send_UpdateWeight() { uint64_t data = 0; RF24NetworkHeader header(rTable.getBroadcastNode().ip, 'U', data, rTable.getCurrentNode().ip); header.source_data.ip = rTable.getCurrentNode().ip; header.source_data.weight = rTable.getCurrentNode().weight; header.prev_node = rTable.getShortestRouteNode().ip; IF_SERIAL_DEBUG(printf_P(PSTR("%lu:Sending update weight (%s) \n\r"),rTable.getMillis(),header.toString())); return write(header); }
bool RF24Mesh::enqueue(void) { bool result = false; IF_SERIAL_DEBUG(printf_P(PSTR("%lu: NET Enqueue @%x "),rTable.getMillis(),receive_frame-receive_queue)); // Copy the current frame into the frame queue if ( receive_frame < receive_queue + sizeof(receive_queue) ) { memcpy(receive_frame,frame_buffer, frame_size ); receive_frame += frame_size; result = true; IF_SERIAL_DEBUG(printf_P(PSTR("ok\n\r"))); } else { printf_P(PSTR("failed\n\r")); } return result; }
uint8_t RF24_write_register(RF24* rf24, uint8_t reg, uint8_t value) { uint8_t status; IF_SERIAL_DEBUG(printf_P(PSTR("write_register(%02x,%02x)\r\n"),reg,value)); RF24_csn(rf24, LOW); status = rf24->spi->transfer( W_REGISTER | ( REGISTER_MASK & reg ) ); rf24->spi->transfer(value); RF24_csn(rf24, HIGH); return status; }
bool RF24Mesh::send_enqueue() { bool result = false; IF_SERIAL_DEBUG(printf_P(PSTR("%lu: NET Send Enqueue @%x "),rTable.getMillis(),send_frame_p-send_queue)); // Copy the current frame into the frame queue if (send_frame_p < send_queue + sizeof(send_queue)) { memcpy(send_frame_p, frame_buffer, frame_size); send_frame_p += frame_size; result = true; IF_SERIAL_DEBUG(printf_P(PSTR("copied to send buffer\n\r"))); } else { printf_P(PSTR("*******WARNING!!!!!!******* failed to write send queue Memory is not enough for message buffer\n\r")); } return result; }
/** * 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); } }
uint8_t RF24::write_register(uint8_t reg, uint8_t value) { uint8_t status; IF_SERIAL_DEBUG(printf_P(PSTR("write_register(%02x,%02x)\n\r"),reg,value)); csn(LOW); status = SPI.transfer( W_REGISTER | ( REGISTER_MASK & reg ) ); SPI.transfer(value); csn(HIGH); return status; }
uint8_t RF24::write_register(uint8_t reg, uint8_t value) { uint8_t status; IF_SERIAL_DEBUG(printf("write_register(%02x,%02x)\r\n", reg, value)); csn(LOW); status = spi->transfer( W_REGISTER | ( REGISTER_MASK & reg ) ); spi->transfer(value); csn(HIGH); return status; }
bool RF24Mesh::write(T_MAC to_mac) { bool ok = false; IF_SERIAL_DEBUG(printf_P(PSTR("%lu: NET Trying to write mac %lu \n\r"),rTable.getMillis(),to_mac) ); // First, stop listening so we can talk radio.stopListening(); if (to_mac != rTable.getBroadcastMac()) { IF_SERIAL_DEBUG(printf_P(PSTR("%lu: It is not broadcast mac so acknowledge is true %lu \n\r"),rTable.getMillis(),to_mac) ); radio.setAutoAck(0,true); } else radio.setAutoAck(0,false); // Open the correct pipe for writing. radio.openWritingPipe(to_mac); // Retry a few times short attempts = 15; do { ok = radio.write( frame_buffer, frame_size ); IF_SERIAL_DEBUG(printf_P(PSTR("%lu: Tried to send packet result:%d attempt %d \n\r"),rTable.getMillis(),ok, attempts) ); } while ( !ok && --attempts ); // Now, continue listening radio.startListening(); radio.setAutoAck(0,false); if(!ok) callback.sendingFailed(to_mac); return ok; }
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; }
/** * 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(); } } }
uint8_t RF24::write_register(uint8_t reg, const uint8_t* buf, uint8_t len) { uint8_t status; IF_SERIAL_DEBUG(printf_P(PSTR("write_register(%02x, %d bytes)\r\n"),reg,len)); csn(LOW); status = SPI.transfer( W_REGISTER | ( REGISTER_MASK & reg)); while (len--) SPI.transfer(*buf++); csn(HIGH); return status; }
bool RF24Mesh::send_WelcomeMessage(T_IP toNode) { unsigned long time = rTable.getMillis(); uint8_t data[16]; memset(&data,0,sizeof(unsigned long)); memcpy(&data,&time,sizeof(unsigned long)); RF24NetworkHeader header(toNode, 'W',data , rTable.getCurrentNode().ip); header.source_data.ip = rTable.getCurrentNode().ip; header.source_data.weight = rTable.getCurrentNode().weight; printf_P(PSTR("---------------------------------\n\r")); IF_SERIAL_DEBUG(printf_P(PSTR("%lu: APP Sending Welcome Message (%s)...\n\r"),rTable.getMillis(),header.toString())); return write(header); //broadcast mac'ine gonder. }
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)); }
void RF24Mesh::sendPackets() { static int error_rate = 0; // Is there anything ready for us? while ( send_available() ) { if(write() == false) error_rate++; else error_rate = 0; } if (error_rate > 4) { setState(NJOINED); IF_SERIAL_DEBUG(printf_P(PSTR("%lu: Fazla gonderme hatasi oldugu icin network dustu\n\r"),rTable.getMillis())); error_rate = 0; } }
uint8_t RF24::write_register(uint8_t reg, uint8_t value) { uint8_t status; IF_SERIAL_DEBUG(printf_P(PSTR("write_register(%02x,%02x)\r\n"),reg,value)); #if defined (__arm__) && !defined ( CORE_TEENSY ) status = SPI.transfer(csn_pin, W_REGISTER | ( REGISTER_MASK & reg ), SPI_CONTINUE); SPI.transfer(csn_pin,value); #else csn(LOW); status = SPI.transfer( W_REGISTER | ( REGISTER_MASK & reg ) ); SPI.transfer(value); csn(HIGH); #endif return status; }
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; }
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; }; } }