Jim Flynn / Mbed OS aws-iot-device-sdk-mbed-c
Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers network.cpp Source File

network.cpp

00001 /*
00002  *  TCP/IP or UDP/IP networking functions
00003  *
00004  *  This version of net_sockets.c is setup to use ARM easy-connect for network connectivity
00005  *
00006  *
00007  *  Licensed under the Apache License, Version 2.0 (the "License"); you may
00008  *  not use this file except in compliance with the License.
00009  *  You may obtain a copy of the License at
00010  *
00011  *  http://www.apache.org/licenses/LICENSE-2.0
00012  *
00013  *  Unless required by applicable law or agreed to in writing, software
00014  *  distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
00015  *  WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
00016  *  See the License for the specific language governing permissions and
00017  *  limitations under the License.
00018  *
00019  */
00020 
00021 #include "mbed.h"
00022 
00023 #include "easy-connect.h"
00024 
00025 #define MBEDTLS_FS_IO 1
00026 
00027 #include <stdbool.h>
00028 #include <string.h>
00029 #include <timer_platform.h >
00030 #include <network_interface.h>
00031 
00032 #include "mbedtls/platform.h"
00033 #include "mbedtls/ssl.h"
00034 #include "mbedtls/entropy.h"
00035 #include "mbedtls/ctr_drbg.h"
00036 #include "mbedtls/error.h"
00037 #include "mbedtls/x509_crt.h"
00038 #include "mbedtls/pk.h"
00039 
00040 #if DEBUG_LEVEL > 0
00041 #include "mbedtls/debug.h"
00042 #endif
00043 
00044 #include "aws_iot_error.h"
00045 #include "aws_iot_log.h"
00046 #include "network_interface.h"
00047 #include "network_platform.h"
00048 
00049 #include "awscerts.h"
00050 
00051 
00052 NetworkInterface *network = NULL;
00053 TCPSocket        mbedtls_socket;
00054 bool             network_connected = false;
00055 
00056 /*
00057  * Initialize a context
00058  */
00059 void mbedtls_aws_init( mbedtls_net_context *ctx )
00060 {
00061     FUNC_ENTRY;
00062 
00063     if( network != NULL )
00064         network->disconnect();       //disconnect from the current network
00065 
00066     network_connected = false;
00067     network = easy_connect(true);
00068     if (!network) {
00069         IOT_DEBUG("Network Connection Failed!");
00070         return;
00071         }
00072     IOT_DEBUG("Modem SW Revision: %s", FIRMWARE_REV(network));
00073     network_connected = true;
00074     ctx->fd = 1;
00075 }
00076 
00077 /*
00078  * Initiate a TCP connection with host:port and the given protocol
00079  * return 0 if success, otherwise error is returned
00080  */
00081 int mbedtls_aws_connect( mbedtls_net_context *ctx, const char *host, uint16_t port, int proto )
00082 {
00083     FUNC_ENTRY;
00084     if( !network_connected ) {
00085         IOT_DEBUG("No network connection");
00086         FUNC_EXIT_RC(NETWORK_ERR_NET_CONNECT_FAILED);
00087         }
00088 
00089     int ret = mbedtls_socket.open(network) || mbedtls_socket.connect(host,port);
00090     if( ret != 0 ){
00091         IOT_DEBUG("Socket Open Failed - %d",ret);
00092         }
00093 
00094     FUNC_EXIT_RC(ret);
00095 }
00096 
00097 /*
00098  * Create a listening socket on bind_ip:port
00099  */
00100 int mbedtls_aws_bind( mbedtls_net_context *ctx, const char *bind_ip, const char *port, int proto )
00101 {
00102     FUNC_EXIT_RC(MBEDTLS_ERR_NET_BIND_FAILED);
00103 }
00104 
00105 /*
00106  * Accept a connection from a remote client
00107  */
00108 int mbedtls_aws_accept( mbedtls_net_context *bind_ctx,
00109                         mbedtls_net_context *client_ctx,
00110                         void *client_ip, size_t buf_size, size_t *ip_len )
00111 {
00112     FUNC_ENTRY;
00113     FUNC_EXIT_RC(MBEDTLS_ERR_NET_ACCEPT_FAILED );
00114 }
00115 
00116 /*
00117  * Set the socket blocking or non-blocking
00118  */
00119 int mbedtls_aws_set_block( mbedtls_net_context *ctx )
00120 {
00121         mbedtls_socket.set_blocking(true);
00122         return 0;
00123 }
00124 
00125 int mbedtls_aws_set_nonblock( mbedtls_net_context *ctx )
00126 {
00127     mbedtls_socket.set_blocking(false);
00128     return 0;
00129 }
00130 
00131 /*
00132  * Portable usleep helper
00133  */
00134 void mbedtls_aws_usleep( unsigned long usec )
00135 {
00136     FUNC_ENTRY;
00137     Timer t;
00138     t.start();
00139     while( t.read_us() < (int)usec )
00140         /* wait here */ ;
00141 }
00142 
00143 /*
00144  * Read at most 'len' characters
00145  */
00146 int mbedtls_aws_recv( void *ctx, unsigned char *buf, size_t len )
00147 {
00148     int ret;
00149     int fd = ((mbedtls_net_context *) ctx)->fd;
00150 
00151     FUNC_ENTRY;
00152     if( fd < 0 )
00153         FUNC_EXIT_RC(MBEDTLS_ERR_NET_INVALID_CONTEXT );
00154 
00155     ret = (int) mbedtls_socket.recv( buf, len );
00156 
00157     if( ret == NSAPI_ERROR_WOULD_BLOCK )
00158         ret = MBEDTLS_ERR_SSL_WANT_READ;
00159     FUNC_EXIT_RC(ret );
00160 }
00161 
00162 /*
00163  * Read at most 'len' characters, blocking for at most 'timeout' ms
00164  */
00165 int mbedtls_aws_recv_timeout( void *ctx, unsigned char *buf, size_t len, uint32_t timeout )
00166 {
00167     int   ret, ttime;
00168     Timer t;
00169     int   fd = ((mbedtls_net_context *) ctx)->fd;
00170     FUNC_ENTRY;
00171     if( fd < 0 )
00172         FUNC_EXIT_RC(MBEDTLS_ERR_NET_INVALID_CONTEXT );
00173 
00174     t.start();
00175     do {
00176         ret = mbedtls_socket.recv( buf, len );
00177         ttime = t.read_ms();
00178         if( ret == 0 && ttime < (int)timeout )
00179             ret = mbedtls_socket.recv( buf, len );
00180        }
00181     while( ttime < (int)timeout && ret == NSAPI_ERROR_WOULD_BLOCK );
00182 
00183     if( ret < 0 && ttime >= (int)timeout )
00184         ret = MBEDTLS_ERR_SSL_TIMEOUT;
00185     FUNC_EXIT_RC(ret);
00186 }
00187 
00188 /*
00189  * Write at most 'len' characters
00190  */
00191 int mbedtls_aws_send( void *ctx, const unsigned char *buf, size_t len )
00192 {
00193     int ret;
00194     int fd = ((mbedtls_net_context *) ctx)->fd;
00195 
00196     FUNC_ENTRY;
00197 
00198     if( fd < 0 )
00199         FUNC_EXIT_RC(MBEDTLS_ERR_NET_INVALID_CONTEXT );
00200 
00201     while( (ret = mbedtls_socket.send(buf, len)) == NSAPI_ERROR_WOULD_BLOCK )
00202         /* keep trying */;
00203     if( ret < 0 ) 
00204         ret = (ret == NSAPI_ERROR_WOULD_BLOCK )? MBEDTLS_ERR_SSL_WANT_WRITE : MBEDTLS_ERR_NET_SEND_FAILED;
00205     FUNC_EXIT_RC( ret );
00206 }
00207 
00208 /*
00209  * Gracefully close the connection
00210  */
00211 void mbedtls_aws_free( mbedtls_net_context *ctx )
00212 {
00213     FUNC_ENTRY;
00214     if( !network_connected || ctx->fd < 0 ) {
00215         FUNC_EXIT;
00216         }
00217 
00218     mbedtls_socket.close();
00219     network->disconnect();       //disconnect from the current network
00220     ctx->fd = -1;
00221     FUNC_EXIT;
00222 }
00223