Luis Amell / IBMIoTF-2

Dependencies:   MQTT

Committer:
lamell
Date:
Sat Mar 21 15:36:30 2020 -0400
Revision:
25:f4727705353b
Parent:
24:8a0b0c410820
Child:
26:3cfeb898b183
Fixed some connectivity issues. Problem turned out to be the laptop sharing internet connections.
The system works well.

Who changed what in which revision?

UserRevisionLine numberNew contents of line
lokeshhk 5:ea9f483e0294 1 /*******************************************************************************
lokeshhk 5:ea9f483e0294 2 * Copyright (c) 2017 IBM Corp.
lokeshhk 5:ea9f483e0294 3 *
lokeshhk 5:ea9f483e0294 4 * All rights reserved. This program and the accompanying materials
lokeshhk 5:ea9f483e0294 5 * are made available under the terms of the Eclipse Public License v1.0
lokeshhk 5:ea9f483e0294 6 * and Eclipse Distribution License v1.0 which accompany this distribution.
lokeshhk 5:ea9f483e0294 7 *
lokeshhk 5:ea9f483e0294 8 * The Eclipse Public License is available at
lokeshhk 5:ea9f483e0294 9 * http://www.eclipse.org/legal/epl-v10.html
lokeshhk 5:ea9f483e0294 10 * and the Eclipse Distribution License is available at
lokeshhk 5:ea9f483e0294 11 * http://www.eclipse.org/org/documents/edl-v10.php.
lokeshhk 5:ea9f483e0294 12 *
lokeshhk 5:ea9f483e0294 13 * Contributors:
lokeshhk 5:ea9f483e0294 14 * Lokesh K Haralakatta Initial implementation to support mbed OS 5
lokeshhk 5:ea9f483e0294 15 * Lokesh K Haralakatta Added SSL/TLS Support
lokeshhk 5:ea9f483e0294 16 *******************************************************************************/
lokeshhk 5:ea9f483e0294 17 #ifndef MQTTNetwork_H
lokeshhk 5:ea9f483e0294 18 #define MQTTNetwork_H
lokeshhk 5:ea9f483e0294 19
lamell 18:ce12e2072cbb 20 //mbed
lamell 18:ce12e2072cbb 21 #include "mbed.h"
lamell 18:ce12e2072cbb 22
lokeshhk 5:ea9f483e0294 23 // Network related header files
lokeshhk 5:ea9f483e0294 24 #include "NetworkInterface.h"
lokeshhk 5:ea9f483e0294 25 #include "EthernetInterface.h"
lokeshhk 5:ea9f483e0294 26
lokeshhk 5:ea9f483e0294 27 // mbedTLS related header files
lokeshhk 5:ea9f483e0294 28 #include "mbedtls/platform.h"
lokeshhk 5:ea9f483e0294 29 #include "mbedtls/ssl.h"
lokeshhk 5:ea9f483e0294 30 #include "mbedtls/entropy.h"
lokeshhk 5:ea9f483e0294 31 #include "mbedtls/ctr_drbg.h"
lokeshhk 5:ea9f483e0294 32 #include "mbedtls/error.h"
lokeshhk 5:ea9f483e0294 33 #include "mbedtls/debug.h"
lokeshhk 5:ea9f483e0294 34
lokeshhk 5:ea9f483e0294 35 //Include certificates header
lokeshhk 5:ea9f483e0294 36 #include "Certificates.h"
lokeshhk 5:ea9f483e0294 37
lamell 25:f4727705353b 38 #include "Logging.h"
lamell 25:f4727705353b 39
lamell 25:f4727705353b 40 //extern RawSerial pc;
lamell 18:ce12e2072cbb 41
lokeshhk 5:ea9f483e0294 42 namespace IoTF {
lokeshhk 5:ea9f483e0294 43
lokeshhk 5:ea9f483e0294 44 //Class to represent Network layer
lokeshhk 5:ea9f483e0294 45 class MQTTNetwork {
lokeshhk 5:ea9f483e0294 46 private:
lokeshhk 5:ea9f483e0294 47 //Variable to stored server port
lokeshhk 5:ea9f483e0294 48 int serverPort;
lokeshhk 5:ea9f483e0294 49
lokeshhk 5:ea9f483e0294 50 //Poniter mebers for mbedTLS structures
lokeshhk 5:ea9f483e0294 51 mbedtls_entropy_context* _entropy;
lokeshhk 5:ea9f483e0294 52 mbedtls_ctr_drbg_context* _ctr_drbg;
lokeshhk 5:ea9f483e0294 53 mbedtls_x509_crt* _cacert;
lokeshhk 5:ea9f483e0294 54 mbedtls_ssl_context* _ssl;
lokeshhk 5:ea9f483e0294 55 mbedtls_ssl_config* _ssl_conf;
lokeshhk 5:ea9f483e0294 56 public:
lamell 18:ce12e2072cbb 57 //Pointer member for ethernet interface
lamell 25:f4727705353b 58 NetworkInterface *network;
lamell 25:f4727705353b 59
lamell 25:f4727705353b 60
lamell 25:f4727705353b 61 //EthernetInterface network;
lamell 25:f4727705353b 62 //Create socket with created ethernet interface
lamell 25:f4727705353b 63 TCPSocket socket;
lamell 25:f4727705353b 64
lamell 18:ce12e2072cbb 65 //Default constructor to initialize network, mbedTLS structures
lokeshhk 5:ea9f483e0294 66 MQTTNetwork(): serverPort(1883){
lamell 25:f4727705353b 67 <<<<<<< working copy
lamell 25:f4727705353b 68 =======
lamell 23:1523bdaba8c8 69 pc.printf("serverPort\r\n");
lamell 23:1523bdaba8c8 70 net = new EthernetInterface;
lamell 23:1523bdaba8c8 71 //network->set_blocking(false);
lamell 24:8a0b0c410820 72 //net->set_blocking(false);
lamell 24:8a0b0c410820 73 //pc.printf("set_blocking(false)\r\n");
lamell 25:f4727705353b 74 >>>>>>> destination
lokeshhk 5:ea9f483e0294 75 //Instantiate new ethernet interface
lamell 23:1523bdaba8c8 76 //network = new EthernetInterface();
lokeshhk 5:ea9f483e0294 77 //Connect to ethernet interface
lamell 25:f4727705353b 78 network = NetworkInterface::get_default_instance();
lamell 25:f4727705353b 79
lamell 25:f4727705353b 80 LOG("%d\r\n",network->connect());
lamell 25:f4727705353b 81 LOG("%d\r\n",socket.open(network));
lamell 25:f4727705353b 82
lokeshhk 5:ea9f483e0294 83 //Instantiate mbedTLS structures
lokeshhk 5:ea9f483e0294 84 _entropy = new mbedtls_entropy_context();
lokeshhk 5:ea9f483e0294 85 _ctr_drbg = new mbedtls_ctr_drbg_context();
lokeshhk 5:ea9f483e0294 86 _cacert = new mbedtls_x509_crt();
lokeshhk 5:ea9f483e0294 87 _ssl = new mbedtls_ssl_context();
lokeshhk 5:ea9f483e0294 88 _ssl_conf = new mbedtls_ssl_config();
lokeshhk 5:ea9f483e0294 89
lokeshhk 5:ea9f483e0294 90 //Initialize mbedTLS structures
lokeshhk 5:ea9f483e0294 91 mbedtls_entropy_init(_entropy);
lokeshhk 5:ea9f483e0294 92 mbedtls_ctr_drbg_init(_ctr_drbg);
lokeshhk 5:ea9f483e0294 93 mbedtls_x509_crt_init(_cacert);
lokeshhk 5:ea9f483e0294 94 mbedtls_ssl_init(_ssl);
lokeshhk 5:ea9f483e0294 95 mbedtls_ssl_config_init(_ssl_conf);
lokeshhk 5:ea9f483e0294 96 }
lokeshhk 5:ea9f483e0294 97
lamell 18:ce12e2072cbb 98 // //Getter method to return underlying EthernetInterface
lamell 18:ce12e2072cbb 99 // NetworkInterface* getEth()
lamell 18:ce12e2072cbb 100 // {
lamell 18:ce12e2072cbb 101 // return network;
lamell 18:ce12e2072cbb 102 // }
lokeshhk 5:ea9f483e0294 103
lokeshhk 5:ea9f483e0294 104 //Destructor to release the resources
lokeshhk 5:ea9f483e0294 105 ~MQTTNetwork() {
lokeshhk 5:ea9f483e0294 106 //Release mbedTLS resources
lokeshhk 5:ea9f483e0294 107 mbedtls_entropy_free(_entropy);
lokeshhk 5:ea9f483e0294 108 mbedtls_ctr_drbg_free(_ctr_drbg);
lokeshhk 5:ea9f483e0294 109 mbedtls_x509_crt_free(_cacert);
lokeshhk 5:ea9f483e0294 110 mbedtls_ssl_free(_ssl);
lokeshhk 5:ea9f483e0294 111 mbedtls_ssl_config_free(_ssl_conf);
lokeshhk 5:ea9f483e0294 112
lokeshhk 5:ea9f483e0294 113 //Free the allocated memory for socket and network pointers
lamell 25:f4727705353b 114 //delete network;
lamell 18:ce12e2072cbb 115 //delete socket;
lokeshhk 5:ea9f483e0294 116
lokeshhk 5:ea9f483e0294 117 //Free the allocated memory for mbedTLS structures
lokeshhk 5:ea9f483e0294 118 delete _entropy;
lokeshhk 5:ea9f483e0294 119 delete _ctr_drbg;
lokeshhk 5:ea9f483e0294 120 delete _cacert;
lokeshhk 5:ea9f483e0294 121 delete _ssl;
lokeshhk 5:ea9f483e0294 122 delete _ssl_conf;
lokeshhk 5:ea9f483e0294 123 }
lokeshhk 5:ea9f483e0294 124
lokeshhk 5:ea9f483e0294 125 //Connect method to establish TCP socket connection
lokeshhk 5:ea9f483e0294 126 //If port=1883, opens unsecured socket connection
lokeshhk 5:ea9f483e0294 127 //If port is other than 1883, opens secured socket connection
lokeshhk 5:ea9f483e0294 128 int connect(const char*host, int port){
lokeshhk 5:ea9f483e0294 129 int rc = -1;
lokeshhk 5:ea9f483e0294 130
lamell 25:f4727705353b 131
lamell 25:f4727705353b 132 LOG("%d\r\n",socket.open(network));
lamell 25:f4727705353b 133
lokeshhk 5:ea9f483e0294 134 serverPort = port;
lamell 25:f4727705353b 135 if(port == 1883) {
lokeshhk 5:ea9f483e0294 136 //Establish unsecured socket connection
lamell 25:f4727705353b 137
lamell 18:ce12e2072cbb 138 rc = socket.connect(host, port);
lamell 25:f4727705353b 139
lamell 25:f4727705353b 140 } else {
lokeshhk 5:ea9f483e0294 141 //Establish secure socket connection using SSL/TLS
lokeshhk 5:ea9f483e0294 142 //Perform mbedTLS initialization
lokeshhk 5:ea9f483e0294 143 if((rc = initializeTLS(host)) == 0){
lamell 18:ce12e2072cbb 144 //if((rc = socket->connect(host, port))==0){
lamell 25:f4727705353b 145 rc = socket.connect(host, port);
lamell 25:f4727705353b 146 //LOG("%d\r\n",rc);
lamell 25:f4727705353b 147 if((rc)==0){
lamell 25:f4727705353b 148 LOG("Socket connection to %s:%d successful...\r\n",host,port);
lokeshhk 5:ea9f483e0294 149 //Perform SSL handshake
lamell 25:f4727705353b 150 rc = mbedtls_ssl_handshake(_ssl);
lamell 25:f4727705353b 151 //LOG("%d\r\n",rc);
lamell 25:f4727705353b 152 if ((rc) < 0) {
lokeshhk 5:ea9f483e0294 153 if (rc != MBEDTLS_ERR_SSL_WANT_READ &&
lokeshhk 5:ea9f483e0294 154 rc != MBEDTLS_ERR_SSL_WANT_WRITE) {
lamell 25:f4727705353b 155 LOG("mbedtls_ssl_handshake failed - 0x%x\r\n", -rc);
lokeshhk 5:ea9f483e0294 156 }
lokeshhk 5:ea9f483e0294 157 goto exit;
lokeshhk 5:ea9f483e0294 158 }
lokeshhk 5:ea9f483e0294 159 }
lokeshhk 5:ea9f483e0294 160 }
lokeshhk 5:ea9f483e0294 161 }
lokeshhk 5:ea9f483e0294 162
lokeshhk 5:ea9f483e0294 163 exit:
lokeshhk 5:ea9f483e0294 164 return rc;
lokeshhk 5:ea9f483e0294 165 }
lokeshhk 5:ea9f483e0294 166
lokeshhk 5:ea9f483e0294 167 //Method to initialize mbedTLS structures
lokeshhk 5:ea9f483e0294 168 int initializeTLS(const char* hostName){
lokeshhk 5:ea9f483e0294 169 int rc = 0;
lamell 25:f4727705353b 170 LOG("initializeTLS(%s)\r\n",hostName);
lokeshhk 5:ea9f483e0294 171
lokeshhk 5:ea9f483e0294 172 //Initialize entropy seeding
lamell 25:f4727705353b 173 rc = mbedtls_ctr_drbg_seed(_ctr_drbg, mbedtls_entropy_func, _entropy,
lokeshhk 5:ea9f483e0294 174 (const unsigned char *) tlsClientName,
lamell 25:f4727705353b 175 sizeof (tlsClientName));
lamell 25:f4727705353b 176 //LOG("%d\r\n",rc);
lamell 25:f4727705353b 177 if ((rc) != 0) {
lamell 25:f4727705353b 178 LOG("mbedtls_crt_drbg_init failed - 0x%x\r\n", -rc);
lokeshhk 5:ea9f483e0294 179 goto exit;
lokeshhk 5:ea9f483e0294 180 }
lokeshhk 5:ea9f483e0294 181
lokeshhk 5:ea9f483e0294 182 //Parse certificates into mbedTLS structure
lamell 25:f4727705353b 183 rc = mbedtls_x509_crt_parse(_cacert, (const unsigned char *) serverCert,
lamell 25:f4727705353b 184 sizeof(serverCert));
lamell 25:f4727705353b 185 //LOG("%d\r\n",rc);
lamell 25:f4727705353b 186 if ((rc) != 0) {
lamell 25:f4727705353b 187 LOG("mbedtls_x509_crt_parse for serverCert failed - 0x%x\r\n", -rc);
lokeshhk 5:ea9f483e0294 188 goto exit;
lokeshhk 5:ea9f483e0294 189 }
lokeshhk 5:ea9f483e0294 190
lokeshhk 5:ea9f483e0294 191 //Set ssl config details
lamell 25:f4727705353b 192 rc = mbedtls_ssl_config_defaults(_ssl_conf,
lokeshhk 5:ea9f483e0294 193 MBEDTLS_SSL_IS_CLIENT,
lokeshhk 5:ea9f483e0294 194 MBEDTLS_SSL_TRANSPORT_STREAM,
lamell 25:f4727705353b 195 MBEDTLS_SSL_PRESET_DEFAULT);
lamell 25:f4727705353b 196 //LOG("%d\r\n",rc);
lamell 25:f4727705353b 197 if ((rc) != 0) {
lamell 25:f4727705353b 198 LOG("mbedtls_ssl_config_defaults failed - 0x%x\r\n", -rc);
lokeshhk 5:ea9f483e0294 199 goto exit;
lokeshhk 5:ea9f483e0294 200 }
lokeshhk 5:ea9f483e0294 201
lokeshhk 5:ea9f483e0294 202 //Add parsed server certificate to ssl config
lokeshhk 5:ea9f483e0294 203 mbedtls_ssl_conf_ca_chain(_ssl_conf, _cacert, NULL);
lamell 25:f4727705353b 204 //LOG("mbedtls_ssl_conf_ca_chain(_ssl_conf, _cacert, NULL)\r\n");
lokeshhk 5:ea9f483e0294 205 mbedtls_ssl_conf_rng(_ssl_conf, mbedtls_ctr_drbg_random, _ctr_drbg);
lamell 25:f4727705353b 206 //LOG("mbedtls_ssl_conf_rng(_ssl_conf, mbedtls_ctr_drbg_random, _ctr_drbg)\r\n");
lokeshhk 5:ea9f483e0294 207 //Set Server Certificate authorization mode
lokeshhk 5:ea9f483e0294 208 mbedtls_ssl_conf_authmode(_ssl_conf, MBEDTLS_SSL_VERIFY_NONE);
lamell 25:f4727705353b 209 //LOG("mbedtls_ssl_conf_authmode(_ssl_conf, MBEDTLS_SSL_VERIFY_NONE)\r\n");
lokeshhk 5:ea9f483e0294 210 //Perform mbedTLS ssl setup
lamell 25:f4727705353b 211 rc = mbedtls_ssl_setup(_ssl, _ssl_conf);
lamell 25:f4727705353b 212 //LOG("%d\r\n",rc);
lamell 25:f4727705353b 213 if ((rc) != 0) {
lamell 25:f4727705353b 214 LOG("mbedtls_ssl_setup failed - 0x%x\r\n", -rc);
lokeshhk 5:ea9f483e0294 215 goto exit;
lokeshhk 5:ea9f483e0294 216 }
lokeshhk 5:ea9f483e0294 217
lokeshhk 5:ea9f483e0294 218 //Set hostname to establish SSL connection
lokeshhk 5:ea9f483e0294 219 mbedtls_ssl_set_hostname(_ssl, hostName);
lamell 25:f4727705353b 220 //LOG("mbedtls_ssl_set_hostname(_ssl, hostName)\r\n");
lokeshhk 5:ea9f483e0294 221 //Set buffer I/O methods for SSL connection
lamell 18:ce12e2072cbb 222 mbedtls_ssl_set_bio(_ssl, static_cast<void *>(&socket),
lokeshhk 5:ea9f483e0294 223 tlsWrite, tlsRead, NULL );
lamell 25:f4727705353b 224 //LOG("mbedtls_ssl_set_bio(_ssl, static_cast<void *>(&socket),tlsWrite, tlsRead, NULL )\r\n");
lokeshhk 5:ea9f483e0294 225 exit:
lamell 25:f4727705353b 226 LOG("%d\r\n", rc);
lokeshhk 5:ea9f483e0294 227 return rc;
lokeshhk 5:ea9f483e0294 228 }
lokeshhk 5:ea9f483e0294 229
lokeshhk 5:ea9f483e0294 230 //Method to read from SSL socket
lokeshhk 5:ea9f483e0294 231 static int tlsRead(void *ctx,unsigned char* buffer, size_t len) {
lamell 25:f4727705353b 232 TCPSocket *readsocket = static_cast<TCPSocket *>(ctx);
lamell 25:f4727705353b 233 int rc = readsocket->recv(buffer, len);
lokeshhk 5:ea9f483e0294 234 return rc;
lokeshhk 5:ea9f483e0294 235 }
lokeshhk 5:ea9f483e0294 236
lokeshhk 5:ea9f483e0294 237 //Method to write to SSL socket
lokeshhk 5:ea9f483e0294 238 static int tlsWrite(void *ctx,const unsigned char* buffer, size_t len) {
lamell 25:f4727705353b 239 TCPSocket *wrsocket = static_cast<TCPSocket *>(ctx);
lamell 25:f4727705353b 240 int rc = wrsocket->send(buffer, len);
lokeshhk 5:ea9f483e0294 241 return rc;
lokeshhk 5:ea9f483e0294 242 }
lokeshhk 5:ea9f483e0294 243
lokeshhk 5:ea9f483e0294 244 //Method to read MQTT Packets
lokeshhk 5:ea9f483e0294 245 int read(unsigned char* buffer, int len, int timeout) {
lokeshhk 5:ea9f483e0294 246 int rc = 0;
lokeshhk 5:ea9f483e0294 247
lokeshhk 5:ea9f483e0294 248 if(serverPort == 1883)
lamell 18:ce12e2072cbb 249 rc = socket.recv(buffer,len);
lokeshhk 5:ea9f483e0294 250 else
lokeshhk 5:ea9f483e0294 251 rc = mbedtls_ssl_read(_ssl, (unsigned char *) buffer, len);
lokeshhk 5:ea9f483e0294 252
lokeshhk 5:ea9f483e0294 253 return rc;
lokeshhk 5:ea9f483e0294 254 }
lokeshhk 5:ea9f483e0294 255
lokeshhk 5:ea9f483e0294 256 //Method to send MQTT Packets
lokeshhk 5:ea9f483e0294 257 int write(unsigned char* buffer, int len, int timeout) {
lokeshhk 5:ea9f483e0294 258 int rc = 0;
lokeshhk 5:ea9f483e0294 259
lokeshhk 5:ea9f483e0294 260 if(serverPort == 1883)
lamell 18:ce12e2072cbb 261 rc = socket.send(buffer,len);
lokeshhk 5:ea9f483e0294 262 else
lokeshhk 5:ea9f483e0294 263 rc = mbedtls_ssl_write(_ssl, (const unsigned char *) buffer, len);
lokeshhk 5:ea9f483e0294 264
lokeshhk 5:ea9f483e0294 265 return rc;
lokeshhk 5:ea9f483e0294 266 }
lokeshhk 5:ea9f483e0294 267
lokeshhk 5:ea9f483e0294 268 //Method to close socket connection
lokeshhk 5:ea9f483e0294 269 void disconnect(){
lamell 18:ce12e2072cbb 270 socket.close();
lokeshhk 5:ea9f483e0294 271 }
lokeshhk 5:ea9f483e0294 272
lokeshhk 5:ea9f483e0294 273 };
lokeshhk 5:ea9f483e0294 274 }
lokeshhk 5:ea9f483e0294 275 #endif