TI's mqtt.
Diff: platform/cc31xx_sl_net.cpp
- Revision:
- 0:698866e331b2
diff -r 000000000000 -r 698866e331b2 platform/cc31xx_sl_net.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/platform/cc31xx_sl_net.cpp Sat Jun 06 13:29:50 2015 +0000 @@ -0,0 +1,661 @@ +/****************************************************************************** + * + * 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 +