TI's mqtt.

Dependencies:   client server

platform/cc31xx_sl_net.cpp

Committer:
dflet
Date:
2015-06-06
Revision:
1:673880ad39ad
Parent:
0:698866e331b2

File content as of revision 1:673880ad39ad:

/******************************************************************************
 *
 *   Copyright (C) 2014 Texas Instruments Incorporated
 *
 *   All rights reserved. Property of Texas Instruments Incorporated.
 *   Restricted rights to use, duplicate or disclose this code are
 *   granted through contract.
 *
 *   The program may not be used without the written permission of
 *   Texas Instruments Incorporated or against the terms and conditions
 *   stipulated in the agreement under which this program has been supplied,
 *   and under no circumstances can it be used with non-TI connectivity device.
 *
 ******************************************************************************/
//#include "mbed.h"
#include "cc3100_simplelink.h"
#include "cc3100_sl_common.h"
#include "cc31xx_sl_net.h"
#include "sl_mqtt_client.h"
#include "mqtt_client.h"
#include "cc3200_platform.h"
#include "cc3100.h"
#include "fPtr_func.h"
#include "myBoardInit.h"
#include "cli_uart.h"

#define PRINT_BUF_LEN    128
extern int8_t print_buf[PRINT_BUF_LEN];

using namespace mbed_cc3100;

#if (THIS_BOARD == MBED_BOARD_LPC1768)
cc3100 _cc3100_module_(p16, p17, p9, p10, p8, SPI(p5, p6, p7));//LPC1768  irq, nHib, cs, mosi, miso, sck
//cc3100 _cc3100_module_(p9, p10, p8, SPI(p11, p12, p13));//LPC1768  irq, nHib, cs, mosi, miso, sck
#elif (THIS_BOARD == Seeed_Arch_Max)
class cc3100 _cc3100_module_(PE_5, PE_4, PE_6, SPI(PB_5, PB_4, PB_3));
#elif (THIS_BOARD == ST_MBED_NUCLEOF103)
class cc3100 _cc3100_module_(PA_9, PC_7, PB_6, SPI(PA_7, PA_6, PA_5));//nucleoF103  irq, nHib, cs, mosi, miso, sck
#elif (THIS_BOARD == ST_MBED_NUCLEOF411)
class cc3100 _cc3100_module_(PA_9, PC_7, PB_6, SPI(PA_7, PA_6, PA_5));//nucleoF411  irq, nHib, cs, mosi, miso, sck
#elif (THIS_BOARD == ST_MBED_NUCLEOF401)
class cc3100 _cc3100_module_(PA_8, PA_9, PC_7, PB_6, SPI(PA_7, PA_6, PA_5));//nucleoF401  irq, nHib, cs, mosi, miso, sck
#elif (THIS_BOARD == EA_MBED_LPC4088)
class cc3100 _cc3100_module_(p14, p15, p9, p10, p8, SPI(p5, p6, p7));//LPC4088  irq, nHib, cs, mosi, miso, sck
#elif (THIS_BOARD == LPCXpresso4337)
class cc3100 _cc3100_module_(P2_2, P3_5, P1_2, SPI(P1_4, P1_3, PF_4));//LPCXpresso4337  irq, nHib, cs, mosi, miso, sck
#endif

