Had to fork with a different name, because of some incompatibility issues.
MQTTNetwork.h
- Committer:
- lamell
- Date:
- 2020-09-14
- Revision:
- 29:40cc05c6c14b
- Parent:
- 26:3cfeb898b183
File content as of revision 29:40cc05c6c14b:
/******************************************************************************* * 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 //mbed #include "mbed.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" #include "Logging.h" //extern RawSerial pc; namespace IoTF { //Class to represent Network layer class MQTTNetwork { private: //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: //Pointer member for ethernet interface NetworkInterface *network; //EthernetInterface network; //Create socket with created ethernet interface TCPSocket socket; //Default constructor to initialize network, mbedTLS structures MQTTNetwork(): serverPort(1883){ //Instantiate new ethernet interface //network = new EthernetInterface(); //Connect to ethernet interface network = NetworkInterface::get_default_instance(); nsapi_error_t neterr = network->connect(); if (neterr != NSAPI_ERROR_OK) { debug("Net disconn %d\r\n",network->disconnect()); debug("%d\r\n",network->connect()); } debug("%d\r\n",socket.open(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 network; //delete socket; //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; LOG("%d\r\n",socket.open(network)); 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){ rc = socket.connect(host, port); //LOG("%d\r\n",rc); if((rc)==0){ LOG("Socket connection to %s:%d successful...\r\n",host,port); //Perform SSL handshake rc = mbedtls_ssl_handshake(_ssl); //LOG("%d\r\n",rc); if ((rc) < 0) { if (rc != MBEDTLS_ERR_SSL_WANT_READ && rc != MBEDTLS_ERR_SSL_WANT_WRITE) { LOG("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; LOG("initializeTLS(%s)\r\n",hostName); //Initialize entropy seeding rc = mbedtls_ctr_drbg_seed(_ctr_drbg, mbedtls_entropy_func, _entropy, (const unsigned char *) tlsClientName, sizeof (tlsClientName)); //LOG("%d\r\n",rc); if ((rc) != 0) { LOG("mbedtls_crt_drbg_init failed - 0x%x\r\n", -rc); goto exit; } //Parse certificates into mbedTLS structure rc = mbedtls_x509_crt_parse(_cacert, (const unsigned char *) serverCert, sizeof(serverCert)); //LOG("%d\r\n",rc); if ((rc) != 0) { LOG("mbedtls_x509_crt_parse for serverCert failed - 0x%x\r\n", -rc); goto exit; } //Set ssl config details rc = mbedtls_ssl_config_defaults(_ssl_conf, MBEDTLS_SSL_IS_CLIENT, MBEDTLS_SSL_TRANSPORT_STREAM, MBEDTLS_SSL_PRESET_DEFAULT); //LOG("%d\r\n",rc); if ((rc) != 0) { LOG("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); //LOG("mbedtls_ssl_conf_ca_chain(_ssl_conf, _cacert, NULL)\r\n"); mbedtls_ssl_conf_rng(_ssl_conf, mbedtls_ctr_drbg_random, _ctr_drbg); //LOG("mbedtls_ssl_conf_rng(_ssl_conf, mbedtls_ctr_drbg_random, _ctr_drbg)\r\n"); //Set Server Certificate authorization mode mbedtls_ssl_conf_authmode(_ssl_conf, MBEDTLS_SSL_VERIFY_NONE); //LOG("mbedtls_ssl_conf_authmode(_ssl_conf, MBEDTLS_SSL_VERIFY_NONE)\r\n"); //Perform mbedTLS ssl setup rc = mbedtls_ssl_setup(_ssl, _ssl_conf); //LOG("%d\r\n",rc); if ((rc) != 0) { LOG("mbedtls_ssl_setup failed - 0x%x\r\n", -rc); goto exit; } //Set hostname to establish SSL connection mbedtls_ssl_set_hostname(_ssl, hostName); //LOG("mbedtls_ssl_set_hostname(_ssl, hostName)\r\n"); //Set buffer I/O methods for SSL connection mbedtls_ssl_set_bio(_ssl, static_cast<void *>(&socket), tlsWrite, tlsRead, NULL ); //LOG("mbedtls_ssl_set_bio(_ssl, static_cast<void *>(&socket),tlsWrite, tlsRead, NULL )\r\n"); exit: LOG("%d\r\n", rc); return rc; } //Method to read from SSL socket static int tlsRead(void *ctx,unsigned char* buffer, size_t len) { TCPSocket *readsocket = static_cast<TCPSocket *>(ctx); int rc = readsocket->recv(buffer, len); return rc; } //Method to write to SSL socket static int tlsWrite(void *ctx,const unsigned char* buffer, size_t len) { TCPSocket *wrsocket = static_cast<TCPSocket *>(ctx); int rc = wrsocket->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