Using CyaSSL library, which is included by default with MTSAS library.

Dependencies:   FP MQTTPacket

Fork of MQTTS by Vivek Ratna Kansakar

MQTTSocket.h

Committer:
vivekratna
Date:
2017-05-25
Revision:
49:8a88045f2b79
Parent:
48:4e7679e7ff94

File content as of revision 49:8a88045f2b79:

#if !defined(MQTTSOCKET_H)
#define MQTTSOCKET_H

#define NO_FILESYSTEM

#include "MQTTmbed.h"
#include "TCPSocketConnection.h"
#include "ssl.h"

#define MAX_URL_HOSTNAME_LENGTH 128
#define MAX_URL_PATH_LENGTH     128

//Debug is disabled by default
#if 0
//Enable debug
#include <cstdio>
#define DBG(x, ...) std::printf("[HTTPClient : DBG]"x"\r\n", ##__VA_ARGS__);
#define WARN(x, ...) std::printf("[HTTPClient : WARN]"x"\r\n", ##__VA_ARGS__);
#define ERR(x, ...) std::printf("[HTTPClient : ERR]"x"\r\n", ##__VA_ARGS__);

#else
//Disable debug
#define DBG(x, ...)
#define WARN(x, ...)
#define ERR(x, ...)

#endif

static  TCPSocketConnection* m_sock;
#define CHUNK_SIZE    256
#define SEND_BUF_SIZE 1024
static char send_buf[SEND_BUF_SIZE] ;
static char *send_buf_p = NULL;

static int SocketReceive(CYASSL* ssl, char *buf, int sz, void *ctx)
{
    int n ;
    int i ;
#define RECV_RETRY 3

    for(i=0; i<RECV_RETRY; i++) {
        n = m_sock->receive(buf, sz) ;
        if(n >= 0)return n  ;
        wait(0.2) ;
    }
    ERR("SocketReceive:%d/%d\n", n, sz)  ;
    return n ;
}

static int SocketSend(CYASSL* ssl, char *buf, int sz, void *ctx)
{
    int n ;

    wait(0.1);
    n = m_sock->send(buf, sz);
    if(n > 0) {
        wait(0.3);
        return n;
    } else {
    ERR("SocketSend:%d/%d\n", n, sz);
    }
    return n;
}

class MQTTSocket
{
public:
    MQTTSocket()
    {
        m_sock = &_m_sock;
        //CyaSSL_Debugging_ON() ;   //Turn on if the CyaSSL library isn't working, turns on debug printf's

        peerMethod = VERIFY_NONE;
        ctx = 0 ;
        ssl = 0 ;
        SSLver = 3 ;
        certificates = NULL;
        redirect_url = NULL ;
        redirect = 0 ;
        header = NULL ;
    }

    int connect(char* hostname, int port,  const char *certName = NULL, int timeout=1000)
    {

        m_sock->set_blocking(false, timeout);    // 1 second Timeout
        isTLS = certName == NULL ? false : true ;
        int ret = m_sock->connect(hostname, port);
        if((ret == 0) && isTLS) {
            return tls_connect(certName) ;
        } else return ret ;
    }

    int read(unsigned char* buffer, int len, int timeout)
    {
        m_sock->set_blocking(false, timeout);
        return isTLS ?
               CyaSSL_read(ssl, (char*)buffer, len) :
               m_sock->receive((char *)buffer, len) ;
    }

    int write(unsigned char* buffer, int len, int timeout)
    {
        m_sock->set_blocking(false, timeout);
        return isTLS ?
               CyaSSL_write(ssl, (char*)buffer, len) :
               m_sock->send((char *)buffer, len) ;
    }

    int disconnect()
    {
        if(isTLS) {
            CyaSSL_free(ssl);
            CyaSSL_CTX_free(ctx);
            CyaSSL_Cleanup();
        }
        return m_sock->close();
    }

private:

    // TCPSocketConnection m_sock;
    bool  isTLS ;
    // WOLFSSL_CTX* ctx;
    // WOLFSSL*     ssl;

    //Parameters
    TCPSocketConnection _m_sock;

    int m_timeout;

    const char* m_basicAuthUser;
    const char* m_basicAuthPassword;
    int m_httpResponseCode;

    const char * header ;
    char * redirect_url ;
    int    redirect_url_size ;
    int    redirect ;

    /* for CyaSSL */
    const char* certificates; //CA certificates
    SSLMethod peerMethod;
    int    SSLver ;
    uint16_t port;
    struct CYASSL_CTX* ctx ;
    struct CYASSL    * ssl ;

    int tls_connect(const char *certName)
    {
        /* create and initiLize WOLFSSL_CTX structure */
        if ((ctx = CyaSSL_CTX_new(CyaTLSv1_2_client_method())) == NULL) {
            printf("SSL_CTX_new error.\n");
            return EXIT_FAILURE;
        }
        if(*certName == '\0'){
            CyaSSL_CTX_set_verify(ctx, SSL_VERIFY_NONE, 0);
        } else {
            if (CyaSSL_CTX_load_verify_buffer(ctx, (const unsigned char*)certName, strlen(certName), SSL_FILETYPE_PEM) != SSL_SUCCESS)
                printf("can't load ca file\n");
        }

        CyaSSL_SetIORecv(ctx, SocketReceive) ;
        CyaSSL_SetIOSend(ctx, SocketSend) ;

        if ((ssl = CyaSSL_new(ctx)) == NULL) {
            printf("CyaSSL_new error.\n");
            return EXIT_FAILURE;
        }

        CyaSSL_SetIOReadCtx(ssl, (void *)m_sock) ;
        CyaSSL_SetIOWriteCtx(ssl, (void *)m_sock) ;

        if (CyaSSL_connect(ssl) != SSL_SUCCESS) {
            char data[32];
            printf("TLS Connect error, %s\n", CyaSSL_ERR_error_string(CyaSSL_get_error(ssl, 0), data));
            return EXIT_FAILURE;
        } else {
            logInfo("SSL Successs.");
            return 0 ;
        }
    }
};



#endif