int32_t SOCKETS_SetSockOpt()

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;
}