2 * Amazon FreeRTOS Secure Sockets V1.1.5
\r
3 * Copyright (C) 2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
\r
5 * Permission is hereby granted, free of charge, to any person obtaining a copy of
\r
6 * this software and associated documentation files (the "Software"), to deal in
\r
7 * the Software without restriction, including without limitation the rights to
\r
8 * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
\r
9 * the Software, and to permit persons to whom the Software is furnished to do so,
\r
10 * subject to the following conditions:
\r
12 * The above copyright notice and this permission notice shall be included in all
\r
13 * copies or substantial portions of the Software.
\r
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
\r
16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
\r
17 * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
\r
18 * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
\r
19 * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
\r
20 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
\r
22 * http://aws.amazon.com/freertos
\r
23 * http://www.FreeRTOS.org
\r
26 /* Define _SECURE_SOCKETS_WRAPPER_NOT_REDEFINE to prevent secure sockets functions
\r
27 * from redefining in iot_secure_sockets_wrapper_metrics.h */
\r
28 #define _SECURE_SOCKETS_WRAPPER_NOT_REDEFINE
\r
30 /* FreeRTOS includes. */
\r
31 #include "FreeRTOS.h"
\r
32 #include "FreeRTOSIPConfig.h"
\r
35 #include "FreeRTOS_IP.h"
\r
36 #include "FreeRTOS_Sockets.h"
\r
37 #include "iot_secure_sockets.h"
\r
40 #undef _SECURE_SOCKETS_WRAPPER_NOT_REDEFINE
\r
42 /* Internal context structure. */
\r
43 typedef struct SSOCKETContext
\r
46 char * pcDestination;
\r
47 BaseType_t xSendFlags;
\r
48 BaseType_t xRecvFlags;
\r
49 BaseType_t xConnectAttempted;
\r
50 } SSOCKETContext_t, * SSOCKETContextPtr_t;
\r
57 * @brief Network send callback.
\r
59 static BaseType_t prvNetworkSend( void * pvContext,
\r
60 const unsigned char * pucData,
\r
61 size_t xDataLength )
\r
63 SSOCKETContextPtr_t pxContext = ( SSOCKETContextPtr_t ) pvContext; /*lint !e9087 cast used for portability. */
\r
65 return FreeRTOS_send( pxContext->xSocket, pucData, xDataLength, pxContext->xSendFlags );
\r
67 /*-----------------------------------------------------------*/
\r
70 * @brief Network receive callback.
\r
72 static BaseType_t prvNetworkRecv( void * pvContext,
\r
73 unsigned char * pucReceiveBuffer,
\r
74 size_t xReceiveLength )
\r
76 SSOCKETContextPtr_t pxContext = ( SSOCKETContextPtr_t ) pvContext; /*lint !e9087 cast used for portability. */
\r
78 return FreeRTOS_recv( pxContext->xSocket, pucReceiveBuffer, xReceiveLength, pxContext->xRecvFlags );
\r
80 /*-----------------------------------------------------------*/
\r
83 * Interface routines.
\r
86 int32_t SOCKETS_Close( Socket_t xSocket )
\r
88 SSOCKETContextPtr_t pxContext = ( SSOCKETContextPtr_t ) xSocket; /*lint !e9087 cast used for portability. */
\r
91 if( ( xSocket != SOCKETS_INVALID_SOCKET ) && ( NULL != pxContext ) )
\r
93 /* Clean-up destination string. */
\r
94 if( NULL != pxContext->pcDestination )
\r
96 vPortFree( pxContext->pcDestination );
\r
99 /* Close the underlying socket handle. */
\r
100 ( void ) FreeRTOS_closesocket( pxContext->xSocket );
\r
102 /* Free the context. */
\r
103 vPortFree( pxContext );
\r
104 lReturn = SOCKETS_ERROR_NONE;
\r
108 lReturn = SOCKETS_EINVAL;
\r
113 /*-----------------------------------------------------------*/
\r
115 int32_t SOCKETS_Connect( Socket_t xSocket,
\r
116 SocketsSockaddr_t * pxAddress,
\r
117 Socklen_t xAddressLength )
\r
119 int32_t lStatus = SOCKETS_ERROR_NONE;
\r
120 SSOCKETContextPtr_t pxContext = ( SSOCKETContextPtr_t ) xSocket; /*lint !e9087 cast used for portability. */
\r
121 struct freertos_sockaddr xTempAddress = { 0 };
\r
123 if( ( pxContext != SOCKETS_INVALID_SOCKET ) && ( pxAddress != NULL ) )
\r
125 /* A connection was attempted. If this function fails, then the socket is invalid and the user
\r
126 * must call SOCKETS_Close(), on this socket, and SOCKETS_Socket() to get a new socket. */
\r
127 pxContext->xConnectAttempted = pdTRUE;
\r
129 /* Connect the wrapped socket. */
\r
130 xTempAddress.sin_addr = pxAddress->ulAddress;
\r
131 xTempAddress.sin_family = pxAddress->ucSocketDomain;
\r
132 xTempAddress.sin_len = ( uint8_t ) sizeof( xTempAddress );
\r
133 xTempAddress.sin_port = pxAddress->usPort;
\r
134 lStatus = FreeRTOS_connect( pxContext->xSocket, &xTempAddress, xAddressLength );
\r
138 lStatus = SOCKETS_SOCKET_ERROR;
\r
143 /*-----------------------------------------------------------*/
\r
145 uint32_t SOCKETS_GetHostByName( const char * pcHostName )
\r
147 return FreeRTOS_gethostbyname( pcHostName );
\r
149 /*-----------------------------------------------------------*/
\r
151 int32_t SOCKETS_Recv( Socket_t xSocket,
\r
153 size_t xBufferLength,
\r
156 int32_t lStatus = SOCKETS_SOCKET_ERROR;
\r
157 SSOCKETContextPtr_t pxContext = ( SSOCKETContextPtr_t ) xSocket; /*lint !e9087 cast used for portability. */
\r
159 if( ( xSocket != SOCKETS_INVALID_SOCKET ) &&
\r
160 ( pvBuffer != NULL ) )
\r
162 pxContext->xRecvFlags = ( BaseType_t ) ulFlags;
\r
164 /* Receive unencrypted. */
\r
165 lStatus = prvNetworkRecv( pxContext, pvBuffer, xBufferLength );
\r
169 lStatus = SOCKETS_EINVAL;
\r
174 /*-----------------------------------------------------------*/
\r
176 int32_t SOCKETS_Send( Socket_t xSocket,
\r
177 const void * pvBuffer,
\r
178 size_t xDataLength,
\r
181 int32_t lStatus = SOCKETS_SOCKET_ERROR;
\r
182 SSOCKETContextPtr_t pxContext = ( SSOCKETContextPtr_t ) xSocket; /*lint !e9087 cast used for portability. */
\r
184 if( ( xSocket != SOCKETS_INVALID_SOCKET ) &&
\r
185 ( pvBuffer != NULL ) )
\r
187 pxContext->xSendFlags = ( BaseType_t ) ulFlags;
\r
189 /* Send unencrypted. */
\r
190 lStatus = prvNetworkSend( pxContext, pvBuffer, xDataLength );
\r
194 lStatus = SOCKETS_EINVAL;
\r
199 /*-----------------------------------------------------------*/
\r
201 int32_t SOCKETS_SetSockOpt( Socket_t xSocket,
\r
203 int32_t lOptionName,
\r
204 const void * pvOptionValue,
\r
205 size_t xOptionLength )
\r
207 int32_t lStatus = SOCKETS_ERROR_NONE;
\r
208 TickType_t xTimeout;
\r
209 SSOCKETContextPtr_t pxContext = ( SSOCKETContextPtr_t ) xSocket; /*lint !e9087 cast used for portability. */
\r
211 if( ( xSocket != SOCKETS_INVALID_SOCKET ) && ( xSocket != NULL ) )
\r
213 switch( lOptionName )
\r
215 case SOCKETS_SO_NONBLOCK:
\r
218 /* Non-blocking connect is not supported. Socket may be set to nonblocking
\r
219 * only after a connection is made. */
\r
220 if( pdTRUE == pxContext->xConnectAttempted )
\r
222 lStatus = FreeRTOS_setsockopt( pxContext->xSocket,
\r
224 SOCKETS_SO_RCVTIMEO,
\r
226 sizeof( xTimeout ) );
\r
228 if( lStatus == SOCKETS_ERROR_NONE )
\r
230 lStatus = FreeRTOS_setsockopt( pxContext->xSocket,
\r
232 SOCKETS_SO_SNDTIMEO,
\r
234 sizeof( xTimeout ) );
\r
239 lStatus = SOCKETS_EISCONN;
\r
244 case SOCKETS_SO_RCVTIMEO:
\r
245 case SOCKETS_SO_SNDTIMEO:
\r
246 /* Comply with Berkeley standard - a 0 timeout is wait forever. */
\r
247 xTimeout = *( ( const TickType_t * ) pvOptionValue ); /*lint !e9087 pvOptionValue passed should be of TickType_t */
\r
249 if( xTimeout == 0U )
\r
251 xTimeout = portMAX_DELAY;
\r
254 lStatus = FreeRTOS_setsockopt( pxContext->xSocket,
\r
262 lStatus = FreeRTOS_setsockopt( pxContext->xSocket,
\r
272 lStatus = SOCKETS_EINVAL;
\r
277 /*-----------------------------------------------------------*/
\r
279 int32_t SOCKETS_Shutdown( Socket_t xSocket,
\r
283 SSOCKETContextPtr_t pxContext = ( SSOCKETContextPtr_t ) xSocket; /*lint !e9087 cast used for portability. */
\r
285 if( ( xSocket != SOCKETS_INVALID_SOCKET ) && ( xSocket != NULL ) )
\r
287 lReturn = FreeRTOS_shutdown( pxContext->xSocket, ( BaseType_t ) ulHow );
\r
291 lReturn = SOCKETS_EINVAL;
\r
296 /*-----------------------------------------------------------*/
\r
298 Socket_t SOCKETS_Socket( int32_t lDomain,
\r
300 int32_t lProtocol )
\r
302 SSOCKETContextPtr_t pxContext = NULL;
\r
305 /* Ensure that only supported values are supplied. */
\r
306 configASSERT( lDomain == SOCKETS_AF_INET );
\r
307 configASSERT( lType == SOCKETS_SOCK_STREAM );
\r
308 configASSERT( lProtocol == SOCKETS_IPPROTO_TCP );
\r
310 /* Create the wrapped socket. */
\r
311 xSocket = FreeRTOS_socket( lDomain, lType, lProtocol );
\r
313 if( xSocket != FREERTOS_INVALID_SOCKET )
\r
315 /* Allocate the internal context structure. */
\r
316 if( NULL == ( pxContext = pvPortMalloc( sizeof( SSOCKETContext_t ) ) ) )
\r
318 /* Need to close socket. */
\r
319 ( void ) FreeRTOS_closesocket( xSocket );
\r
320 pxContext = SOCKETS_INVALID_SOCKET;
\r
324 memset( pxContext, 0, sizeof( SSOCKETContext_t ) );
\r
325 pxContext->xSocket = xSocket;
\r
330 pxContext = SOCKETS_INVALID_SOCKET;
\r
335 /*-----------------------------------------------------------*/
\r
337 BaseType_t SOCKETS_Init( void )
\r
339 /* Empty initialization for this port. */
\r
342 /*-----------------------------------------------------------*/
\r