Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Diff: MQTTNetwork.h
- Revision:
- 5:ea9f483e0294
- Child:
- 18:ce12e2072cbb
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/MQTTNetwork.h Tue May 30 06:24:06 2017 +0000 @@ -0,0 +1,237 @@ +/******************************************************************************* + * Copyright (c) 2017 IBM Corp. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * and Eclipse Distribution License v1.0 which accompany this distribution. + * + * The Eclipse Public License is available at + * http://www.eclipse.org/legal/epl-v10.html + * and the Eclipse Distribution License is available at + * http://www.eclipse.org/org/documents/edl-v10.php. + * + * Contributors: + * Lokesh K Haralakatta Initial implementation to support mbed OS 5 + * Lokesh K Haralakatta Added SSL/TLS Support + *******************************************************************************/ +#ifndef MQTTNetwork_H +#define MQTTNetwork_H + +// Network related header files +#include "NetworkInterface.h" +#include "EthernetInterface.h" + +// mbedTLS related header files +#include "mbedtls/platform.h" +#include "mbedtls/ssl.h" +#include "mbedtls/entropy.h" +#include "mbedtls/ctr_drbg.h" +#include "mbedtls/error.h" +#include "mbedtls/debug.h" + +//Include certificates header +#include "Certificates.h" + +namespace IoTF { + + //Class to represent Network layer + class MQTTNetwork { + private: + //Pointer member for ethernet interface + NetworkInterface* network; + + //Pointer member to represent socket + TCPSocket* socket; + + //Variable to stored server port + int serverPort; + + //Poniter mebers for mbedTLS structures + mbedtls_entropy_context* _entropy; + mbedtls_ctr_drbg_context* _ctr_drbg; + mbedtls_x509_crt* _cacert; + mbedtls_ssl_context* _ssl; + mbedtls_ssl_config* _ssl_conf; + public: + //Default constructor to initialize network, mbedTLS structures + MQTTNetwork(): serverPort(1883){ + //Instantiate new ethernet interface + network = new EthernetInterface(); + //Connect to ethernet interface + network->connect(); + //Create socket with created ethernet interface + socket = new TCPSocket(network); + + //Instantiate mbedTLS structures + _entropy = new mbedtls_entropy_context(); + _ctr_drbg = new mbedtls_ctr_drbg_context(); + _cacert = new mbedtls_x509_crt(); + _ssl = new mbedtls_ssl_context(); + _ssl_conf = new mbedtls_ssl_config(); + + //Initialize mbedTLS structures + mbedtls_entropy_init(_entropy); + mbedtls_ctr_drbg_init(_ctr_drbg); + mbedtls_x509_crt_init(_cacert); + mbedtls_ssl_init(_ssl); + mbedtls_ssl_config_init(_ssl_conf); + } + + //Getter method to return underlying EthernetInterface + NetworkInterface* getEth() + { + return network; + } + + //Destructor to release the resources + ~MQTTNetwork() { + //Release mbedTLS resources + mbedtls_entropy_free(_entropy); + mbedtls_ctr_drbg_free(_ctr_drbg); + mbedtls_x509_crt_free(_cacert); + mbedtls_ssl_free(_ssl); + mbedtls_ssl_config_free(_ssl_conf); + + //Free the allocated memory for socket and network pointers + delete socket; + delete network; + + //Free the allocated memory for mbedTLS structures + delete _entropy; + delete _ctr_drbg; + delete _cacert; + delete _ssl; + delete _ssl_conf; + } + + //Connect method to establish TCP socket connection + //If port=1883, opens unsecured socket connection + //If port is other than 1883, opens secured socket connection + int connect(const char*host, int port){ + int rc = -1; + + serverPort = port; + if(port == 1883) + //Establish unsecured socket connection + rc = socket->connect(host, port); + else{ + //Establish secure socket connection using SSL/TLS + //Perform mbedTLS initialization + if((rc = initializeTLS(host)) == 0){ + if((rc = socket->connect(host, port))==0){ + printf("Socket connection to %s:%d successful...\r\n",host,port); + //Perform SSL handshake + if ((rc = mbedtls_ssl_handshake(_ssl)) < 0) { + if (rc != MBEDTLS_ERR_SSL_WANT_READ && + rc != MBEDTLS_ERR_SSL_WANT_WRITE) { + printf("mbedtls_ssl_handshake failed - 0x%x\r\n", -rc); + } + goto exit; + } + } + } + } + + exit: + return rc; + } + + //Method to initialize mbedTLS structures + int initializeTLS(const char* hostName){ + int rc = 0; + + //Initialize entropy seeding + if ((rc = mbedtls_ctr_drbg_seed(_ctr_drbg, mbedtls_entropy_func, _entropy, + (const unsigned char *) tlsClientName, + sizeof (tlsClientName))) != 0) { + printf("mbedtls_crt_drbg_init failed - 0x%x\r\n", -rc); + goto exit; + } + + //Parse certificates into mbedTLS structure + if ((rc = mbedtls_x509_crt_parse(_cacert, (const unsigned char *) serverCert, + sizeof(serverCert))) != 0) { + printf("mbedtls_x509_crt_parse for serverCert failed - 0x%x\r\n", -rc); + goto exit; + } + + //Set ssl config details + if ((rc = mbedtls_ssl_config_defaults(_ssl_conf, + MBEDTLS_SSL_IS_CLIENT, + MBEDTLS_SSL_TRANSPORT_STREAM, + MBEDTLS_SSL_PRESET_DEFAULT)) != 0) { + printf("mbedtls_ssl_config_defaults failed - 0x%x\r\n", -rc); + goto exit; + } + + //Add parsed server certificate to ssl config + mbedtls_ssl_conf_ca_chain(_ssl_conf, _cacert, NULL); + + mbedtls_ssl_conf_rng(_ssl_conf, mbedtls_ctr_drbg_random, _ctr_drbg); + + //Set Server Certificate authorization mode + mbedtls_ssl_conf_authmode(_ssl_conf, MBEDTLS_SSL_VERIFY_NONE); + + //Perform mbedTLS ssl setup + if ((rc = mbedtls_ssl_setup(_ssl, _ssl_conf)) != 0) { + printf("mbedtls_ssl_setup failed - 0x%x\r\n", -rc); + goto exit; + } + + //Set hostname to establish SSL connection + mbedtls_ssl_set_hostname(_ssl, hostName); + + //Set buffer I/O methods for SSL connection + mbedtls_ssl_set_bio(_ssl, static_cast<void *>(socket), + tlsWrite, tlsRead, NULL ); + + exit: + return rc; + } + + //Method to read from SSL socket + static int tlsRead(void *ctx,unsigned char* buffer, size_t len) { + TCPSocket *socket = static_cast<TCPSocket *>(ctx); + int rc = socket->recv(buffer, len); + return rc; + } + + //Method to write to SSL socket + static int tlsWrite(void *ctx,const unsigned char* buffer, size_t len) { + TCPSocket *socket = static_cast<TCPSocket *>(ctx); + int rc = socket->send(buffer, len); + return rc; + } + + //Method to read MQTT Packets + int read(unsigned char* buffer, int len, int timeout) { + int rc = 0; + + if(serverPort == 1883) + rc = socket->recv(buffer,len); + else + rc = mbedtls_ssl_read(_ssl, (unsigned char *) buffer, len); + + return rc; + } + + //Method to send MQTT Packets + int write(unsigned char* buffer, int len, int timeout) { + int rc = 0; + + if(serverPort == 1883) + rc = socket->send(buffer,len); + else + rc = mbedtls_ssl_write(_ssl, (const unsigned char *) buffer, len); + + return rc; + } + + //Method to close socket connection + void disconnect(){ + socket->close(); + } + + }; +} +#endif