namespace mbed_mqtt {

#ifdef DEBUG_NET_DEV
extern int32_t (*debug_printf)(const char *fmt, ...);
#define PRINTF(x,...)    debug_printf(x,##__VA_ARGS__)
#else
#define PRINTF(x,...)
#endif
/*
 3200 Devices specific Network Services Implementation
 */

#define LISTEN_QUE_SIZE 2

//*****************************************************************************
//                      GLOBAL VARIABLES
//*****************************************************************************

//*****************************************************************************
//                      STATIC FUNCTIONS
//*****************************************************************************

#ifdef DEBUG_NET_DEV
static int32_t buf_printf(const uint8_t *buf, uint32_t len, uint32_t idt)
{
    int32_t i = 0;
    for(i = 0; i < len; i++)
    {
        memset(print_buf, 0x00, PRINT_BUF_LEN);
        sprintf((char*) print_buf, "%02x ", *buf++);
        Uart_Write((uint8_t *) print_buf);

        if(0x03 == (i & 0x03))
        Uart_Write((uint8_t *)" ");

        if(0x0F == (i & 0x0F))
        {
            int32_t j = 0;
            Uart_Write((uint8_t *)"\n\r");

            for(j = 0; j < idt; j++)
            Uart_Write((uint8_t *)" ");
        }
    }

    Uart_Write((uint8_t *)"\n\r");

    return len;
}
#endif

/*-----------------------------------------------------------------------------
 Open a TCP socket and modify its properties i.e security options if req.
 Socket properties modified in this function are based on the options set
 outside the scope of this function.
 Returns a valid handle on success, otherwise a negative number.
 -----------------------------------------------------------------------------*/

static int32_t create_socket(uint32_t nwconn_opts, struct secure_conn *nw_security_opts)
{

    int32_t MqttSocketFd, Status;

    //local variables for creating secure socket
    uint8_t SecurityMethod;
    uint32_t SecurityCypher;
    int8_t i;

    //If TLS is required
    if ((nwconn_opts & DEV_NETCONN_OPT_SEC) != 0) // bit was set to 1
            {
        MqttSocketFd = _cc3100_module_._socket.sl_Socket(SL_AF_INET, SL_SOCK_STREAM, SL_SEC_SOCKET);
        if (MqttSocketFd < 0) {
            memset(print_buf, 0x00, PRINT_BUF_LEN);
            sprintf((char*) print_buf, "MqttSocketFd  fail %i\r\n",MqttSocketFd);
            Uart_Write((uint8_t *) print_buf);
            return (MqttSocketFd);
        }

        SecurityMethod = *((uint8_t *) (nw_security_opts->method));
        SecurityCypher = *((uint32_t *) (nw_security_opts->cipher));

        if (nw_security_opts->n_file < 1  || nw_security_opts->n_file > 4 ) {
            Uart_Write((uint8_t*)"\n\r ERROR: security files missing or wrong number of security files\n\r");
            Uart_Write((uint8_t*)"\n\r ERROR: Did not create socket\n\r");
            return (-1);
        }

        //Set Socket Options that were just defined
        Status = _cc3100_module_._socket.sl_SetSockOpt(MqttSocketFd, SL_SOL_SOCKET, SL_SO_SECMETHOD,
                &SecurityMethod, sizeof(SecurityMethod));
        if (Status < 0) {
            memset(print_buf, 0x00, PRINT_BUF_LEN);
            sprintf((char*) print_buf, "Status error %i socket closed\n\r",Status);
            Uart_Write((uint8_t *) print_buf);
            _cc3100_module_._socket.sl_Close(MqttSocketFd);
            return (Status);
        }

        Status = _cc3100_module_._socket.sl_SetSockOpt(MqttSocketFd, SL_SOL_SOCKET, SL_SO_SECURE_MASK,
                &SecurityCypher, sizeof(SecurityCypher));
        if (Status < 0) {
            memset(print_buf, 0x00, PRINT_BUF_LEN);
            sprintf((char*) print_buf, "Status error %i socket closed\n\r",Status);
            Uart_Write((uint8_t *) print_buf);
            _cc3100_module_._socket.sl_Close(MqttSocketFd);
            return (Status);
        }

        if(nw_security_opts->n_file == 1){
        	Status = _cc3100_module_._socket.sl_SetSockOpt(MqttSocketFd, SL_SOL_SOCKET, SL_SO_SECURE_FILES_CA_FILE_NAME,
        			 nw_security_opts->files[0], strlen(nw_security_opts->files[0]));
        	if (Status < 0) {
        		memset(print_buf, 0x00, PRINT_BUF_LEN);
                sprintf((char*) print_buf, "Status error %i socket closed\n\r",Status);
                Uart_Write((uint8_t *) print_buf);
				_cc3100_module_._socket.sl_Close(MqttSocketFd);
				return (Status);
			}
        }else{
        	for(i=0; i<nw_security_opts->n_file;i++){
        		if(NULL != nw_security_opts->files[i]){
        			Status = _cc3100_module_._socket.sl_SetSockOpt(MqttSocketFd, SL_SOL_SOCKET,
        					(SL_SO_SECURE_FILES_PRIVATE_KEY_FILE_NAME+i),
        			        nw_security_opts->files[i],
        			        strlen(nw_security_opts->files[i]));
        			if (Status < 0) {
        				memset(print_buf, 0x00, PRINT_BUF_LEN);
                        sprintf((char*) print_buf, "Status error %i socket closed\n\r",Status);
                        Uart_Write((uint8_t *) print_buf);
						_cc3100_module_._socket.sl_Close(MqttSocketFd);
						return (Status);
					}
        		}
        	}
        }

    }
    // If no TLS required
    else {
        // check to create a udp or tcp socket
        if ((nwconn_opts & DEV_NETCONN_OPT_UDP) != 0) // bit is set ; create a udp socket
                {
            MqttSocketFd = _cc3100_module_._socket.sl_Socket(SL_AF_INET, SL_SOCK_DGRAM, SL_IPPROTO_UDP);
        } else // socket for tcp
        {
            MqttSocketFd = _cc3100_module_._socket.sl_Socket(SL_AF_INET, SL_SOCK_STREAM,
            SL_IPPROTO_TCP); // consider putting 0 in place of SL_IPPROTO_TCP
        }
    }
    
    return (MqttSocketFd);

} // end of function

/*-----------------------------------------------------------------------------
 This function takes an ipv4 address in dot format i.e "a.b.c.d" and returns the
 ip address in Network byte Order, which can be used in connect call
 It returns 0, if a valid ip address is not detected.
 -----------------------------------------------------------------------------*/

static uint32_t svr_addr_NB_order_IPV4(char *svr_addr_str)
{
    uint8_t addr[4];
    int8_t i = 0;
    char *token;
    uint32_t svr_addr;
    int32_t temp;

    /*take a temporary copy of the string. strtok modifies the input string*/
    int8_t svr_addr_size = strlen(svr_addr_str);
    char *svr_addr_cpy = (char*)malloc(svr_addr_size + 1); //1 for null
	if(NULL == svr_addr_cpy) return 0;
    strcpy(svr_addr_cpy, svr_addr_str);

    memset(print_buf, 0x00, PRINT_BUF_LEN);
    sprintf((char*) print_buf, "\n\r server address = %s\n\r", svr_addr_cpy);
    Uart_Write((uint8_t *) print_buf);
    memset(print_buf, 0x00, PRINT_BUF_LEN);
    sprintf((char*) print_buf, "\n\r server address string length = %d\n\r", strlen(svr_addr_cpy));
    Uart_Write((uint8_t *) print_buf);

    /* get the first token */
    token = strtok((char*)svr_addr_cpy, ".");

    /* walk through other tokens */
    while (token != NULL) {
        temp = atoi((const char*)token);

        //check for invalid tokens or if already 4 tokens were obtained
        if ((temp < 0) || (temp > 255) || (i >= 4)) {
            free(svr_addr_cpy);
            return (0);
        }

        addr[i++] = (uint8_t) temp;
        token = strtok(NULL, ".");
    }

    // check if exactly 4 valid tokens are available or not
    if (i != 4) {
        free(svr_addr_cpy);
        return (0);
    }

    //form address if above test passed
    svr_addr = *((uint32_t *) &addr);
    free(svr_addr_cpy);

    return (svr_addr);

} // end of function

//*****************************************************************************
//                      Network Services functions
//*****************************************************************************

/*-----------------------------------------------------------------------------
 Open a TCP socket with required properties
 Also connect to the server.
 Returns a valid handle on success, NULL on failure.
 -----------------------------------------------------------------------------*/

int32_t comm_open(uint32_t nwconn_opts, const char *server_addr, uint16_t port_number,
        const struct secure_conn *nw_security)
{

    int32_t Status, MqttSocketFd;

    SlSockAddrIn_t LocalAddr; //address of the server to connect to
    int32_t LocalAddrSize;

    uint32_t uiIP;

    // create socket
    MqttSocketFd = create_socket(nwconn_opts,
            (struct secure_conn*) nw_security);

    if (MqttSocketFd < 0) {
        Uart_Write((uint8_t*)"\n\r ERROR: Could not create a socket.\n\r");
        return -1;
    }

    if ((nwconn_opts & DEV_NETCONN_OPT_UDP) != 0) // bit is set ; create a udp socket
            {
        //filling the UDP server socket address
        LocalAddr.sin_family = SL_AF_INET;
        LocalAddr.sin_port = _cc3100_module_._socket.sl_Htons((unsigned short) port_number);
        LocalAddr.sin_addr.s_addr = 0;
        LocalAddrSize = sizeof(SlSockAddrIn_t);

        Status = _cc3100_module_._socket.sl_Bind(MqttSocketFd, (SlSockAddr_t *) &LocalAddr,
                LocalAddrSize);
        if (Status < 0) {
            // error
            Uart_Write((uint8_t*)"\n\r ERROR: Could not bind socket.\n\r");
            _cc3100_module_._socket.sl_Close(MqttSocketFd);
            return -1;
        }
    } else // do tcp connection
    {
        // get the ip address of server to do tcp connect
        if ((nwconn_opts & DEV_NETCONN_OPT_URL) != 0) // server address is a URL
                {
            Status = _cc3100_module_._netapp.sl_NetAppDnsGetHostByName((uint8_t*) server_addr,
                    strlen(server_addr), (uint32_t*) &uiIP, SL_AF_INET);

            if (Status < 0) {
                Uart_Write((uint8_t*)"\n\r ERROR: Could not resolve the ip address of the server \n\r");
                return (-1);
            }
            // convert the address to network byte order as the function returns in host byte order
            uiIP = _cc3100_module_._socket.sl_Htonl(uiIP);
        } else // server address is a string in dot notation
        {
            if ((nwconn_opts & DEV_NETCONN_OPT_IP6) != 0) // server address is an IPV6 address string
                    {
                Uart_Write((uint8_t*)"\n\r ERROR: Currently do not support IPV6 addresses \n\r");
                return (-1);
            } else // address is an IPv4 string
            {
                // get the server ip address in Network Byte order
                uiIP = svr_addr_NB_order_IPV4((char*) server_addr);
                if (0 == uiIP) {
                    Uart_Write((uint8_t*)"\n\r ERROR: Could not resolve the ip address of the server \n\r");
                    return (-1);
                }
            }

        }

        LocalAddr.sin_family = SL_AF_INET;
        LocalAddr.sin_addr.s_addr = uiIP;
        LocalAddr.sin_port = _cc3100_module_._socket.sl_Htons(port_number);
        LocalAddrSize = sizeof(SlSockAddrIn_t);

        // do tcp connect
        Status = _cc3100_module_._socket.sl_Connect(MqttSocketFd, (SlSockAddr_t *) &LocalAddr,
                LocalAddrSize);

        if (Status < 0) {
            if (SL_ESECSNOVERIFY != Status) {
                Uart_Write((uint8_t*)" \n\r ERROR: Could not establish connection to server.\n\r");Uart_Write((uint8_t*)" \n\r ERROR: Closing the socket.\n\r");

                _cc3100_module_._socket.sl_Close(MqttSocketFd);
                return (-1);
            } else // SL_ESECSNOVERIFY == Status
            {
                Uart_Write((uint8_t*)" \n\r ERROR: Could not establish secure connection to server.\n\r");Uart_Write((uint8_t*)" \n\r Continuing with unsecure connection to server...\n\r");
            }
        }

        // Success
        Uart_Write((uint8_t*)"\n\r Connected to server ....\n\r");

    } // end of doing binding port to udp socket or doing tcp connect

    // set Timer for host processor
    platform_timer_init();
    
    return (MqttSocketFd);

} // end of function

int32_t tcp_send(int32_t comm, const uint8_t *buf, uint32_t len, void *ctx)
{

    int32_t Status;

    PRINTF("\n\r TCP send invoked for data with len %d\n\r", len);PRINTF("\n\r Sent Data : ");

#ifdef DEBUG_NET_DEV
    buf_printf(buf, len, 0);
#endif

    Status = _cc3100_module_._socket.sl_Send(comm, buf, len, 0);

    return (Status);

} // end of function

int32_t tcp_recv(int32_t comm, uint8_t *buf, uint32_t len, uint32_t wait_secs, bool *timed_out, void *ctx)
{
    int32_t Status;
    int32_t MqttSocketFd = comm;

#ifdef SOC_RCV_TIMEOUT_OPT

    // socket receive time out options
    SlTimeval_t timeVal;

    // recv time out options
    timeVal.tv_sec = wait_secs;      // Seconds
    timeVal.tv_usec = 0;          // Microseconds. 10000 microseconds resoultion

    /*------------------- setting receive timeout option on socket ---------------------*/

    Status = _cc3100_module_._socket.sl_SetSockOpt(MqttSocketFd, SOL_SOCKET, SL_SO_RCVTIMEO, &timeVal,
            sizeof(timeVal));

    if (Status == 0) {

    } else if (Status < 0) {
        Uart_Write((uint8_t*)"\n\r ERROR: setting socket recv_timeout_option unsuccessfull! \n\r");

    }
    /*--------------end of setting receive timeout option on socket ---------------------*/

#endif

//    printf("\n\r TCP recv invoked ...\n\r");
    *timed_out = 0;

    Status = _cc3100_module_._socket.sl_Recv(MqttSocketFd, buf, len, 0);

    if (Status > 0) {
#ifdef DEBUG_NET_DEV
        buf_printf(buf, Status, 0);
#endif
    }

    if (0 == Status) {
        Uart_Write((uint8_t*)"\n\r Connection Closed by peer....\n\r");
    }

    if (SL_EAGAIN == Status) {
        Uart_Write((uint8_t*)"\n\r ERROR: Recv Time out error on server socket \n\r");
        *timed_out = 1;
    }

    return (Status);

}             // end of function

int32_t comm_close(int32_t comm) {
    int32_t Status;

    Status = _cc3100_module_._socket.sl_Close(comm);
    return (Status);

}             // end of function

uint32_t rtc_secs(void) {
    return(platform_get_time_in_secs());   
}             // end of function

//--------------------------- adding functions for server functionalities ---------------------------

int32_t tcp_listen(uint32_t nwconn_info, uint16_t port_number,
        const struct secure_conn *nw_security)
{
    SlSockAddrIn_t sLocalAddr;
    int32_t iSockID, iAddrSize;
    int32_t iStatus;

    //filling the TCP server socket address
    sLocalAddr.sin_family = SL_AF_INET;
    sLocalAddr.sin_port = _cc3100_module_._socket.sl_Htons(port_number);
    sLocalAddr.sin_addr.s_addr = 0;
    iAddrSize = sizeof(SlSockAddrIn_t);

    // creating a TCP socket
    iSockID = _cc3100_module_._socket.sl_Socket(SL_AF_INET, SL_SOCK_STREAM, 0);
    if (iSockID < 0) {
        // error
        return (-1);
    }

    // binding the TCP socket to the TCP server address
    iStatus = _cc3100_module_._socket.sl_Bind(iSockID, (SlSockAddr_t *) &sLocalAddr, iAddrSize);
    if (iStatus < 0) {
        // error
        _cc3100_module_._socket.sl_Close(iSockID);
        return (-1);
    }

    // putting the socket for listening to the incoming TCP connection
    iStatus = _cc3100_module_._socket.sl_Listen(iSockID, LISTEN_QUE_SIZE);
    if (iStatus < 0) {
        _cc3100_module_._socket.sl_Close(iSockID);
        return (-1);
    }

    memset(print_buf, 0x00, PRINT_BUF_LEN);
    sprintf((char*) print_buf, "\n\r\t Server Socket created and listening on port number: %d! \n\r", port_number);
    Uart_Write((uint8_t *) print_buf);

    return (iSockID);

}             // end of function

int32_t tcp_select(int32_t *recv_cvec, int32_t *send_cvec, int32_t *rsvd_cvec, uint32_t wait_secs)
{

    SlTimeval_t tv, *p_tv;
    SlFdSet_t rdfds;
    int32_t rd_idx = 0, wr_idx = 0, max_fd = 0;
    int32_t rv = 0;

    tv.tv_sec = wait_secs;
    tv.tv_usec = 0;

    p_tv = (0xFFFFFFFF != wait_secs) ? &tv : NULL;

    _cc3100_module_._socket.SL_FD_ZERO(&rdfds);

    while (-1 != recv_cvec[rd_idx]) {
        int32_t fd = recv_cvec[rd_idx++];

        _cc3100_module_._socket.SL_FD_SET(fd, &rdfds);

        if (max_fd < fd){
            max_fd = fd;
        }    
    }

//    printf("Blocking network for (%s) %u secs to monitor %d fd(s)\n\r",
//            p_tv? "finite" : "forever", wait_secs, rd_idx);

    rv = _cc3100_module_._socket.sl_Select(max_fd + 1, &rdfds, NULL, NULL, p_tv);

    if (rv <= 0) {
//        printf("Select Failed %i\n\r",rv);
        return rv;
    }

    rd_idx = 0;
    while (-1 != recv_cvec[rd_idx]) {
        int32_t fd = recv_cvec[rd_idx++];
        if (_cc3100_module_._socket.SL_FD_ISSET(fd, &rdfds))
            recv_cvec[wr_idx++] = fd;
    }

    recv_cvec[wr_idx] = NULL;

//    printf("Number of sockets on which activity is observed = %d \n\r", wr_idx);

    return (wr_idx);
}             // end of function

int32_t tcp_accept(int32_t listen_hnd, uint8_t *client_ip, uint32_t *ip_length)
{
    int32_t new_fd;
    SlSockAddrIn_t client_addr = {0}; // client address
    SlSocklen_t cl_addr_size;

    cl_addr_size = sizeof(client_addr);

    new_fd = _cc3100_module_._socket.sl_Accept(listen_hnd, (SlSockAddr_t *) &client_addr,
                       &cl_addr_size);

    if (new_fd < 0) {
        Uart_Write((uint8_t*)"\n\r ERROR: in accept \n\r");
        return (NULL);
    }

    client_ip[0] = (client_addr.sin_addr.s_addr & 0xFF000000) >> 24;
    client_ip[1] = (client_addr.sin_addr.s_addr & 0x00FF0000) >> 16;
    client_ip[2] = (client_addr.sin_addr.s_addr & 0x0000FF00) >> 8;
    client_ip[3] = (client_addr.sin_addr.s_addr & 0x000000FF);

    *ip_length = 4;

    return new_fd;

} // end of function

//--------------------------- adding functions for udp functionalities ---------------------------

int32_t send_dest(int32_t comm, const uint8_t *buf, uint32_t len, uint16_t dest_port,
              const uint8_t *dest_ip, uint32_t ip_len)
{

    int32_t iSockID = (int32_t) comm;
    int32_t iStatus, iAddrSize;
    SlSockAddrIn_t sAddr;
    uint32_t uiDestIp;

    //get destination ip
#if 0
    uiDestIp = svr_addr_NB_order_IPV4((uint8_t*)dest_ip); //assuming a IPV4 address is passed in dot notation.
    if( 0 == uiDestIp )
    {
        Uart_Write((uint8_t*)"\n\r ERROR: Could not resolve the ip address of the destination \n\r");
        return(-1);
    }
#else
    uiDestIp = (((uint32_t) dest_ip[0] << 24) | ((uint32_t) dest_ip[1] << 16)
            | (dest_ip[2] << 8) | (dest_ip[3]));

//    printf("Writing to %d, %08x\r\n", (int32_t)comm, uiDestIp);

#endif

    //filling the UDP server socket address
    sAddr.sin_family = SL_AF_INET;
    sAddr.sin_port = _cc3100_module_._socket.sl_Htons((unsigned short) dest_port);
    sAddr.sin_addr.s_addr = _cc3100_module_._socket.sl_Htonl(uiDestIp);

    iAddrSize = sizeof(SlSockAddrIn_t);

    // sending packet
    iStatus = _cc3100_module_._socket.sl_SendTo(iSockID, buf, len, 0, (SlSockAddr_t *) &sAddr,
            iAddrSize);

    if (iStatus <= 0) {
        // error
        _cc3100_module_._socket.sl_Close(iSockID);
        Uart_Write((uint8_t*)"Error: Closed the UDP socket\n\r");
    }
    
    return (iStatus);

} // end of function

int32_t recv_from(int32_t comm, uint8_t *buf, uint32_t len, uint16_t *from_port, uint8_t *from_ip, uint32_t *ip_len)
{

    int32_t iSockID = (int32_t) comm;
    int32_t iStatus, iAddrSize;
    SlSockAddrIn_t fromAddr = {0};

    iAddrSize = sizeof(SlSockAddrIn_t);

    iStatus = _cc3100_module_._socket.sl_RecvFrom(iSockID, buf, len, 0, (SlSockAddr_t *) &fromAddr,
                          (SlSocklen_t*) &iAddrSize);

    if (iStatus < 0) {
        // error
        _cc3100_module_._socket.sl_Close(iSockID);
        Uart_Write((uint8_t*)"Error: Closed the UDP socket\n\r");
        return (iStatus);
    }

    //else populate from ip, from_port and ip_len parameters
    // refer to comments in .h
    if (from_port)
        *from_port = fromAddr.sin_port;

    if (from_ip) {
        from_ip[0] = (fromAddr.sin_addr.s_addr & 0xFF000000) >> 24;
        from_ip[1] = (fromAddr.sin_addr.s_addr & 0x00FF0000) >> 16;
        from_ip[2] = (fromAddr.sin_addr.s_addr & 0x0000FF00) >> 8;
        from_ip[3] = (fromAddr.sin_addr.s_addr & 0x000000FF);
        *ip_len = 4;
    }

    return (iStatus);

}    // end of function

}//namespace mbed_mqtt