in amazon-freertos/lib/secure_sockets/portable/ti/cc3220_launchpad/aws_secure_sockets.c [1018:1242]
int32_t SOCKETS_SetSockOpt( Socket_t xSocket,
int32_t lLevel,
int32_t lOptionName,
const void * pvOptionValue,
size_t xOptionLength )
{
SSocketContextPtr_t pxSocketContext;
SlSockNonblocking_t xSockNonblocking;
struct SlTimeval_t xTimeVal;
_i16 sTIRetCode;
int32_t lRetCode = SOCKETS_SOCKET_ERROR;
uint32_t ulTimeoutInMilliseconds;
uint32_t ulSocketNumber = ( uint32_t ) xSocket;
/* Remove compiler warnings about unused parameters. */
( void ) lLevel;
/* Ensure that the socket is valid. */
if( prvIsValidSocket( ulSocketNumber ) == pdTRUE )
{
/* Shortcut for easy access. */
pxSocketContext = &( xSockets[ ulSocketNumber ] );
switch( lOptionName )
{
case SOCKETS_SO_SERVER_NAME_INDICATION:
if( ( pxSocketContext->ulFlags & securesocketsSOCKET_IS_CONNECTED ) == 0 )
{
/* Set Server Name Indication (SNI) on the TI socket. */
sTIRetCode = sl_SetSockOpt( pxSocketContext->sSocketDescriptor,
SL_SOL_SOCKET,
SL_SO_SECURE_DOMAIN_NAME_VERIFICATION,
pvOptionValue,
( SlSocklen_t ) xOptionLength );
/* If the above sl_SetSockOpt succeeded, return success to the user. */
if( sTIRetCode >= 0 )
{
lRetCode = SOCKETS_ERROR_NONE;
}
else
{
/* See \lib\third_party\mcu_vendor\ti\SimpleLink_CC32xx\v2_10_00_04\source\ti\drivers\net\wifi\errors.h */
SOCKETS_PRINT( ( "ERROR: %d SockOpt SNI failed.\r\n", sTIRetCode ) );
}
}
else
{
lRetCode = SOCKETS_SOCKET_ERROR;
SOCKETS_PRINT( ( "ERROR: SNI must be set before connection is established.\r\n" ) );
}
break;
case SOCKETS_SO_TRUSTED_SERVER_CERTIFICATE:
if( ( pxSocketContext->ulFlags & securesocketsSOCKET_IS_CONNECTED ) == 0 )
{
/* Write the certificate to the file system. */
lRetCode = prvWriteCertificate( socketsconfigSECURE_FILE_NAME_CUSTOMROOTCA,
pvOptionValue,
xOptionLength - 1U );
/* If the certificate was successfully written to the
* file system, use it for the socket. */
if( lRetCode == SOCKETS_ERROR_NONE )
{
sTIRetCode = sl_SetSockOpt( pxSocketContext->sSocketDescriptor,
SL_SOL_SOCKET,
SL_SO_SECURE_FILES_CA_FILE_NAME,
socketsconfigSECURE_FILE_NAME_CUSTOMROOTCA,
( SlSocklen_t ) strlen( socketsconfigSECURE_FILE_NAME_CUSTOMROOTCA ) );
if( sTIRetCode >= 0 )
{
/* Mark the socket as having a custom trusted root CA. */
pxSocketContext->ulFlags |= securesocketsSOCKET_TRUSTED_SERVER_CERT_FLAG;
}
else
{
/* See \lib\third_party\mcu_vendor\ti\SimpleLink_CC32xx\v2_10_00_04\source\ti\drivers\net\wifi\errors.h */
SOCKETS_PRINT( ( "ERROR: %d Failed to set the custom root certificate.\r\n", sTIRetCode ) );
lRetCode = SOCKETS_SOCKET_ERROR;
}
}
}
else
{
lRetCode = SOCKETS_SOCKET_ERROR;
SOCKETS_PRINT( ( "ERROR: Secure trusted cert must be set before connection is established.\r\n" ) );
}
break;
case SOCKETS_SO_REQUIRE_TLS:
if( ( pxSocketContext->ulFlags & securesocketsSOCKET_IS_CONNECTED ) == 0 )
{
/* Create the semaphore required for synchronizing TLS handshake
* results returned in the SimpleLink socket event handler callback. */
pxSocketContext->xSSLSyncSemaphore = xSemaphoreCreateBinary();
if( pxSocketContext->xSSLSyncSemaphore != NULL )
{
/* Store that we need to use TLS on this socket. */
pxSocketContext->ulFlags |= securesocketsSOCKET_SECURE_FLAG;
/* Success. */
lRetCode = SOCKETS_ERROR_NONE;
}
else
{
/* Since we failed to create the TLS handshake synchronization
* semaphore, there is no point of turning the TLS flag on,
* as we will not be able to setup TLS connection. Let the user
* know that we failed to enable TLS. */
lRetCode = SOCKETS_SOCKET_ERROR;
}
}
else
{
lRetCode = SOCKETS_SOCKET_ERROR;
SOCKETS_PRINT( ( "ERROR: Require TLS must be set before connection is established.\r\n" ) );
}
break;
case SOCKETS_SO_RCVTIMEO:
/* Ensure that uint32_t was passed as value. */
configASSERT( ( xOptionLength == sizeof( uint32_t ) ) );
/* Read the passed value. */
ulTimeoutInMilliseconds = *( ( const uint32_t * ) pvOptionValue ); /*lint !e9079 !e9087 uint32_t type is expected. This function will hard-fault if the wrong type is passed. */
/* Convert the milliseconds to the struct SlTimeval_t which
* contains seconds and microseconds. */
xTimeVal.tv_sec = ( SlTime_t ) ( ulTimeoutInMilliseconds / 1000 );
ulTimeoutInMilliseconds = ulTimeoutInMilliseconds - ( uint32_t ) xTimeVal.tv_sec * 1000U;
xTimeVal.tv_usec = ( SlTime_t ) ( ulTimeoutInMilliseconds * 1000 );
/* Set receive timeout on the TI socket. */
sTIRetCode = sl_SetSockOpt( pxSocketContext->sSocketDescriptor,
SL_SOL_SOCKET,
SL_SO_RCVTIMEO,
&( xTimeVal ),
( SlSocklen_t ) sizeof( xTimeVal ) );
/* If the above sl_SetSockOpt succeeded, return success to the user. */
if( sTIRetCode >= 0 )
{
lRetCode = SOCKETS_ERROR_NONE;
}
else
{
/* See \lib\third_party\mcu_vendor\ti\SimpleLink_CC32xx\v2_10_00_04\source\ti\drivers\net\wifi\errors.h */
SOCKETS_PRINT( ( "ERROR: %d SockOpt RCVTIMEO failed.\r\n", sTIRetCode ) );
}
break;
case SOCKETS_SO_SNDTIMEO:
/* Ensure that uint32_t was passed as value. */
configASSERT( xOptionLength == sizeof( uint32_t ) );
/* Simple Link socket layer does not provide socket send
* timeout. So currently we just store the user supplied
* timeout in the socket context and do not use it. In future,
* we may use it to simulate send timeout in secure sockets
* layer. */
pxSocketContext->xSendTimeoutTicks = pdMS_TO_TICKS( *( ( const uint32_t * ) pvOptionValue ) ); /*lint !e9079 !e9087 uint32_t type is expected. This function will hard-fault if the wrong type is passed. */
/* Success. */
lRetCode = SOCKETS_ERROR_NONE;
break;
case SOCKETS_SO_NONBLOCK:
if( ( pxSocketContext->ulFlags & securesocketsSOCKET_IS_CONNECTED ) != 0 )
{
xSockNonblocking.NonBlockingEnabled = 1;
/* Mark the TI socket as non-blocking. */
sTIRetCode = sl_SetSockOpt( pxSocketContext->sSocketDescriptor,
SL_SOL_SOCKET,
SL_SO_NONBLOCKING,
&( xSockNonblocking ),
( SlSocklen_t ) sizeof( xSockNonblocking ) );
/* If the above sl_SetSockOpt succeeded, return success to the user. */
if( sTIRetCode >= 0 )
{
lRetCode = SOCKETS_ERROR_NONE;
}
else
{
/* See \lib\third_party\mcu_vendor\ti\SimpleLink_CC32xx\v2_10_00_04\source\ti\drivers\net\wifi\errors.h */
SOCKETS_PRINT( ( "ERROR: %d SockOpt NONBLOCK failed.\r\n", sTIRetCode ) );
}
}
else
{
lRetCode = SOCKETS_SOCKET_ERROR;
SOCKETS_PRINT( ( "ERROR: NONBLOCKING socket option must be called after connect. Nonblocking connect is not supported.\r\n" ) );
}
break;
default:
/* Invalid option. */
lRetCode = SOCKETS_EINVAL;
break;
}
}
else
{
SOCKETS_PRINT( ( "ERROR: SOCKETS_Connect - Invalid Socket number.\r\n" ) );
lRetCode = SOCKETS_EINVAL;
}
return lRetCode;
}