diff --git a/lcd.h b/lcd.h index 812084d..c2cd199 100644 --- a/lcd.h +++ b/lcd.h @@ -11,6 +11,7 @@ uint8_t rows, cols; char* buffer = NULL; + public: LCDWrapper(uint8_t addr, uint8_t cols, uint8_t rows, uint8_t charsize=LCD_5x8DOTS) : LiquidCrystal_I2C(addr,cols,rows,charsize) { this->cols = cols; @@ -22,20 +23,6 @@ LiquidCrystal_I2C::backlight(); } - void printf(const char *fmt, ...){ - buffer = (char*) malloc( BUFSIZE * sizeof(char*)); - buffer[0] = 0; - - va_list ap; - va_start(ap, fmt); - int size = vsnprintf(buffer, BUFSIZE, fmt, ap); - va_end(ap); - if( size < 0 || size > BUFSIZE ){ free(buffer); return; } - - LiquidCrystal_I2C::print(buffer); - free(buffer); - } - void printfn(const uint8_t line, const char *fmt, ...){ buffer = (char*) malloc( BUFSIZE * sizeof(char*)); buffer[0] = 0; @@ -44,7 +31,7 @@ va_start(ap, fmt); int size = vsnprintf(buffer, BUFSIZE, fmt, ap); va_end(ap); - if( size < 0 || size > BUFSIZE ){ free(buffer); return; } + if( size < 0 || size >= BUFSIZE ){ free(buffer); return; } LiquidCrystal_I2C::setCursor(0, line); LiquidCrystal_I2C::print(buffer); @@ -59,20 +46,36 @@ va_start(ap, fmt); int size = vsnprintf(buffer, BUFSIZE, fmt, ap); va_end(ap); - if( size < 0 || size > BUFSIZE ){ free(buffer); return; } + buffer[BUFSIZE-1] = 0; + if( size < 0 || size >= BUFSIZE ){ free(buffer); return; } - LiquidCrystal_I2C::setCursor(0, line); + + LiquidCrystal_I2C::setCursor(0,line); LiquidCrystal_I2C::print(buffer); if( size <= cols ){ free(buffer); return; } for( uint8_t offset = 1 ; offset <= size-cols ; offset++ ){ delay(200); - - LiquidCrystal_I2C::setCursor(0, line); + LiquidCrystal_I2C::setCursor(0,line); LiquidCrystal_I2C::print(buffer+offset); } free(buffer); } + + protected: + void printf(const char *fmt, ...) { + buffer = (char*) malloc( BUFSIZE * sizeof(char*)); + buffer[0] = 0; + + va_list ap; + va_start(ap, fmt); + int size = vsnprintf(buffer, BUFSIZE, fmt, ap); + va_end(ap); + if( size < 0 || size >= BUFSIZE ){ free(buffer); return; } + + LiquidCrystal_I2C::print(buffer); + free(buffer); + } }; #endif \ No newline at end of file diff --git a/node/main/main.ino b/node/main/main.ino index 080952e..07f2039 100644 --- a/node/main/main.ino +++ b/node/main/main.ino @@ -20,10 +20,9 @@ void setup() { Serial.println("+ ready"); screen.begin(); - screen.printf("[ node ready ]"); + screen.printfn(0, "[ node ready ]"); xbee.begin(38400); - time = millis(); } @@ -35,7 +34,6 @@ void loop() { send_data(); } - /* [2] Listen for incoming data */ if( xbee.receive(recv) != XBWRECV_OK ) return; @@ -43,11 +41,11 @@ void loop() { uint8_t opcode = recv.getOpcode(); // 1. manage discover request - if( opcode == 0 ) + if( opcode == OPCODE_DISCOVER ) return manage_discover(); // 2. manage message data - else if( opcode == 1 ) + else if( opcode == OPCODE_MESSAGE ) return manage_message(); @@ -56,21 +54,19 @@ void loop() { void send_data(){ Serial.println(" -> message"); // 1. prepare message - send.setOpcode(1); + send.setOpcode(OPCODE_MESSAGE); + send.setSender(SENDERID); send.setDist(dist); send.setTTL(MESSAGE_TTL); - uint8_t data[32] = {0}; + char data[64] = {0}; strcpy(data, "https://git.xdrm.io"); - Serial.print("'"); - Serial.print( (char*) data); - Serial.println("'"); - send.setData(data, strlen(data)); - send.setSender(SENDERID); + send.setData(data); // 2. debug screen.clear(); screen.printfn(0, "msg[%3d/%3d] %3d", send.getDist(), send.getTTL(), send.getSize()); - screen.printfn_overflow(1, "%s", send.getData()); + screen.printfn_overflow(1, "%s", (char*) send.getData()); + delay(1000); // 3. send xbee.broadcast(send); @@ -79,17 +75,18 @@ void send_data(){ void manage_discover(){ - Serial.println(" <- discover"); - // security - if( recv.getDist() == 0 && recv.getSender() != SENDERID ) - return; + Serial.print(" <- discover[ "); + Serial.print(recv.getDist()); + Serial.print(" / "); + Serial.print(recv.getWave()); + Serial.println(" ]"); screen.clear(); - screen.printfn(0, "dsc[%3d] %3d/%3d", recv.getSender(), recv.getDist(), recv.getWave()); + screen.printfn(0, "dsc[ %3d / %3d ]", recv.getDist(), recv.getWave()); // ignore if same wave if( recv.getWave() == wave_id ){ - screen.printfn(1, "x"); + screen.printfn(1, "x "); return; } @@ -98,33 +95,44 @@ void manage_discover(){ dist = recv.getDist()+1; // propagate wave - send.setOpcode(0); + send.setOpcode(OPCODE_DISCOVER); send.setWave(wave_id); send.setDist(dist); - send.setSender(SENDERID); - screen.printfn(1, "dsc[%3d] %3d/%3d", send.getSender(), send.getDist(), send.getWave()); + screen.printfn(1, "dsc[ %3d / %3d ]", send.getDist(), send.getWave()); xbee.broadcast(send); } void manage_message(){ - Serial.println(" <- message"); + if( recv.getTTL() <= 0 ) + return; + + Serial.print(" <- message["); + Serial.print(recv.getDist()); + Serial.print("/"); + Serial.print(recv.getTTL()); + Serial.print("] "); + Serial.print(recv.getSize()); + Serial.print(" '"); + Serial.print((char*) recv.getData()); + Serial.println("'"); + screen.clear(); screen.printfn(0, "msg[%3d/%3d] %3d", recv.getDist(), recv.getTTL(), recv.getSize()); - delay(500); - screen.printfn_overflow(0, "%s", recv.getData()); + screen.printfn_overflow(1, "%s", (char*) recv.getData()); + delay(1000); // ignore - if( recv.getTTL() <= 0 || recv.getDist() > dist ){ - screen.printfn(1, "x"); + if( recv.getDist() > dist ){ + screen.printfn(1, "x "); return; } // propagation - send.setOpcode(1); + send.setOpcode(OPCODE_MESSAGE); send.setTTL(recv.getTTL()-1); send.setDist(dist); - send.setData(recv.getData(), recv.getSize()); + send.setData(recv.getData()); screen.printfn(1, "msg[%3d/%3d] %3d", send.getDist(), send.getTTL(), send.getSize()); xbee.broadcast(send); diff --git a/packet.cpp b/packet.cpp index f81f0cf..33cf332 100644 --- a/packet.cpp +++ b/packet.cpp @@ -1,10 +1,12 @@ #include "packet.h" - +Packet::Packet(){ + msg.data = malloc(1 * sizeof(char)); +} /* PUBLIC ----------------------------------------*/ // builds a packet from raw data and returns the error code -uint8_t Packet::read(uint8_t buf[], const size_t size){ +uint8_t Packet::read(uint8_t* buf, const size_t size){ // 1. fail on invalid size if( size < 1 ) return PKTREAD_EMPTY; if( size > PROTO_SIZE ) return PKTREAD_OVERFLOW; @@ -18,7 +20,7 @@ uint8_t Packet::read(uint8_t buf[], const size_t size){ }; // writes the binary representation of the packet -size_t Packet::write(uint8_t buf[]){ +size_t Packet::write(uint8_t* buf){ if( opcode == 0 ) return write_discover(buf); @@ -33,8 +35,8 @@ void Packet::setOpcode(uint8_t value) { opcode = value; dsc.opcode = value; msg. uint8_t Packet::getWave() { return dsc.wave; } void Packet::setWave(uint8_t value) { dsc.wave = value; } -uint8_t Packet::getSender() { return (opcode == 0) ? dsc.sender : msg.sender; } -void Packet::setSender(uint8_t value) { if(opcode == 0) dsc.sender = value; else msg.sender = value; } +uint8_t Packet::getSender() { return msg.sender; } +void Packet::setSender(uint8_t value) { msg.sender = value; } uint8_t Packet::getDist() { return (opcode == 0) ? dsc.dist : msg.dist; } void Packet::setDist(uint8_t value) { if(opcode == 0) dsc.dist = value; else msg.dist = value; } @@ -44,14 +46,22 @@ void Packet::setTTL(uint8_t value) { msg.ttl = value; } uint8_t Packet::getSize() { return msg.size; } -uint8_t* Packet::getData() { return msg.data; } -void Packet::setData(uint8_t *buffer, uint8_t size) { memcpy(msg.data, buffer, size); msg.size = size; } +uint8_t* Packet::getData(){ return msg.data; } +void Packet::setData(uint8_t *buffer) { + if( strlen(buffer) >= 255 ) + return; + + msg.size = strlen(buffer); + + resizeMessage(); + strcpy(msg.data, buffer); +} /* PRIVATE ----------------------------------------*/ -uint8_t Packet::read_discover(uint8_t buf[], const size_t size){ +uint8_t Packet::read_discover(uint8_t *buf, const size_t size){ // 1. fail on invalid size if( size != DISCOVER_SIZE ) return PKTREAD_INVALID_DISCOVER_FORMAT; @@ -59,52 +69,52 @@ uint8_t Packet::read_discover(uint8_t buf[], const size_t size){ dsc.opcode = buf[0]; dsc.wave = buf[1]; dsc.dist = buf[2]; - dsc.sender = buf[3]; return PKTREAD_OK; }; -uint8_t Packet::read_message(uint8_t buf[], const size_t size){ + +size_t Packet::write_discover(uint8_t *buf){ + buf[0] = dsc.opcode; + buf[1] = dsc.wave; + buf[2] = dsc.dist; + + return 3; +}; + + +uint8_t Packet::read_message(uint8_t *buf, const size_t size){ // 1. fail on invalid size if( size < MESSAGE_MIN_SIZE || size > MESSAGE_MAX_SIZE ) return PKTREAD_INVALID_MESSAGE_FORMAT; + // 2. fill values msg.opcode = buf[0]; - msg.dist = buf[1]; - msg.ttl = buf[2]; - msg.size = buf[3]; + msg.sender = buf[1]; + msg.dist = buf[2]; + msg.ttl = buf[3]; + msg.size = buf[4]; // 3. check message size - if( size - 5 - 1 != msg.size ) + if( size - 5 != msg.size ) return PKTREAD_INVALID_MESSAGE_FORMAT; // 4. extract message - memcpy(msg.data, buf+4, msg.size); - - // 5. add sender id - msg.sender = buf[msg.size+4+1]; + resizeMessage(); + strncpy(msg.data, buf+5, msg.size); return PKTREAD_OK; }; -size_t Packet::write_discover(uint8_t buf[]){ - buf[0] = dsc.opcode; - buf[1] = dsc.wave; - buf[2] = dsc.dist; - buf[3] = dsc.sender; - - return 4; -}; - -size_t Packet::write_message(uint8_t buf[]){ +size_t Packet::write_message(uint8_t *buf){ buf[0] = msg.opcode; - buf[1] = msg.dist; - buf[2] = msg.ttl; - buf[3] = msg.size; + buf[1] = msg.sender; + buf[2] = msg.dist; + buf[3] = msg.ttl; + buf[4] = msg.size; - memcpy( buf+4, msg.data, msg.size ); + buf = realloc(buf, (5+msg.size+1)* sizeof(uint8_t)); + strncpy(buf+5, msg.data, msg.size); - buf[msg.size+5] = msg.sender; - - return 4 + msg.size; + return 5 + msg.size; }; \ No newline at end of file diff --git a/packet.h b/packet.h index 4da5014..82fe9a4 100644 --- a/packet.h +++ b/packet.h @@ -20,17 +20,19 @@ struct message msg; // 3. helpers - uint8_t read_discover(uint8_t buf[], const size_t size); - uint8_t read_message(uint8_t buf[], const size_t size); - size_t write_discover(uint8_t buf[]); - size_t write_message(uint8_t buf[]); + uint8_t read_discover(uint8_t* buf, const size_t size); + uint8_t read_message(uint8_t* buf, const size_t size); + size_t write_discover(uint8_t* buf); + size_t write_message(uint8_t* buf); public: + + Packet(); // builds a packet from raw data and returns the status code - uint8_t read(uint8_t buf[], const size_t size); + uint8_t read(uint8_t* buf, const size_t size); // writes the binary representation of the packet returns the size - size_t write(uint8_t buf[]); + size_t write(uint8_t* buf); // GETTERS / SETTERS uint8_t getOpcode(); @@ -51,7 +53,13 @@ uint8_t getSize(); uint8_t* getData(); - void setData(uint8_t *buffer, uint8_t size); + void setData(uint8_t *buffer); + + protected: + resizeMessage(){ + msg.data = realloc(msg.data, (msg.size+1) * sizeof(uint8_t)); + // memset(msg.data, 0, msg.size+1); + } }; diff --git a/protocol.h b/protocol.h index 8669eaa..00046ee 100644 --- a/protocol.h +++ b/protocol.h @@ -7,56 +7,29 @@ #define SENDERID 42 #define MESSAGE_TTL 10 + #define OPCODE_DISCOVER 0 + #define OPCODE_MESSAGE 1 + // discover request (c.f. class node) - #define DISCOVER_SIZE sizeof(uint8_t)*4 + #define DISCOVER_SIZE sizeof(uint8_t)*3 struct discover { uint8_t opcode; // opcode = 0 uint8_t wave; // id de la wave uint8_t dist; // current node's distance - uint8_t sender; // sender id }; #define MESSAGE_MIN_SIZE sizeof(uint8_t)*5 - #define MESSAGE_MAX_SIZE sizeof(uint8_t)*5+sizeof(uint8_t)*255 + #define MESSAGE_MAX_SIZE (5 + 255) * sizeof(uint8_t) struct message { uint8_t opcode; // opcode = 1 + uint8_t sender; // sender id uint8_t dist; // distance of the last sender uint8_t ttl; // time to live default = 10 uint8_t size; // size of message in bytes uint8_t *data; // actual message - uint8_t sender; // sender id }; - #define PROTO_SIZE MESSAGE_MAX_SIZE - // A object is held by each node which values are determined thanks - // to the DISCOVER requests it receives; each node broadcasts a DISCOVER - // request every DISCOVER_TTL milliseconds - // class node{ - // private: - // // unique id of the node : MAC ADDR - // int id; - - // // last received wave id - // uint8_t last_wave; - - // // relative node-distance to the well - // // WELL : dist = 0 - // // NODE1 can reach WELL : dist = 1 - // // NODE2 can reach NODE1 : dist = 2 - // // and so on... - // uint8_t dist; - - // public: - - // // send a discover request - // bool discover(); - - // // update the current node according to a (received) - // // discover request - // bool update(struct discover dsc); - // }; - #endif \ No newline at end of file diff --git a/well/main/main.ino b/well/main/main.ino index fa826e3..43a7e06 100644 --- a/well/main/main.ino +++ b/well/main/main.ino @@ -17,7 +17,7 @@ void setup() { Serial.println("+ ready"); screen.begin(); - screen.printf("[ well ready ]"); + screen.printfn(0, "[ well ready ]"); xbee.begin(38400); @@ -31,13 +31,12 @@ void loop() { time = millis(); // increment wave id (will overflow from 255 to 0) - send.setOpcode(0); + send.setOpcode(OPCODE_DISCOVER); send.setWave(++wave_id); send.setDist(0); - send.setSender(SENDERID); screen.clear(); - screen.printfn(0, "dsc[%3d] %3d/%3d", send.getSender(), send.getDist(), send.getWave()); + screen.printfn(0, "dsc[ %3d / %3d ]", send.getDist(), send.getWave()); if( xbee.broadcast(send) == XBWSEND_OK ) screen.printfn(1, "sent"); else screen.printfn(1, "failed"); diff --git a/xbee_wrapper.cpp b/xbee_wrapper.cpp index 9a764c7..188da3d 100644 --- a/xbee_wrapper.cpp +++ b/xbee_wrapper.cpp @@ -49,21 +49,14 @@ uint8_t XBeeWrapper::broadcast(Packet& pkt){ XBeeAddress64 bcast = XBeeAddress64(0x00000000, 0x0000FFFF); // build payload from packet - uint8_t payload[PROTO_SIZE]; + uint8_t* payload = malloc(6 * sizeof(uint8_t)); size_t payload_size = pkt.write(payload); // send Tx64Request tx = Tx64Request(bcast, payload, payload_size); xbee.send(tx); - // // check status - // TxStatusResponse txStatus = TxStatusResponse(); - // xbee.readPacket(); - // if( xbee.getResponse().isAvailable() ){ - // if( xbee.getResponse().getApiId() == TX_STATUS_RESPONSE ){ - // xbee.getResponse().getTxStatusResponse(txStatus); - // return txStatus.isSuccess() ? XBWSEND_OK : XBWSEND_ERROR; - // } - // } + free(payload); + return XBWSEND_OK; }; \ No newline at end of file