Fabio Gatti / Mbed OS MultiProtocol_Cloud_copy

Dependencies:   HTS221 MQTT

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers main.cpp Source File

main.cpp

00001 // main.cpp
00002 #include <string>
00003 
00004 #include "mbed.h"
00005 #include "ISM43362Interface.h"
00006 #include "TCPSocket.h"
00007 #include "HTS221Sensor.h"
00008 
00009 #include "thingsboard_account.h"
00010 
00011 
00012 // H file per MQTT
00013 #include "MQTTmbed.h"
00014 #include "MQTTClient.h"
00015 
00016 // H file per COAP
00017 #include "sn_nsdl.h"
00018 #include "sn_coap_protocol.h"
00019 #include "sn_coap_header.h"
00020 
00021 // Definitions ---------------------------------------------------------
00022 
00023 // Change it with your WiFi network name
00024 //#define WIFI_NETWORK_NAME       "farnell_iot_lab"
00025 #define WIFI_NETWORK_NAME       "rucola"
00026 // Change it with your WiFi password name
00027 //#define WIFI_NETWORK_PASSWORD   "smartlab"
00028 #define WIFI_NETWORK_PASSWORD   "Rosmarino_10"
00029 
00030 #define WIFI_SECURITY           NSAPI_SECURITY_WPA_WPA2
00031 
00032 #define COMM_PROTO              2
00033 
00034 // scegliere il protocollo di trasporto dati
00035 // COMM_PROTO = 0 -> accesso MQTT (default);
00036 // COMM_PROTO = 1 -> access  HTTP;
00037 // COMM_PROTO = 2 -> accesso COAP;
00038 #ifndef COMM_PROTO
00039 #define COMM_PROTO 0
00040 #endif
00041 
00042 // scegliere il token al device
00043 #define DEVICE_ID                 5
00044 #define DEVICE_ACCESS_TOKEN       TEAM_5_DEVICE_ACCESS_TOKEN
00045 
00046 // ciclo di frequenza lettura
00047 #define SENSOR_READING_PERIOD     5000 //in ms
00048 
00049 #if COMM_PROTO==0    //MQTT protocol
00050 
00051   #define MQTT_HOST               "demo.thingsboard.io"
00052   #define MQTT_PORT               1883
00053   #define MQTT_TOPIC              "v1/devices/me/telemetry"
00054 
00055 #elif COMM_PROTO==1  //HTTP protocol
00056   #define HTTP_HOST               "demo.thingsboard.io"
00057   #define HTTP_PORT               80
00058   #define HTTP_STR_1              "/api/v1/"
00059   #define HTTP_STR_2              "/telemetry"
00060 
00061 #elif COMM_PROTO==2  //COAP protocol
00062   #define COAP_HOST               "demo.thingsboard.io"
00063   #define COAP_PORT               5683
00064   #define COAP_STR_1              "/api/v1/"
00065   #define COAP_STR_2              "/telemetry"
00066   
00067   #define SHOW_COAP_RESPONSE      false
00068 
00069 #endif              //end protocol
00070 
00071 // strutture comuni
00072 
00073 #if COMM_PROTO == 0
00074 class MQTTNetwork
00075 {
00076 public:
00077     MQTTNetwork(NetworkInterface* aNetwork) : network(aNetwork) {
00078         socket = new TCPSocket();
00079     }
00080 
00081     ~MQTTNetwork() {
00082         delete socket;
00083     }
00084 
00085     int read(unsigned char* buffer, int len, int timeout) {
00086         return socket->recv(buffer, len);
00087     }
00088 
00089     int write(unsigned char* buffer, int len, int timeout) {
00090         return socket->send(buffer, len);
00091     }
00092 
00093     int connect(const char* hostname, int port) {
00094         socket->open(network);
00095         return socket->connect(hostname, port);
00096     }
00097 
00098     int disconnect() {
00099         return socket->close();
00100     }
00101 
00102 private:
00103     NetworkInterface* network;
00104     TCPSocket* socket;
00105 };
00106 
00107 #elif COMM_PROTO==2  //COAP protocol
00108 UDPSocket socket;           // Socket to talk CoAP over
00109 Thread recvfromThread;      // Thread to receive messages over CoAP
00110 struct coap_s* coapHandle;
00111 coap_version_e coapVersion = COAP_VERSION_1;
00112 
00113 // CoAP HAL
00114 void* coap_malloc(uint16_t size) {
00115     return malloc(size);
00116 }
00117 
00118 void coap_free(void* addr) {
00119     free(addr);
00120 }
00121 
00122 // tx_cb and rx_cb are not used in this program
00123 uint8_t coap_tx_cb(uint8_t *a, uint16_t b, sn_nsdl_addr_s *c, void *d) {
00124     printf("coap tx cb\n");
00125     return 0;
00126 }
00127 
00128 int8_t coap_rx_cb(sn_coap_hdr_s *a, sn_nsdl_addr_s *b, void *c) {
00129     printf("coap rx cb\n");
00130     return 0;
00131 }
00132 
00133 
00134 #endif
00135 
00136 Serial pc(USBTX, USBRX); //use these pins for serial coms.
00137 int main()
00138 {
00139  
00140     int count = 0;
00141     pc.baud(115200);
00142     
00143     printf(" --- START SESSION ---\n");
00144     ISM43362Interface wifi(MBED_CONF_APP_WIFI_SPI_MOSI,
00145             MBED_CONF_APP_WIFI_SPI_MISO,
00146             MBED_CONF_APP_WIFI_SPI_SCLK,
00147             MBED_CONF_APP_WIFI_SPI_NSS,
00148             MBED_CONF_APP_WIFI_RESET,
00149             MBED_CONF_APP_WIFI_DATAREADY,
00150             MBED_CONF_APP_WIFI_WAKEUP, false);
00151 
00152     // Scanning WiFi networks ------------------------------------------
00153 
00154     WiFiAccessPoint *ap;
00155 
00156     count = wifi.scan(NULL, 0);
00157     printf("%d networks available.\n", count);
00158 
00159     /* Limit number of network arbitrary to 15 */
00160     count = count < 15 ? count : 15;
00161 
00162     ap = new WiFiAccessPoint[count];
00163     count = wifi.scan(ap, count);
00164     for (int i = 0; i < count; i++) {
00165         printf("Network: %s RSSI: %hhd\n", ap[i].get_ssid(), ap[i].get_rssi());
00166     }
00167 
00168     delete[] ap;
00169 
00170     // Connecting to WiFi network --------------------------------------
00171 
00172     printf("\nConnecting to %s...\n", WIFI_NETWORK_NAME);
00173     int ret = wifi.connect(WIFI_NETWORK_NAME, WIFI_NETWORK_PASSWORD, WIFI_SECURITY);
00174     if (ret != 0) {
00175         printf("\nConnection error\n");
00176         return -1;
00177     }
00178 
00179     printf("Success\n\n");
00180     printf("MAC: %s\n", wifi.get_mac_address());
00181     printf("IP: %s\n", wifi.get_ip_address());
00182     printf("Netmask: %s\n", wifi.get_netmask());
00183     printf("Gateway: %s\n", wifi.get_gateway());
00184     printf("RSSI: %d\n\n", wifi.get_rssi());
00185 
00186 #if COMM_PROTO == 0  //MQTT
00187     printf("Collegamento MQTT server: " MQTT_HOST  "\n");
00188 
00189     MQTTNetwork network(&wifi);
00190     MQTT::Client<MQTTNetwork, Countdown> client(network);
00191 
00192     char assess_token[] = DEVICE_ACCESS_TOKEN;
00193 
00194     MQTTPacket_connectData conn_data = MQTTPacket_connectData_initializer;
00195     conn_data.username.cstring = assess_token;
00196 
00197     if (network.connect(MQTT_HOST, MQTT_PORT) < 0) {
00198       printf("failed to connect to " MQTT_HOST  "\n");
00199       return -1;
00200     }
00201 
00202     if (client.connect(conn_data) < 0) {
00203       printf("failed to send MQTT connect message\n");
00204       return -1;
00205     }
00206 
00207     printf("successfully connect to MQTT server!\n");
00208 
00209 #elif COMM_PROTO == 1  //HTTP
00210 
00211     printf("Collegamento HTTP server: " HTTP_HOST  "\n");
00212     TCPSocket socket;
00213     nsapi_error_t response;
00214 
00215     // Open a socket on the network interface, and create a TCP connection 
00216     socket.open(&wifi);
00217     response = socket.connect(HTTP_HOST, HTTP_PORT);
00218     if(0 != response) {
00219         printf("Error connecting: %d\n", response);
00220         socket.close();
00221         return -1;
00222     }
00223     socket.close();
00224 #elif COMM_PROTO == 2 // COAP
00225     
00226     //inserire un test di invio dati al server coap
00227 
00228 
00229 #endif
00230 
00231 // Initialize sensors --------------------------------------------------
00232 
00233 uint8_t id;
00234     DevI2C i2c_2(PB_11, PB_10);
00235     HTS221Sensor hum_temp(&i2c_2);
00236 
00237     hum_temp.init(NULL);
00238     hum_temp.enable();
00239     hum_temp.read_id(&id);
00240     printf("HTS221  humidity & temperature sensor = 0x%X\r\n", id);
00241 
00242 // Variabili di appoggio  -----------------------------------------------
00243 #if COMM_PROTO == 1
00244     uint8_t http_request[1024];   
00245     char request_body[256];
00246     static   uint8_t http_resp[512];
00247     uint16_t reqLen;
00248     uint16_t respLen;
00249 
00250 #elif COMM_PROTO == 2 // COAP
00251     char coap_body[256];
00252     char coap_uri_path[256];
00253     uint16_t coap_message_id;
00254     coap_message_id=0;
00255     
00256 
00257 #endif
00258 
00259 
00260 
00261 
00262 // ciclo di lettura sensori e caricamento su cloud       
00263 for (;;) {
00264     float temp, humid;
00265 
00266     hum_temp.get_temperature(&temp);
00267     hum_temp.get_humidity(&humid);
00268     
00269     printf("ID: %d HTS221:  [temp] %.2f C, [hum]   %.2f%%\r\n", DEVICE_ID,temp, humid);
00270 
00271 #if COMM_PROTO == 0
00272     char msg[256];
00273     int n = snprintf(msg, sizeof(msg),
00274         "{\"ID\":%d,\"temperature\":%f, \"humidity\":%f}",
00275         DEVICE_ID,temp, humid);
00276 
00277     void *payload = reinterpret_cast<void*>(msg);
00278     size_t payload_len = n;
00279     printf("Message payload lenght: %d\r\n",payload_len);
00280     printf("publish to: %s %d %s\r\n", MQTT_HOST, MQTT_PORT, MQTT_TOPIC);
00281     if (client.publish(MQTT_TOPIC, payload, n) < 0) {
00282         printf("failed to publish MQTT message");
00283     }
00284     
00285 #elif COMM_PROTO == 1
00286     // ciclo di scrittura su socket
00287     // - open
00288     // - connect
00289     // - send 
00290     // - close
00291    
00292     socket.open(&wifi);
00293     response = socket.connect(HTTP_HOST, HTTP_PORT);
00294     if(0 != response) {
00295         printf("Error connecting: %d\n", response);
00296         socket.close();
00297         return -1;
00298     }
00299         
00300         
00301     // body of the request
00302 
00303     sprintf(request_body, "{\"ID\":%d,\"temperature\": %f,\"humidity\": %f}\r\n",DEVICE_ID, temp, humid);
00304 
00305     // build header of the request
00306     sprintf((char *)http_request, "POST %s%s%s HTTP/1.1\r\nHost: %s \r\n", HTTP_STR_1,DEVICE_ACCESS_TOKEN,HTTP_STR_2, HTTP_HOST);
00307     strcat((char *)http_request, "Accept: */*\r\n");
00308     strcat((char *)http_request, "User-agent: ST-475-IOT\r\n");
00309     strcat((char *)http_request, "Connection: Close\r\n"); 
00310     char buffer[64];
00311     strcat((char *)http_request, "Content-Type: application/json\r\n");
00312     sprintf(buffer, "Content-Length: %d \r\n\r\n", strlen(request_body));
00313     strcat((char *)http_request, buffer);
00314 
00315     // append body to the header of the request
00316     strcat((char *)http_request, request_body);
00317     reqLen = strlen((char *)http_request);
00318     printf((char *)http_request);
00319 
00320     // Send a simple http request
00321     
00322     nsapi_size_t size = strlen((char *)http_request);
00323     response = 0;
00324     
00325     while(size)
00326     {
00327         response = socket.send(((char *)http_request)+response, size);
00328         
00329         if (response < 0) {
00330             printf("Error sending data: %d\n", response);
00331             socket.close();
00332             return -1;
00333         } else {
00334             size -= response;
00335             // Check if entire message was sent or not
00336             printf("sent %d [%.*s]\n", response, strstr((char *)http_request, "\r\n")-(char *)http_request, (char *)http_request);
00337         }
00338     }
00339     // pulizia risorse della socket
00340     socket.close();        
00341         
00342 #elif COMM_PROTO == 2 //COAP              
00343    
00344 
00345     // Open a socket on the network interface
00346     socket.open(&wifi);
00347 
00348     // Initialize the CoAP protocol handle, pointing to local implementations on malloc/free/tx/rx functions
00349     coapHandle = sn_coap_protocol_init(&coap_malloc, &coap_free, &coap_tx_cb, &coap_rx_cb);
00350 
00351 
00352     // Path to the resource we want to retrieve
00353     sprintf(coap_uri_path, "%s%s%s", COAP_STR_1,DEVICE_ACCESS_TOKEN,COAP_STR_2);
00354     sprintf(coap_body, "{\"ID\":%d,\"temperature\": %f,\"humidity\": %f}\r\n", DEVICE_ID,temp, humid);
00355 
00356     printf ("URI PATH: %s\n",coap_uri_path);
00357     printf ("BODY: %s\n",coap_body);
00358     printf ("id: %d\n",coap_message_id);
00359 
00360     // See ns_coap_header.h
00361     sn_coap_hdr_s *coap_res_ptr = (sn_coap_hdr_s*)calloc(sizeof(sn_coap_hdr_s), 1);
00362     coap_res_ptr->uri_path_ptr = (uint8_t*)coap_uri_path;       // Path
00363     coap_res_ptr->uri_path_len = strlen(coap_uri_path);
00364     coap_res_ptr->msg_type = COAP_MSG_TYPE_NON_CONFIRMABLE;
00365     coap_res_ptr->msg_code = COAP_MSG_CODE_REQUEST_POST;         // CoAP method
00366     coap_res_ptr->content_format = COAP_CT_JSON;          // CoAP content type
00367     coap_res_ptr->payload_len = strlen(coap_body);                              // Body length
00368     coap_res_ptr->payload_ptr = (uint8_t*)coap_body;                              // Body pointer
00369     coap_res_ptr->options_list_ptr = 0;                         // Optional: options list
00370     coap_res_ptr->msg_id = coap_message_id;  //msg ID, don't forget to increase it
00371     coap_message_id++;
00372     
00373     // Calculate the CoAP message size, allocate the memory and build the message
00374     uint16_t message_len = sn_coap_builder_calc_needed_packet_data_size(coap_res_ptr);
00375     printf("Calculated message length: %d bytes\n", message_len);
00376 
00377     uint8_t* message_ptr = (uint8_t*)malloc(message_len);
00378     sn_coap_builder(message_ptr, coap_res_ptr);
00379 
00380     // Uncomment to see the raw buffer that will be sent...
00381      printf("Message is: ");
00382      for (size_t ix = 0; ix < message_len; ix++) {
00383          printf("%02x ", message_ptr[ix]);
00384      }
00385      printf("\n");
00386 
00387     int scount = socket.sendto(COAP_HOST, COAP_PORT, message_ptr, message_len);
00388     printf("Sent %d bytes to coap://%s:%d\n", scount,COAP_HOST, COAP_PORT);
00389 
00390 // routine di ricezione    
00391 #if SHOW_COAP_RESPONSE == true
00392     SocketAddress addr;
00393     uint8_t* recv_buffer = (uint8_t*)malloc(1280); // Suggested is to keep packet size under 1280 bytes
00394     
00395     if ((ret = socket.recvfrom(&addr, recv_buffer, 1280)) >= 0) {
00396         // to see where the message came from, inspect addr.get_addr() and addr.get_port()
00397   
00398         printf("Received packets from (%s,%d)\n", addr.get_ip_address(),addr.get_port());
00399 
00400         sn_coap_hdr_s* parsed = sn_coap_parser(coapHandle, ret, recv_buffer, &coapVersion);
00401 
00402         // We know the payload is going to be a string
00403         std::string payload((const char*)parsed->payload_ptr, parsed->payload_len);
00404 
00405         printf("\tmsg_id:           %d\n", parsed->msg_id);
00406         printf("\tmsg_code:         %d\n", parsed->msg_code);
00407         printf("\tcontent_format:   %d\n", parsed->content_format);
00408         printf("\tpayload_len:      %d\n", parsed->payload_len);
00409         printf("\tpayload:          %s\n", payload.c_str());
00410         printf("\toptions_list_ptr: %p\n", parsed->options_list_ptr);
00411     }
00412 
00413     free(recv_buffer);  
00414  
00415 
00416 #endif //end SHOW_COAP_RESPONSE   
00417     socket.close();
00418     sn_coap_protocol_destroy(coapHandle);
00419     free(coap_res_ptr);
00420     free(message_ptr);
00421 
00422      
00423 #endif //end protocol selection
00424     wait_ms(SENSOR_READING_PERIOD);
00425 }
00426 
00427 //le disconnect non vengono raggiunte perche' rimaniamo all'interno del ciclo
00428 //client.disconnect();
00429 //wifi.disconnect();
00430 
00431 //printf("\ndone\n");
00432 //return 0;
00433 
00434 }