IOT_GRZYBKI
/
server2
code for gateway node connecting by wifi with backend and by radio with sensor nodes
main.cpp@2:73331442c00e, 2019-01-25 (annotated)
- Committer:
- tkanas
- Date:
- Fri Jan 25 03:42:30 2019 +0000
- Revision:
- 2:73331442c00e
- Parent:
- 1:605fa4405e4f
tralalalalaal
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
Ka_myk | 0:544925185af9 | 1 | #include "mbed.h" |
Ka_myk | 0:544925185af9 | 2 | #include "coapServer.h" |
Ka_myk | 0:544925185af9 | 3 | #include "radioWrapper.h" |
Ka_myk | 0:544925185af9 | 4 | #include <string> |
Ka_myk | 0:544925185af9 | 5 | #include "dbg.h" |
Ka_myk | 0:544925185af9 | 6 | #include "msg.h" |
Ka_myk | 0:544925185af9 | 7 | #include "itoa.h" |
Ka_myk | 0:544925185af9 | 8 | |
Ka_myk | 0:544925185af9 | 9 | int channel = 4; |
Ka_myk | 0:544925185af9 | 10 | |
Ka_myk | 0:544925185af9 | 11 | unsigned long long txAdress = 0xABCDEF08; |
Ka_myk | 0:544925185af9 | 12 | unsigned long long rxAdress[] = {0xABCDEF11, 0xABCDEF12, 0xABCDEF13}; |
Ka_myk | 0:544925185af9 | 13 | |
tkanas | 2:73331442c00e | 14 | Serial pc(SERIAL_TX, SERIAL_RX); |
tkanas | 2:73331442c00e | 15 | Serial wifi(PA_11, PA_12); |
tkanas | 2:73331442c00e | 16 | DigitalOut send(PC_8); |
Ka_myk | 0:544925185af9 | 17 | |
tkanas | 2:73331442c00e | 18 | #define PCDBG(...) if(1){ pc.printf(__VA_ARGS__); pc.printf("\r\n");} |
tkanas | 2:73331442c00e | 19 | #define BINDBG(buff, len) if(1){ print_bin(buff, len); } |
tkanas | 2:73331442c00e | 20 | #define HEXDBG(buff, len) if(1){ print_hex(buff, len);} |
tkanas | 2:73331442c00e | 21 | |
tkanas | 2:73331442c00e | 22 | //Number of retransmissions |
tkanas | 2:73331442c00e | 23 | #define RETRANSMISSION 10 |
tkanas | 2:73331442c00e | 24 | //Timeout in ms |
tkanas | 2:73331442c00e | 25 | #define TIMEOUT 2000 |
tkanas | 2:73331442c00e | 26 | |
tkanas | 2:73331442c00e | 27 | //Length of PUT (data) response |
tkanas | 2:73331442c00e | 28 | #define PUT_ANS_LEN 5 |
tkanas | 2:73331442c00e | 29 | //Length of GET (conf) response |
tkanas | 2:73331442c00e | 30 | #define GET_ANS_LEN 10 |
tkanas | 2:73331442c00e | 31 | |
tkanas | 2:73331442c00e | 32 | int read_finished = 0; |
tkanas | 2:73331442c00e | 33 | uint16_t messageID = 1; |
tkanas | 2:73331442c00e | 34 | |
tkanas | 2:73331442c00e | 35 | void print_bin(uint8_t* buff, int len) { |
tkanas | 2:73331442c00e | 36 | char str[len]; |
tkanas | 2:73331442c00e | 37 | for(int i = 0; i < len; ++i) { |
tkanas | 2:73331442c00e | 38 | if((buff[i] >= 'a' && buff[i] <= 'z') || (buff[i] >= 'A' && buff[i] <= 'Z') || (buff[i] >= '0'&& buff[i] <= '9')) { |
tkanas | 2:73331442c00e | 39 | str[i] = buff[i]; |
tkanas | 2:73331442c00e | 40 | } else { |
tkanas | 2:73331442c00e | 41 | str[i] = '.'; |
tkanas | 2:73331442c00e | 42 | } |
tkanas | 2:73331442c00e | 43 | } |
tkanas | 2:73331442c00e | 44 | PCDBG("%s", str); |
tkanas | 2:73331442c00e | 45 | } |
tkanas | 2:73331442c00e | 46 | |
tkanas | 2:73331442c00e | 47 | void print_hex(uint8_t* buff, int len) { |
tkanas | 2:73331442c00e | 48 | for(int i = 0; i < len; ++i) { |
tkanas | 2:73331442c00e | 49 | pc.printf("%X ", buff[i]); |
tkanas | 2:73331442c00e | 50 | } |
tkanas | 2:73331442c00e | 51 | pc.printf("\r\n"); |
tkanas | 2:73331442c00e | 52 | } |
tkanas | 2:73331442c00e | 53 | |
tkanas | 2:73331442c00e | 54 | void read_cb(int arg) { |
tkanas | 2:73331442c00e | 55 | (void)arg; |
tkanas | 2:73331442c00e | 56 | read_finished = 1; |
tkanas | 2:73331442c00e | 57 | } |
tkanas | 2:73331442c00e | 58 | |
tkanas | 2:73331442c00e | 59 | CoapPDU* read(uint8_t* rx_buff, int len) { |
tkanas | 2:73331442c00e | 60 | int ret; |
tkanas | 2:73331442c00e | 61 | PCDBG("Reading"); |
tkanas | 2:73331442c00e | 62 | read_finished = 0; |
tkanas | 2:73331442c00e | 63 | Timer t; |
tkanas | 2:73331442c00e | 64 | t.start(); |
tkanas | 2:73331442c00e | 65 | while(!wifi.readable() && t.read_ms() < TIMEOUT) {} |
tkanas | 2:73331442c00e | 66 | if(wifi.readable()) |
tkanas | 2:73331442c00e | 67 | //ret = wifi.read(rx_buff, len, event_callback_t(&read_cb)); |
tkanas | 2:73331442c00e | 68 | wifi.gets((char*)rx_buff, len + 1); |
tkanas | 2:73331442c00e | 69 | else { |
tkanas | 2:73331442c00e | 70 | t.stop(); |
tkanas | 2:73331442c00e | 71 | return NULL; |
tkanas | 2:73331442c00e | 72 | } |
tkanas | 2:73331442c00e | 73 | PCDBG("Started reading"); |
tkanas | 2:73331442c00e | 74 | //t.reset(); |
tkanas | 2:73331442c00e | 75 | //t.start(); |
tkanas | 2:73331442c00e | 76 | //while(read_finished == 0 && t.read_ms() < TIMEOUT) {} |
tkanas | 2:73331442c00e | 77 | //while(read_finished == 0) {} |
tkanas | 2:73331442c00e | 78 | t.stop(); |
tkanas | 2:73331442c00e | 79 | PCDBG("Finished Reading, ret = %d, read_finished = %d, time = %d", ret, read_finished, t.read_ms()) |
tkanas | 2:73331442c00e | 80 | HEXDBG(rx_buff, len); |
tkanas | 2:73331442c00e | 81 | //if(read_finished != 1) { |
tkanas | 2:73331442c00e | 82 | // wifi.abort_read(); |
tkanas | 2:73331442c00e | 83 | // read_finished = 0; |
tkanas | 2:73331442c00e | 84 | // return NULL; |
tkanas | 2:73331442c00e | 85 | // } |
tkanas | 2:73331442c00e | 86 | read_finished = 0; |
tkanas | 2:73331442c00e | 87 | CoapPDU* recvPDU = new CoapPDU(rx_buff, len); |
tkanas | 2:73331442c00e | 88 | PCDBG("PDU created"); |
tkanas | 2:73331442c00e | 89 | if(recvPDU->validate()) { |
tkanas | 2:73331442c00e | 90 | PCDBG("Validated"); |
tkanas | 2:73331442c00e | 91 | recvPDU->printHuman(); |
tkanas | 2:73331442c00e | 92 | PCDBG("Code = %d", recvPDU->getCode()); |
tkanas | 2:73331442c00e | 93 | PCDBG("Payload:"); |
tkanas | 2:73331442c00e | 94 | HEXDBG(recvPDU->getPayloadPointer(), len - 6); |
tkanas | 2:73331442c00e | 95 | return recvPDU; |
tkanas | 2:73331442c00e | 96 | } |
tkanas | 2:73331442c00e | 97 | return NULL; |
tkanas | 2:73331442c00e | 98 | } |
tkanas | 2:73331442c00e | 99 | |
tkanas | 2:73331442c00e | 100 | void send_cb(int arg) { |
tkanas | 2:73331442c00e | 101 | (void)arg; |
tkanas | 2:73331442c00e | 102 | send.write(1); |
tkanas | 2:73331442c00e | 103 | wait(0.05); |
tkanas | 2:73331442c00e | 104 | send.write(0); |
tkanas | 2:73331442c00e | 105 | } |
tkanas | 2:73331442c00e | 106 | |
tkanas | 2:73331442c00e | 107 | int sendd(uint8_t* buff, int len) { |
tkanas | 2:73331442c00e | 108 | while(!wifi.writable()) { |
tkanas | 2:73331442c00e | 109 | //PCDBG("Wifi not wirtable"); |
tkanas | 2:73331442c00e | 110 | //wait(0.5); |
tkanas | 2:73331442c00e | 111 | } |
tkanas | 2:73331442c00e | 112 | PCDBG("Sending:"); |
tkanas | 2:73331442c00e | 113 | HEXDBG(buff, len); |
tkanas | 2:73331442c00e | 114 | //For some mysterious reason it doesn't print first character |
tkanas | 2:73331442c00e | 115 | uint8_t buf2[len+1]; |
tkanas | 2:73331442c00e | 116 | std::memcpy(buf2+1, buff, len); |
tkanas | 2:73331442c00e | 117 | buf2[0] = 0; |
tkanas | 2:73331442c00e | 118 | int ret = wifi.write(buf2, len + 1, event_callback_t(&send_cb)); |
tkanas | 2:73331442c00e | 119 | PCDBG("Sending initiated"); |
tkanas | 2:73331442c00e | 120 | return ret; |
tkanas | 2:73331442c00e | 121 | } |
tkanas | 2:73331442c00e | 122 | |
tkanas | 2:73331442c00e | 123 | CoapPDU* send_or_fail(uint8_t* buff, int len, uint8_t* rx_buff, int ans_len) { |
tkanas | 2:73331442c00e | 124 | int ret; |
tkanas | 2:73331442c00e | 125 | CoapPDU* ans; |
tkanas | 2:73331442c00e | 126 | for(int i = 0; i < RETRANSMISSION; ++i) { |
tkanas | 2:73331442c00e | 127 | ret = sendd(buff, len); |
tkanas | 2:73331442c00e | 128 | if(ret < 0) { |
tkanas | 2:73331442c00e | 129 | PCDBG("Send Failed"); |
tkanas | 2:73331442c00e | 130 | return NULL; |
tkanas | 2:73331442c00e | 131 | } |
tkanas | 2:73331442c00e | 132 | ans = read(rx_buff, ans_len); |
tkanas | 2:73331442c00e | 133 | if(ans == NULL) { |
tkanas | 2:73331442c00e | 134 | PCDBG("Read Failed"); |
tkanas | 2:73331442c00e | 135 | } else if(ans->getType() != CoapPDU::COAP_ACKNOWLEDGEMENT || ans->getMessageID() != messageID) { |
tkanas | 2:73331442c00e | 136 | PCDBG("Wrong answer IS: type = %d, id = %d SHOULD BE: type = %d, id = %d", ans->getType(), ans->getMessageID(), CoapPDU::COAP_ACKNOWLEDGEMENT, messageID); |
tkanas | 2:73331442c00e | 137 | delete ans; |
tkanas | 2:73331442c00e | 138 | } else { |
tkanas | 2:73331442c00e | 139 | PCDBG("ACK get"); |
tkanas | 2:73331442c00e | 140 | return ans; |
tkanas | 2:73331442c00e | 141 | } |
tkanas | 2:73331442c00e | 142 | } |
tkanas | 2:73331442c00e | 143 | PCDBG("Retransmission limit reached"); |
tkanas | 2:73331442c00e | 144 | return NULL; |
tkanas | 2:73331442c00e | 145 | } |
tkanas | 2:73331442c00e | 146 | |
tkanas | 2:73331442c00e | 147 | |
tkanas | 2:73331442c00e | 148 | void preparePDU(CoapPDU& coapPDU) { |
tkanas | 2:73331442c00e | 149 | coapPDU.setVersion(1); |
tkanas | 2:73331442c00e | 150 | coapPDU.setType(CoapPDU::COAP_CONFIRMABLE); |
tkanas | 2:73331442c00e | 151 | coapPDU.setMessageID(++messageID); |
tkanas | 2:73331442c00e | 152 | coapPDU.setToken((uint8_t*)"A", 1); |
tkanas | 2:73331442c00e | 153 | } |
tkanas | 2:73331442c00e | 154 | |
tkanas | 2:73331442c00e | 155 | int send_data(int type, int data) { |
tkanas | 2:73331442c00e | 156 | uint8_t buff[5]; |
tkanas | 2:73331442c00e | 157 | uint8_t rx_buff[PUT_ANS_LEN]; |
tkanas | 2:73331442c00e | 158 | Msg::construct_data_msg(type, data, buff, 5); |
tkanas | 2:73331442c00e | 159 | CoapPDU pdu = CoapPDU(); |
tkanas | 2:73331442c00e | 160 | preparePDU(pdu); |
tkanas | 2:73331442c00e | 161 | pdu.setCode(CoapPDU::COAP_PUT); |
tkanas | 2:73331442c00e | 162 | pdu.setURI((char*)"data",4); |
tkanas | 2:73331442c00e | 163 | pdu.setPayload(buff, 5); |
tkanas | 2:73331442c00e | 164 | CoapPDU* ans = send_or_fail(pdu.getPDUPointer(), pdu.getPDULength(), rx_buff, PUT_ANS_LEN); |
tkanas | 2:73331442c00e | 165 | if(ans == NULL) return -1; |
tkanas | 2:73331442c00e | 166 | delete ans; |
tkanas | 2:73331442c00e | 167 | return 0; |
tkanas | 2:73331442c00e | 168 | } |
tkanas | 2:73331442c00e | 169 | |
tkanas | 2:73331442c00e | 170 | int get_config(uint8_t type) { |
tkanas | 2:73331442c00e | 171 | uint8_t buff[1]; |
tkanas | 2:73331442c00e | 172 | uint8_t rx_buff[GET_ANS_LEN]; |
tkanas | 2:73331442c00e | 173 | PCDBG("Gonna get the conf for type %d", type); |
tkanas | 2:73331442c00e | 174 | buff[0] = type; |
tkanas | 2:73331442c00e | 175 | CoapPDU pdu = CoapPDU(); |
tkanas | 2:73331442c00e | 176 | preparePDU(pdu); |
tkanas | 2:73331442c00e | 177 | pdu.setCode(CoapPDU::COAP_POST); |
tkanas | 2:73331442c00e | 178 | pdu.setURI((char*)"conf",4); |
tkanas | 2:73331442c00e | 179 | pdu.setPayload(buff, 1); |
tkanas | 2:73331442c00e | 180 | CoapPDU* ans = send_or_fail(pdu.getPDUPointer(), pdu.getPDULength(), rx_buff, GET_ANS_LEN); |
tkanas | 2:73331442c00e | 181 | if(ans == NULL) { |
tkanas | 2:73331442c00e | 182 | PCDBG("Failed to get config"); |
tkanas | 2:73331442c00e | 183 | return -1; |
tkanas | 2:73331442c00e | 184 | } |
tkanas | 2:73331442c00e | 185 | uint8_t* config = ans->getPayloadPointer(); |
tkanas | 2:73331442c00e | 186 | int conf = 0; |
tkanas | 2:73331442c00e | 187 | int a = 1; |
tkanas | 2:73331442c00e | 188 | for(int i = 3; i >= 0; --i) { |
tkanas | 2:73331442c00e | 189 | conf += config[i] * a; |
tkanas | 2:73331442c00e | 190 | a *= 256; |
tkanas | 2:73331442c00e | 191 | } |
tkanas | 2:73331442c00e | 192 | delete ans; |
tkanas | 2:73331442c00e | 193 | PCDBG("New config for type %d is %d", type, conf); |
tkanas | 2:73331442c00e | 194 | return conf; |
tkanas | 2:73331442c00e | 195 | } |
tkanas | 2:73331442c00e | 196 | |
Ka_myk | 0:544925185af9 | 197 | InterruptIn button(USER_BUTTON); |
Ka_myk | 0:544925185af9 | 198 | bool start = false; |
Ka_myk | 0:544925185af9 | 199 | |
Ka_myk | 0:544925185af9 | 200 | void send_packet() { |
Ka_myk | 0:544925185af9 | 201 | start = true; |
Ka_myk | 0:544925185af9 | 202 | } |
Ka_myk | 0:544925185af9 | 203 | |
Ka_myk | 0:544925185af9 | 204 | int main() { |
Ka_myk | 0:544925185af9 | 205 | pc.baud(115200); |
tkanas | 2:73331442c00e | 206 | wifi.baud(115200); |
thewiztory | 1:605fa4405e4f | 207 | std::string uris[] = {"/dist", "/temp", "/hum", "/moist", "/conf/dist", "/conf/temp", "/conf/hum", "/conf/moist"}; |
thewiztory | 1:605fa4405e4f | 208 | CoapServer coapServer = CoapServer(32, 1000, uris, 8, channel, txAdress, rxAdress); |
Ka_myk | 0:544925185af9 | 209 | button.rise(&send_packet); |
Ka_myk | 0:544925185af9 | 210 | uint8_t buffer[32]; |
Ka_myk | 0:544925185af9 | 211 | CoapServer::METHOD method; |
Ka_myk | 0:544925185af9 | 212 | int uriNum = -1; |
Ka_myk | 0:544925185af9 | 213 | pc.printf("Server initialized \r\n"); |
Ka_myk | 0:544925185af9 | 214 | int pipe = -1; |
Ka_myk | 0:544925185af9 | 215 | while (1) { |
Ka_myk | 0:544925185af9 | 216 | while (start) { |
Ka_myk | 0:544925185af9 | 217 | int ret = coapServer.listen(buffer, 32, &method, &uriNum, &pipe); |
Ka_myk | 0:544925185af9 | 218 | pc.printf("Code : %d \r\n", ret); |
Ka_myk | 0:544925185af9 | 219 | if (ret >= 0) { |
Ka_myk | 0:544925185af9 | 220 | pc.printf("Recieved: %s \r\n", buffer); |
thewiztory | 1:605fa4405e4f | 221 | pc.printf("*****Pipe: %d", pipe); |
Ka_myk | 0:544925185af9 | 222 | int resLen = 0; |
Ka_myk | 0:544925185af9 | 223 | if (method == CoapServer::POST) { |
Ka_myk | 0:544925185af9 | 224 | resLen = coapServer.respond(uriNum, NULL, 0, CoapPDU::COAP_CREATED, pipe); |
Ka_myk | 0:544925185af9 | 225 | int data = 0; |
Ka_myk | 0:544925185af9 | 226 | uint8_t sensor = 1; |
Ka_myk | 0:544925185af9 | 227 | Msg::deconstruct_data_msg(&sensor, &data, buffer, ret); |
tkanas | 2:73331442c00e | 228 | send_data(uriNum % 4, data); |
thewiztory | 1:605fa4405e4f | 229 | switch (uriNum % 4) { |
Ka_myk | 0:544925185af9 | 230 | case 0: |
Ka_myk | 0:544925185af9 | 231 | DBG("dist %d", data); |
Ka_myk | 0:544925185af9 | 232 | break; |
Ka_myk | 0:544925185af9 | 233 | case 1: |
Ka_myk | 0:544925185af9 | 234 | DBG("TEMP %d", data); |
Ka_myk | 0:544925185af9 | 235 | break; |
Ka_myk | 0:544925185af9 | 236 | case 2: |
Ka_myk | 0:544925185af9 | 237 | DBG("HUM %d", data); |
Ka_myk | 0:544925185af9 | 238 | break; |
thewiztory | 1:605fa4405e4f | 239 | case 3: |
thewiztory | 1:605fa4405e4f | 240 | DBG("MOIST %d", data); |
thewiztory | 1:605fa4405e4f | 241 | break; |
Ka_myk | 0:544925185af9 | 242 | } |
Ka_myk | 0:544925185af9 | 243 | } else if (method == CoapServer::GET) { |
thewiztory | 1:605fa4405e4f | 244 | uint8_t response[10]; |
tkanas | 2:73331442c00e | 245 | int conf = get_config(uriNum % 4); |
tkanas | 2:73331442c00e | 246 | Msg::construct_data_msg(0, conf, response, 10); |
thewiztory | 1:605fa4405e4f | 247 | pc.printf("*****response:\r\n"); |
thewiztory | 1:605fa4405e4f | 248 | for (int i = 0; i < 10; i++) { |
thewiztory | 1:605fa4405e4f | 249 | pc.printf("%d ", response[i]); |
thewiztory | 1:605fa4405e4f | 250 | } |
thewiztory | 1:605fa4405e4f | 251 | pc.printf("\r\n"); |
thewiztory | 1:605fa4405e4f | 252 | resLen = coapServer.respond(uriNum, response, 10, CoapPDU::COAP_CONTENT, pipe); |
Ka_myk | 0:544925185af9 | 253 | } |
Ka_myk | 0:544925185af9 | 254 | DBG("RESPONDED WITH %d", resLen); |
Ka_myk | 0:544925185af9 | 255 | } |
Ka_myk | 0:544925185af9 | 256 | } |
Ka_myk | 0:544925185af9 | 257 | } |
Ka_myk | 0:544925185af9 | 258 | } |