Had to fork with a different name, because of some incompatibility issues.

Dependencies:   MQTT

Committer:
lamell
Date:
Tue Mar 10 21:26:49 2020 -0400
Revision:
23:1523bdaba8c8
Parent:
22:d9576c025cd7
Child:
24:8a0b0c410820
Changed NetworkInterface to EthernetInterchange.
Used mbed-os-5.14.1

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 22:d9576c025cd7 38 extern RawSerial pc;
lamell 18:ce12e2072cbb 39
lokeshhk 5:ea9f483e0294 40 namespace IoTF {
lokeshhk 5:ea9f483e0294 41
lokeshhk 5:ea9f483e0294 42 //Class to represent Network layer
lokeshhk 5:ea9f483e0294 43 class MQTTNetwork {
lokeshhk 5:ea9f483e0294 44 private:
lokeshhk 5:ea9f483e0294 45 //Variable to stored server port
lokeshhk 5:ea9f483e0294 46 int serverPort;
lokeshhk 5:ea9f483e0294 47
lokeshhk 5:ea9f483e0294 48 //Poniter mebers for mbedTLS structures
lokeshhk 5:ea9f483e0294 49 mbedtls_entropy_context* _entropy;
lokeshhk 5:ea9f483e0294 50 mbedtls_ctr_drbg_context* _ctr_drbg;
lamell 23:1523bdaba8c8 51
lokeshhk 5:ea9f483e0294 52 mbedtls_x509_crt* _cacert;
lokeshhk 5:ea9f483e0294 53 mbedtls_ssl_context* _ssl;
lokeshhk 5:ea9f483e0294 54 mbedtls_ssl_config* _ssl_conf;
lokeshhk 5:ea9f483e0294 55 public:
lamell 18:ce12e2072cbb 56 //Pointer member for ethernet interface
lamell 23:1523bdaba8c8 57 //NetworkInterface *network;
lamell 23:1523bdaba8c8 58 EthernetInterface *net;
lamell 23:1523bdaba8c8 59 //Pointer member to represent socket
lamell 23:1523bdaba8c8 60 TCPSocket socket;
lamell 23:1523bdaba8c8 61
lamell 18:ce12e2072cbb 62 //Default constructor to initialize network, mbedTLS structures
lokeshhk 5:ea9f483e0294 63 MQTTNetwork(): serverPort(1883){
lamell 23:1523bdaba8c8 64 pc.printf("serverPort\r\n");
lamell 23:1523bdaba8c8 65 net = new EthernetInterface;
lamell 23:1523bdaba8c8 66 //network->set_blocking(false);
lamell 23:1523bdaba8c8 67 net->set_blocking(false);
lamell 23:1523bdaba8c8 68 pc.printf("set_blocking(false)\r\n");
lokeshhk 5:ea9f483e0294 69 //Instantiate new ethernet interface
lamell 23:1523bdaba8c8 70 //network = new EthernetInterface();
lamell 23:1523bdaba8c8 71 pc.printf("Network\r\n");
lokeshhk 5:ea9f483e0294 72 //Connect to ethernet interface
lamell 23:1523bdaba8c8 73 //nsapi_error_t err = network->connect();
lamell 23:1523bdaba8c8 74 nsapi_error_t err = net->connect();
lamell 23:1523bdaba8c8 75 pc.printf("Connected %d\r\n",err);
lokeshhk 5:ea9f483e0294 76 //Create socket with created ethernet interface
lamell 23:1523bdaba8c8 77 //TCPSocket* socket;
lamell 18:ce12e2072cbb 78 //socket = new TCPSocket(network);
lamell 23:1523bdaba8c8 79 //socket.open(network);
lamell 23:1523bdaba8c8 80 socket.open(net);
lamell 23:1523bdaba8c8 81 pc.printf("Socket\r\n");
lokeshhk 5:ea9f483e0294 82 //Instantiate mbedTLS structures
lokeshhk 5:ea9f483e0294 83 _entropy = new mbedtls_entropy_context();
lokeshhk 5:ea9f483e0294 84 _ctr_drbg = new mbedtls_ctr_drbg_context();
lokeshhk 5:ea9f483e0294 85 _cacert = new mbedtls_x509_crt();
lokeshhk 5:ea9f483e0294 86 _ssl = new mbedtls_ssl_context();
lokeshhk 5:ea9f483e0294 87 _ssl_conf = new mbedtls_ssl_config();
lokeshhk 5:ea9f483e0294 88
lokeshhk 5:ea9f483e0294 89 //Initialize mbedTLS structures
lokeshhk 5:ea9f483e0294 90 mbedtls_entropy_init(_entropy);
lokeshhk 5:ea9f483e0294 91 mbedtls_ctr_drbg_init(_ctr_drbg);
lokeshhk 5:ea9f483e0294 92 mbedtls_x509_crt_init(_cacert);
lokeshhk 5:ea9f483e0294 93 mbedtls_ssl_init(_ssl);
lokeshhk 5:ea9f483e0294 94 mbedtls_ssl_config_init(_ssl_conf);
lokeshhk 5:ea9f483e0294 95 }
lokeshhk 5:ea9f483e0294 96
lamell 18:ce12e2072cbb 97 // //Getter method to return underlying EthernetInterface
lamell 18:ce12e2072cbb 98 // NetworkInterface* getEth()
lamell 18:ce12e2072cbb 99 // {
lamell 18:ce12e2072cbb 100 // return network;
lamell 18:ce12e2072cbb 101 // }
lokeshhk 5:ea9f483e0294 102
lokeshhk 5:ea9f483e0294 103 //Destructor to release the resources
lokeshhk 5:ea9f483e0294 104 ~MQTTNetwork() {
lokeshhk 5:ea9f483e0294 105 //Release mbedTLS resources
lokeshhk 5:ea9f483e0294 106 mbedtls_entropy_free(_entropy);
lokeshhk 5:ea9f483e0294 107 mbedtls_ctr_drbg_free(_ctr_drbg);
lokeshhk 5:ea9f483e0294 108 mbedtls_x509_crt_free(_cacert);
lokeshhk 5:ea9f483e0294 109 mbedtls_ssl_free(_ssl);
lokeshhk 5:ea9f483e0294 110 mbedtls_ssl_config_free(_ssl_conf);
lokeshhk 5:ea9f483e0294 111
lokeshhk 5:ea9f483e0294 112 //Free the allocated memory for socket and network pointers
lamell 18:ce12e2072cbb 113 //delete socket;
lamell 23:1523bdaba8c8 114 //delete network;
lamell 23:1523bdaba8c8 115 delete net;
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 23:1523bdaba8c8 131 //socket.open(network);
lamell 23:1523bdaba8c8 132 socket.open(net);
lokeshhk 5:ea9f483e0294 133 serverPort = port;
lokeshhk 5:ea9f483e0294 134 if(port == 1883)
lokeshhk 5:ea9f483e0294 135 //Establish unsecured socket connection
lamell 23:1523bdaba8c8 136
lamell 18:ce12e2072cbb 137 rc = socket.connect(host, port);
lokeshhk 5:ea9f483e0294 138 else{
lokeshhk 5:ea9f483e0294 139 //Establish secure socket connection using SSL/TLS
lokeshhk 5:ea9f483e0294 140 //Perform mbedTLS initialization
lokeshhk 5:ea9f483e0294 141 if((rc = initializeTLS(host)) == 0){
lamell 18:ce12e2072cbb 142 //if((rc = socket->connect(host, port))==0){
lamell 18:ce12e2072cbb 143 if((rc = socket.connect(host, port))==0){
lamell 18:ce12e2072cbb 144 pc.printf("Socket connection to %s:%d successful...\r\n",host,port);
lokeshhk 5:ea9f483e0294 145 //Perform SSL handshake
lokeshhk 5:ea9f483e0294 146 if ((rc = mbedtls_ssl_handshake(_ssl)) < 0) {
lokeshhk 5:ea9f483e0294 147 if (rc != MBEDTLS_ERR_SSL_WANT_READ &&
lokeshhk 5:ea9f483e0294 148 rc != MBEDTLS_ERR_SSL_WANT_WRITE) {
lamell 18:ce12e2072cbb 149 pc.printf("mbedtls_ssl_handshake failed - 0x%x\r\n", -rc);
lokeshhk 5:ea9f483e0294 150 }
lokeshhk 5:ea9f483e0294 151 goto exit;
lokeshhk 5:ea9f483e0294 152 }
lokeshhk 5:ea9f483e0294 153 }
lokeshhk 5:ea9f483e0294 154 }
lokeshhk 5:ea9f483e0294 155 }
lokeshhk 5:ea9f483e0294 156
lokeshhk 5:ea9f483e0294 157 exit:
lokeshhk 5:ea9f483e0294 158 return rc;
lokeshhk 5:ea9f483e0294 159 }
lokeshhk 5:ea9f483e0294 160
lokeshhk 5:ea9f483e0294 161 //Method to initialize mbedTLS structures
lokeshhk 5:ea9f483e0294 162 int initializeTLS(const char* hostName){
lokeshhk 5:ea9f483e0294 163 int rc = 0;
lokeshhk 5:ea9f483e0294 164
lokeshhk 5:ea9f483e0294 165 //Initialize entropy seeding
lokeshhk 5:ea9f483e0294 166 if ((rc = mbedtls_ctr_drbg_seed(_ctr_drbg, mbedtls_entropy_func, _entropy,
lokeshhk 5:ea9f483e0294 167 (const unsigned char *) tlsClientName,
lokeshhk 5:ea9f483e0294 168 sizeof (tlsClientName))) != 0) {
lamell 18:ce12e2072cbb 169 pc.printf("mbedtls_crt_drbg_init failed - 0x%x\r\n", -rc);
lokeshhk 5:ea9f483e0294 170 goto exit;
lokeshhk 5:ea9f483e0294 171 }
lokeshhk 5:ea9f483e0294 172
lokeshhk 5:ea9f483e0294 173 //Parse certificates into mbedTLS structure
lokeshhk 5:ea9f483e0294 174 if ((rc = mbedtls_x509_crt_parse(_cacert, (const unsigned char *) serverCert,
lokeshhk 5:ea9f483e0294 175 sizeof(serverCert))) != 0) {
lamell 18:ce12e2072cbb 176 pc.printf("mbedtls_x509_crt_parse for serverCert failed - 0x%x\r\n", -rc);
lokeshhk 5:ea9f483e0294 177 goto exit;
lokeshhk 5:ea9f483e0294 178 }
lokeshhk 5:ea9f483e0294 179
lokeshhk 5:ea9f483e0294 180 //Set ssl config details
lokeshhk 5:ea9f483e0294 181 if ((rc = mbedtls_ssl_config_defaults(_ssl_conf,
lokeshhk 5:ea9f483e0294 182 MBEDTLS_SSL_IS_CLIENT,
lokeshhk 5:ea9f483e0294 183 MBEDTLS_SSL_TRANSPORT_STREAM,
lokeshhk 5:ea9f483e0294 184 MBEDTLS_SSL_PRESET_DEFAULT)) != 0) {
lamell 18:ce12e2072cbb 185 pc.printf("mbedtls_ssl_config_defaults failed - 0x%x\r\n", -rc);
lokeshhk 5:ea9f483e0294 186 goto exit;
lokeshhk 5:ea9f483e0294 187 }
lokeshhk 5:ea9f483e0294 188
lokeshhk 5:ea9f483e0294 189 //Add parsed server certificate to ssl config
lokeshhk 5:ea9f483e0294 190 mbedtls_ssl_conf_ca_chain(_ssl_conf, _cacert, NULL);
lokeshhk 5:ea9f483e0294 191
lokeshhk 5:ea9f483e0294 192 mbedtls_ssl_conf_rng(_ssl_conf, mbedtls_ctr_drbg_random, _ctr_drbg);
lokeshhk 5:ea9f483e0294 193
lokeshhk 5:ea9f483e0294 194 //Set Server Certificate authorization mode
lokeshhk 5:ea9f483e0294 195 mbedtls_ssl_conf_authmode(_ssl_conf, MBEDTLS_SSL_VERIFY_NONE);
lokeshhk 5:ea9f483e0294 196
lokeshhk 5:ea9f483e0294 197 //Perform mbedTLS ssl setup
lokeshhk 5:ea9f483e0294 198 if ((rc = mbedtls_ssl_setup(_ssl, _ssl_conf)) != 0) {
lamell 18:ce12e2072cbb 199 pc.printf("mbedtls_ssl_setup failed - 0x%x\r\n", -rc);
lokeshhk 5:ea9f483e0294 200 goto exit;
lokeshhk 5:ea9f483e0294 201 }
lokeshhk 5:ea9f483e0294 202
lokeshhk 5:ea9f483e0294 203 //Set hostname to establish SSL connection
lokeshhk 5:ea9f483e0294 204 mbedtls_ssl_set_hostname(_ssl, hostName);
lokeshhk 5:ea9f483e0294 205
lokeshhk 5:ea9f483e0294 206 //Set buffer I/O methods for SSL connection
lamell 18:ce12e2072cbb 207 mbedtls_ssl_set_bio(_ssl, static_cast<void *>(&socket),
lokeshhk 5:ea9f483e0294 208 tlsWrite, tlsRead, NULL );
lokeshhk 5:ea9f483e0294 209
lokeshhk 5:ea9f483e0294 210 exit:
lokeshhk 5:ea9f483e0294 211 return rc;
lokeshhk 5:ea9f483e0294 212 }
lokeshhk 5:ea9f483e0294 213
lokeshhk 5:ea9f483e0294 214 //Method to read from SSL socket
lokeshhk 5:ea9f483e0294 215 static int tlsRead(void *ctx,unsigned char* buffer, size_t len) {
lokeshhk 5:ea9f483e0294 216 TCPSocket *socket = static_cast<TCPSocket *>(ctx);
lokeshhk 5:ea9f483e0294 217 int rc = socket->recv(buffer, len);
lokeshhk 5:ea9f483e0294 218 return rc;
lokeshhk 5:ea9f483e0294 219 }
lokeshhk 5:ea9f483e0294 220
lokeshhk 5:ea9f483e0294 221 //Method to write to SSL socket
lokeshhk 5:ea9f483e0294 222 static int tlsWrite(void *ctx,const unsigned char* buffer, size_t len) {
lokeshhk 5:ea9f483e0294 223 TCPSocket *socket = static_cast<TCPSocket *>(ctx);
lokeshhk 5:ea9f483e0294 224 int rc = socket->send(buffer, len);
lokeshhk 5:ea9f483e0294 225 return rc;
lokeshhk 5:ea9f483e0294 226 }
lokeshhk 5:ea9f483e0294 227
lokeshhk 5:ea9f483e0294 228 //Method to read MQTT Packets
lokeshhk 5:ea9f483e0294 229 int read(unsigned char* buffer, int len, int timeout) {
lokeshhk 5:ea9f483e0294 230 int rc = 0;
lokeshhk 5:ea9f483e0294 231
lokeshhk 5:ea9f483e0294 232 if(serverPort == 1883)
lamell 18:ce12e2072cbb 233 rc = socket.recv(buffer,len);
lokeshhk 5:ea9f483e0294 234 else
lokeshhk 5:ea9f483e0294 235 rc = mbedtls_ssl_read(_ssl, (unsigned char *) buffer, len);
lokeshhk 5:ea9f483e0294 236
lokeshhk 5:ea9f483e0294 237 return rc;
lokeshhk 5:ea9f483e0294 238 }
lokeshhk 5:ea9f483e0294 239
lokeshhk 5:ea9f483e0294 240 //Method to send MQTT Packets
lokeshhk 5:ea9f483e0294 241 int write(unsigned char* buffer, int len, int timeout) {
lokeshhk 5:ea9f483e0294 242 int rc = 0;
lokeshhk 5:ea9f483e0294 243
lokeshhk 5:ea9f483e0294 244 if(serverPort == 1883)
lamell 18:ce12e2072cbb 245 rc = socket.send(buffer,len);
lokeshhk 5:ea9f483e0294 246 else
lokeshhk 5:ea9f483e0294 247 rc = mbedtls_ssl_write(_ssl, (const unsigned char *) buffer, len);
lokeshhk 5:ea9f483e0294 248
lokeshhk 5:ea9f483e0294 249 return rc;
lokeshhk 5:ea9f483e0294 250 }
lokeshhk 5:ea9f483e0294 251
lokeshhk 5:ea9f483e0294 252 //Method to close socket connection
lokeshhk 5:ea9f483e0294 253 void disconnect(){
lamell 18:ce12e2072cbb 254 socket.close();
lokeshhk 5:ea9f483e0294 255 }
lokeshhk 5:ea9f483e0294 256
lokeshhk 5:ea9f483e0294 257 };
lokeshhk 5:ea9f483e0294 258 }
lokeshhk 5:ea9f483e0294 259 #endif