in amazon-freertos/lib/secure_sockets/portable/infineon/xmc4800_iotkit/aws_secure_sockets.c [663:836]
int32_t SOCKETS_SetSockOpt( Socket_t xSocket,
int32_t lLevel,
int32_t lOptionName,
const void * pvOptionValue,
size_t xOptionLength )
{
int32_t lRetCode = SOCKETS_ERROR_NONE;
uint32_t ulSocketNumber = ( uint32_t ) xSocket;
TickType_t xTimeout;
/* Remove compiler warnings about unused parameters. */
(void)lLevel;
/* Ensure that a valid socket was passed. */
if (prvIsValidSocket(ulSocketNumber) == pdTRUE)
{
SSocketContextPtr_t pxContext = &xSockets[ulSocketNumber];
switch( lOptionName )
{
case SOCKETS_SO_SERVER_NAME_INDICATION:
if ((pxContext->ulFlags & securesocketsSOCKET_IS_CONNECTED) == 0)
{
/* Non-NULL destination string indicates that SNI extension should
* be used during TLS negotiation. */
pxContext->pcDestination = ( char * ) pvPortMalloc( 1U + xOptionLength );
if (pxContext->pcDestination == NULL)
{
lRetCode = SOCKETS_ENOMEM;
}
else
{
if (pvOptionValue != NULL)
{
memcpy(pxContext->pcDestination, pvOptionValue, xOptionLength );
pxContext->pcDestination[ xOptionLength ] = '\0';
}
else
{
lRetCode = SOCKETS_EINVAL;
}
}
}
else
{
lRetCode = SOCKETS_EISCONN;
}
break;
case SOCKETS_SO_TRUSTED_SERVER_CERTIFICATE:
if ((pxContext->ulFlags & securesocketsSOCKET_IS_CONNECTED) == 0)
{
/* Non-NULL server certificate field indicates that the default trust
* list should not be used. */
pxContext->pcServerCertificate = ( char * ) pvPortMalloc( xOptionLength );
if (pxContext->pcServerCertificate == NULL)
{
lRetCode = SOCKETS_ENOMEM;
}
else
{
if (pvOptionValue != NULL)
{
memcpy( pxContext->pcServerCertificate, pvOptionValue, xOptionLength );
pxContext->ulServerCertificateLength = xOptionLength;
}
else
{
lRetCode = SOCKETS_EINVAL;
}
}
}
else
{
lRetCode = SOCKETS_EISCONN;
}
break;
case SOCKETS_SO_REQUIRE_TLS:
if ((pxContext->ulFlags & securesocketsSOCKET_IS_CONNECTED) == 0)
{
pxContext->ulFlags |= securesocketsSOCKET_SECURE_FLAG;
}
else
{
/* Do not set the ALPN option if the socket is already connected. */
lRetCode = SOCKETS_EISCONN;
}
break;
case SOCKETS_SO_ALPN_PROTOCOLS:
if ((pxContext->ulFlags & securesocketsSOCKET_IS_CONNECTED) == 0)
{
/* Allocate a sufficiently long array of pointers. */
pxContext->ulAlpnProtocolsCount = 1 + xOptionLength;
if (NULL == (pxContext->ppcAlpnProtocols = (char **)pvPortMalloc(pxContext->ulAlpnProtocolsCount * sizeof(char *))))
{
lRetCode = SOCKETS_ENOMEM;
}
else
{
pxContext->ppcAlpnProtocols[pxContext->ulAlpnProtocolsCount - 1 ] = NULL;
}
/* Copy each protocol string. */
for (uint32_t ulProtocol = 0; (ulProtocol < pxContext->ulAlpnProtocolsCount - 1) && (lRetCode == pdFREERTOS_ERRNO_NONE); ulProtocol++)
{
char ** ppcAlpnIn = ( char ** ) pvOptionValue;
size_t xLength = strlen(ppcAlpnIn[ ulProtocol ]);
if ((pxContext->ppcAlpnProtocols[ ulProtocol ] = (char *)pvPortMalloc(1 + xLength)) == NULL)
{
lRetCode = SOCKETS_ENOMEM;
}
else
{
memcpy( pxContext->ppcAlpnProtocols[ ulProtocol ], ppcAlpnIn[ ulProtocol ], xLength );
pxContext->ppcAlpnProtocols[ ulProtocol ][ xLength ] = '\0';
}
}
}
else
{
/* Do not set the ALPN option if the socket is already connected. */
lRetCode = SOCKETS_EISCONN;
}
break;
case SOCKETS_SO_SNDTIMEO:
break;
case SOCKETS_SO_RCVTIMEO:
if (pvOptionValue != NULL)
{
xTimeout = *( ( const TickType_t * ) pvOptionValue ); /*lint !e9087 pvOptionValue passed should be of TickType_t. */
esp_netconn_set_receive_timeout(pxContext->xSocket, xTimeout);
}
else
{
lRetCode = SOCKETS_EINVAL;
}
break;
case SOCKETS_SO_NONBLOCK:
if ((pxContext->ulFlags & securesocketsSOCKET_IS_CONNECTED ) != 0)
{
/* Set the timeouts to the smallest value possible.
* This isn't true nonblocking, but as close as we can get. */
esp_netconn_set_receive_timeout(pxContext->xSocket, 1);
}
else
{
lRetCode = SOCKETS_EISCONN;
}
break;
default:
lRetCode = SOCKETS_EINVAL;
}
}
else
{
lRetCode = SOCKETS_EINVAL;
}
return lRetCode;
}