Secure Sockets Library provides APIs to create software that can send and/or receive data over the network using sockets. This library supports both secure and non-secure sockets, and abstracts the complexity involved in directly using network stack and security stack APIs. This library supports both IPv4 and IPv6 addressing modes for UDP and TCP sockets.
Features and Functionality
Features supported:
- Supports Wi-Fi and Ethernet connections
- Supports non-secure TCP and UDP sockets
- Secure TCP (TLS) socket communication using Mbed TLS/NetXSecure library
- Supports both IPv4 and IPv6 addressing. Only link-local IPv6 addressing is supported
- Supports UDP multicast and broadcast for both IPv4 and IPv6.
- Thread-safe APIs
- Provides APIs for both Client and Server mode operations
- Supports both Synchronous and Asynchronous APIs for receiving data on socket
- Asynchronous Server APIs for accepting client connections
- Provides a socket-option API to configure send/receive timeout, callback for asynchronous mode, TCP keepalive parameters, certificate/key, and TLS extensions
- Integrated with PSA Lib through PKCS interface to support secure client TCP (TLS) connection using the device certificate and device keys provisioned in the secure element
Quick Start
- To use secure-sockets library with Wi-Fi kits, on FreeRTOS, lwIP, and Mbed TLS combination, the application should pull wifi-core-freertos-lwip-mbedtls library which will internally pull secure-sockets, wifi-connection-manager, FreeRTOS, lwIP, Mbed TLS and other dependent modules. To pull wifi-core-freertos-lwip-mbedtls create the following .mtb file in deps folder. wifi-core-freertos-lwip-mbedtls.mtb
- To use secure-sockets library with CYW955913EVK-01 kits on Threadx, NetXDuo, and NetXSecure combination, the application should pull wifi-core-threadx-cat5 library which will internally pull secure-sockets and other dependent modules. To pull wifi-core-threadx-cat5 create the following .mtb file in deps folder. wifi-core-threadx-cat5.mtb
- To use secure-sockets library with Ethernet kits, on FreeRTOS, lwIP, and Mbed TLS combination, the application should pull ethernet-core-freertos-lwip-mbedtls library which will internally pull secure-sockets, ethernet-connection-manager, FreeRTOS, lwIP, Mbed TLS and other dependent modules. To pull ethernet-core-freertos-lwip-mbedtls create the following .mtb file in deps folder. ethernet-core-freertos-lwip-mbedtls.mtb
- A set of pre-defined configuration files for FreeRTOS, lwIP, and Mbed TLS combination is bundled in wifi-core-freertos-lwip-mbedtls library for Wi-Fi kits and in ethernet-core-freertos-lwip-mbedtls library for Ethernet kits. The developer is expected to review the configuration and make adjustments. Also, a set of COMPONENTS must be defined in the code example project's Makefile for this library.
- See the "Quick Start" section in README.md for Wi-Fi kits.
- See the "Quick Start" section in README.md for Ethernet kits.
- The secure-sockets library disables all the debug log messages by default. To enable log messages, the application must perform the following:
- Add the
ENABLE_SECURE_SOCKETS_LOGS
macro to the DEFINES in the code example's Makefile. The Makefile entry would look like as follows: DEFINES+=ENABLE_SECURE_SOCKETS_LOGS
- Call the
cy_log_init()
function provided by the cy-log module. cy-log is part of the connectivity-utilities library. See *connectivity-utilities library API documentation. WPS is disabled by default. WPS uses Mbed TLS security stack. Enable the following components for WPS.
Supported Platforms
This library and its features are supported on the following Infineon MCUs:
Send and receive timeout values
- The Secure Sockets Library configures the default send and receive timeout values to 10 seconds for a newly created socket. These can be changed using the
cy_socket_setsockopt
API function. To change the send timeout, use the CY_SOCKET_SO_SNDTIMEO
socket option; similarly, for receive timeout, use the CY_SOCKET_SO_RCVTIMEO
socket option. Adjust the default timeout values based on the network speed or use case.
TCP/IP and security stacks
- The secure sockets library has been designed to support different flavors of the TCP/IP stack or security stack. Currently, secure-sockets supports two combinations of TCP/IP stack and security stack.
- lwIP + Mbed TLS combination
- NetXDuo + NetXSecure combination
- Any application that uses the secure sockets library with lwIP + Mbed TLS combination, must ensure that the following COMPONENTS are defined in the code example project's Makefile. To do so, add LWIP and MBEDTLS components to the Makefile. The Makefile entry would look like as follows:
- Currently NetXDuo + NetXSecure combination is supported only on CYW955913EVK-01. This does not require addition of any COMPONENTS to the code example project's Makefile.
- Applications using the Secure Sockets Library must include only the cy_secure_sockets.h file for non-secure connections. For secure connections, the application must include both cy_secure_sockets.h and cy_tls.h header files.
Stack size
- The default stack size of the secure sockets library is 6 KB (6*1024). To customize the stack size add the
SECURE_SOCKETS_THREAD_STACKSIZE
macro to the DEFINES
in the code example's Makefile with the required stack size. The Makefile entry would look like as follows: DEFINES+=SECURE_SOCKETS_THREAD_STACKSIZE=8*1024
Log messages
- The Secure Sockets Library disables all the debug log messages by default. Do the following to enable log messages:
- Add
ENABLE_SECURE_SOCKETS_LOGS
macro to the DEFINES
in the code example's Makefile. The Makefile entry would look like as follows: DEFINES+=ENABLE_SECURE_SOCKETS_LOGS
- Call the
cy_log_init()
function provided by the cy-log module. cy-log is part of the connectivity-utilities library. See connectivity-utilities library API documentation for cy-log details.
Validity period verification
PKCS/Non-PKCS mode
- Secure sockets library can be built using PKCS and Non-PKCS mode on secure platform such as CY8CKIT-064S0S2-4343W. When Secure sockets library is built with PKCS flow, the certificates and keys can be provisioned in the secure element of the platform, and the provisioned certificates and keys will be read/used by secure sockets library while establishing the TLS connection with the peer. On the other hand, in non-PKCS mode, the certificates/keys will be passed from the application stored in flash/RAM.
Non-PKCS mode
- Provision the kit. See Device provisioning steps.
- Add
CY_TFM_PSA_SUPPORTED
and TFM_MULTI_CORE_NS_OS
to the DEFINES
in the application's Makefile. The Makefile entry would look like as follows: DEFINES+=CY_TFM_PSA_SUPPORTED TFM_MULTI_CORE_NS_OS
PKCS mode
Secure Kits
Secure kits will have inbuilt secure element to store the keys and certificates which can be provisioned into the device.
- Provision the kit. See Device provisioning steps.
- Provision device certificate/RootCA certificate. Add/modify the respective policy *.json* file with the device and RootCA certificate path to be provisioned to the secured element as follows, and then re-provision the kit:
"provisioning:"
{
"chain_of_trust": ["../certificates/device_cert.pem", "../certificates/rootCA.pem"]
},
Dependencies
The secure sockets library depends on the other libraries for PKCS support. Ensure that the following libraries are pulled in by creating the following .mtb files:
Pull required libraries and enable PKCS mode
- Execute the
make getlibs
command to pull the required libraries created as .mtb.
- Add the
CY_TFM_PSA_SUPPORTED
, TFM_MULTI_CORE_NS_OS
and CY_SECURE_SOCKETS_PKCS_SUPPORT
macros to the DEFINES
in the code example's Makefile. The Makefile entry would look like as follows: DEFINES+=CY_TFM_PSA_SUPPORTED TFM_MULTI_CORE_NS_OS CY_SECURE_SOCKETS_PKCS_SUPPORT
Trusted firmware library include path
- To compile the FreeRTOS PKCS PSA integration library, add the trusted firmware library include path before the MBEDTLS library include path. Add the following lines to the Makefile.
INCLUDES=$(SEARCH_trusted-firmware-m)/COMPONENT_TFM_NS_INTERFACE/include
INCLUDES+=./libs/trusted-firmware-m/COMPONENT_TFM_NS_INTERFACE/include
Non-Secure Kits
The non-secure kits can also support the key and certificate storage in separate hardware like optiga. Optiga PKCS11 support is enabled in secure sockets.
Dependencies
The secure sockets library depends on the other libraries for PKCS support. Ensure that the following libraries are pulled in by creating the following .mtb files:
Pull required libraries and enable PKCS mode
- Execute the
make getlibs
command to pull the required libraries created as .mtb.
- Add
OPTIGA
in COMPONENTS
- Add the Optiga PAL interface as per the platform. Use
PSOC6_FREERTOS
for PSOC6 with FREERTOS. The Makefile entry would look like as follows: COMPONENT+=PSOC6_FREERTOS
- Add
OPTIGAFLAGS
with the configuration file for Optiga. A pre-defined configuration file optiga_lib_config_mtb.h is bundled with the secure sockets library. To change the default configuration for PKCS11, copy the optiga_config.h file from the secure sockets library to the top-level application directory, and then modify it. OPTIGAFLAGS=OPTIGA_LIB_EXTERNAL='"optiga_config.h"'
- Add the
CY_SECURE_SOCKETS_PKCS_SUPPORT
and OPTIGAFLAGS
macros to the DEFINES
in the code example's Makefile. The Makefile entry would look like as follows: DEFINES+= $(OPTIGAFLAGS) CY_SECURE_SOCKETS_PKCS_SUPPORT
Configuration for PKCS11
Pre-defined configuration file core_pkcs11_config.h is bundled with secure sockets library. If you need to change default configuration for PKCS11, copy core_pkcs11_config.h file from secure sockets library to top-level code example directory and then modify it.
Secure Kits
FreeRTOS PSA PKCS11 library supports only SHA-256 hashing algorithm. So the application should chose the cipher suite list compatible for SHA-256. To chose the cipher suite list(compatible for SHA-256), application need to copy mbedtls_user_config.h file from libs/wifi-core-freertos-lwip-mbedtls/configs to root folder and add required cipher suites to the MBEDTLS_SSL_CIPHERSUITES
macro.
Non-Secure Kits
- The secure sockets will use 3 OID information from the optiga chip for TLS connection. Secure sockets uses the below macros (default OID value in brackets) correspoding to those OIDs to fetch information. To change the default configuration, add these defines in the makefile with new values.
- Device private key : LABEL_DEVICE_PRIVATE_KEY_FOR_TLS (0xE0F0)
- Device certificate : LABEL_DEVICE_CERTIFICATE_FOR_TLS (0xE0E0)
- Root certificate : LABEL_ROOT_CERTIFICATE (0xE0E8)
Note : Optiga-trust-m has a limitation on the maximum size of Public Key Certificate/Device Certificate. Using a certificate of a size greater than 1728 bytes may result in erroneous outputs.
To use secure-sockets library for FreeRTOS, lwIP, and Mbed TLS, pull wifi-core-freertos-lwip-mbedtls library which will internally pull secure-sockets, wifi-connection-manager, FreeRTOS, lwIP, mbed TLS and other dependent modules.
Code Snippets
Code Snippet 1: Create TCP Socket
This code snippet demonstrates how to initialize and create a TCP socket using an IPv4 address domain.
void snippet_create_socket()
{
cy_rslt_t result;
(void)(result);
}
cy_rslt_t cy_socket_create(int domain, int type, int protocol, cy_socket_t *handle)
Creates a new socket.
cy_rslt_t cy_socket_init(void)
Does general allocation and initialization of resources needed for the library.
#define CY_SOCKET_IPPROTO_TCP
Protocol option for cy_socket_create() - TCP.
Definition: cy_secure_sockets_constants.h:59
#define CY_SOCKET_TYPE_STREAM
Type parameter for cy_socket_create() - Byte-stream.
Definition: cy_secure_sockets_constants.h:54
#define CY_SOCKET_DOMAIN_AF_INET
Domain option for cy_socket_create() - IPv4 internet protocols.
Definition: cy_secure_sockets_constants.h:47
void * cy_socket_t
Socket handle.
Definition: cy_secure_sockets.h:124
Code Snippet 2: Create Secure TCP Socket
This code snippet demonstrates how to initialize and create a TCP socket using an IPv4 address domain, and set the TLS credentials to be used for securing the socket communication.
void snippet_create_secure_socket()
{
cy_rslt_t result;
(void)(result);
void *tls_identity;
static const char tls_cert[] = "-----REPLACE WITH TLS CERTIFICATE FILE-----\n";
static const char private_key[] = "-----REPLACE WITH PRIVATE KEY-----\n";
const uint32_t cert_len = strlen( tls_cert );
const uint32_t pkey_len = strlen( private_key );
}
cy_rslt_t cy_tls_create_identity(const char *certificate_data, const uint32_t certificate_len, const char *private_key, uint32_t private_key_len, void **tls_identity)
Creates an identity structure from the supplied certificate and private key.
cy_socket_tls_auth_mode_t
Options for socket option CY_SOCKET_SO_TLS_AUTH_MODE.
Definition: cy_secure_sockets.h:94
@ CY_SOCKET_TLS_VERIFY_REQUIRED
Peer must present a valid certificate; handshake is aborted if verification failed (default authentic...
Definition: cy_secure_sockets.h:97
cy_rslt_t cy_socket_setsockopt(cy_socket_t handle, int level, int optname, const void *optval, uint32_t optlen)
Sets a particular socket option.
#define CY_SOCKET_IPPROTO_TLS
Protocol option for cy_socket_create() - TLS.
Definition: cy_secure_sockets_constants.h:61
#define CY_SOCKET_SOL_TLS
Level option for cy_socket_setsockopt() - TLS protocol-level option.
Definition: cy_secure_sockets_constants.h:68
#define CY_SOCKET_SO_TLS_AUTH_MODE
Set the TLS authenticate mode.
Definition: cy_secure_sockets_constants.h:271
#define CY_SOCKET_SO_TLS_IDENTITY
Set the TLS identity.
Definition: cy_secure_sockets_constants.h:242
Code Snippet 3: TCP Client Connect
This code snippet demonstrates how to create a TCP client using an IPv4 address domain, and connect to a TCP server. After connection is established with the TCP server, the client sends a message to the TCP server and waits for a message from the server.
#define MAKE_IPV4_ADDRESS(a, b, c, d) ((((uint32_t) d) << 24) | \
(((uint32_t) c) << 16) | \
(((uint32_t) b) << 8) |\
((uint32_t) a))
#define TCP_SERVER_IP_ADDRESS MAKE_IPV4_ADDRESS(192, 168, 18, 9)
#define TCP_SERVER_PORT (50007)
#define MAX_TCP_RECV_BUFFER_SIZE (20)
#define RTOS_TASK_MILLISECONDS_TO_WAIT (1000)
#define SOCKET_DISCONNECT_TIMEOUT (0)
bool received_msg_from_server;
cy_rslt_t tcp_client_recv_handler(
cy_socket_t client_handle,
void *arg)
{
cy_rslt_t result ;
uint32_t bytes_received = 0;
char rx_buffer[MAX_TCP_RECV_BUFFER_SIZE];
result =
cy_socket_recv(client_handle, rx_buffer, MAX_TCP_RECV_BUFFER_SIZE,
received_msg_from_server = true;
return result;
}
void snippet_tcp_client()
{
cy_rslt_t result;
(void)(result);
uint32_t bytes_sent = 0;
.port = TCP_SERVER_PORT
};
char tx_buffer[] = "Message to TCP server";
.arg = NULL
};
for(;;)
{
if(received_msg_from_server)
{
break;
}
cy_rtos_delay_milliseconds(RTOS_TASK_MILLISECONDS_TO_WAIT);
}
}
@ CY_SOCKET_IP_VER_V4
IPv4 protocol.
Definition: cy_secure_sockets.h:86
cy_rslt_t cy_socket_connect(cy_socket_t handle, cy_socket_sockaddr_t *address, uint32_t address_length)
Connects a TCP/TLS socket to the specified server IP address and port.
cy_rslt_t cy_socket_recv(cy_socket_t handle, void *buffer, uint32_t length, int flags, uint32_t *bytes_received)
Receives the data from a connected TCP/TLS socket.
cy_rslt_t cy_socket_send(cy_socket_t handle, const void *buffer, uint32_t length, int flags, uint32_t *bytes_sent)
Sends data over a connected TCP/TLS socket.
#define CY_SOCKET_FLAGS_NONE
cy_socket_send() input flags - No flag.
Definition: cy_secure_sockets_constants.h:450
#define CY_SOCKET_SO_RECEIVE_CALLBACK
Set the callback to be called when the socket has received data.
Definition: cy_secure_sockets_constants.h:180
#define CY_SOCKET_SOL_SOCKET
Level option for cy_socket_setsockopt() - Socket-level option.
Definition: cy_secure_sockets_constants.h:66
uint32_t v4
IPv4 address in network byte order.
Definition: cy_secure_sockets.h:148
union cy_socket_ip_address_t::@0 ip
IP address bytes.
Option value type for CY_SOCKET_SO_CONNECT_REQUEST_CALLBACK, CY_SOCKET_SO_RECEIVE_CALLBACK,...
Definition: cy_secure_sockets.h:167
cy_socket_callback_t callback
Pointer to a caller-defined callback function.
Definition: cy_secure_sockets.h:168
Socket Address.
Definition: cy_secure_sockets.h:157
cy_socket_ip_address_t ip_address
IP Address.
Definition: cy_secure_sockets.h:159
Code Snippet 4: TCP Server - Listening for client connection
This code snippet demonstrates how to create a TCP server using an IPv4 address domain and accept a TCP client connection. The server implementation in this snippet waits for a client connection and a message from the connected client. Upon receiving a message from the client, it sends a response message back to the client.
#define MAKE_IPV4_ADDRESS(a, b, c, d) ((((uint32_t) d) << 24) | \
(((uint32_t) c) << 16) | \
(((uint32_t) b) << 8) |\
((uint32_t) a))
#define TCP_SERVER_IP_ADDRESS MAKE_IPV4_ADDRESS(192, 168, 18, 9)
#define TCP_SERVER_PORT (50007)
#define TCP_SERVER_MAX_PENDING_CONNECTIONS (3)
#define MAX_TCP_RECV_BUFFER_SIZE (20)
#define RTOS_TASK_MILLISECONDS_TO_WAIT (1000)
#define SOCKET_DISCONNECT_TIMEOUT (0)
bool send_msg_to_client;
cy_rslt_t tcp_connection_handler(
cy_socket_t socket_handle,
void *arg)
{
cy_rslt_t result;
uint32_t client_addr_len;
&client_handle);
return result;
}
cy_rslt_t tcp_server_recv_handler(
cy_socket_t socket_handle,
void *arg)
{
cy_rslt_t result ;
uint32_t bytes_received = 0;
char rx_buffer[MAX_TCP_RECV_BUFFER_SIZE];
result =
cy_socket_recv(socket_handle, rx_buffer, MAX_TCP_RECV_BUFFER_SIZE,
send_msg_to_client = true;
return result;
}
void snippet_tcp_server()
{
cy_rslt_t result;
(void)(result);
uint32_t bytes_sent = 0;
.port = TCP_SERVER_PORT
};
char tx_buffer[] = "Message to TCP client";
.arg = NULL
};
.arg = NULL
};
result =
cy_socket_bind(server_handle, &tcp_server_addr,
sizeof(tcp_server_addr));
for (;;)
{
if(send_msg_to_client)
{
send_msg_to_client = false;
}
cy_rtos_delay_milliseconds(RTOS_TASK_MILLISECONDS_TO_WAIT);
}
}
cy_rslt_t cy_socket_listen(cy_socket_t handle, int backlog)
Listens for TCP/TLS socket connections and limits the queue of incoming connections.
cy_rslt_t cy_socket_accept(cy_socket_t handle, cy_socket_sockaddr_t *address, uint32_t *address_length, cy_socket_t *socket)
Accepts a new TCP/TLS connection on a socket.
cy_rslt_t cy_socket_bind(cy_socket_t handle, cy_socket_sockaddr_t *address, uint32_t address_length)
Binds the socket to the given socket address.
#define CY_SOCKET_SO_CONNECT_REQUEST_CALLBACK
Set the callback to be called upon an incoming client connection request.
Definition: cy_secure_sockets_constants.h:163
Code Snippet 5: TCP IPv6 Client Connect
This code snippet demonstrates how to create a TCP client using an IPv6 address domain and connect to a TCP server. After connection is established with the TCP server, the client sends a message to the TCP server and waits for a message from the server.
#define HTONS(x) ( ( ( (x) & 0x0000FF00) >> 8 ) | ((x) & 0x000000FF) << 8 )
#define MAKE_IPV6_ADDRESS(a, b, c, d, e, f, g, h) { \
( (uint32_t) (HTONS(a)) | ( (uint32_t) (HTONS(b)) << 16 ) ), \
( (uint32_t) (HTONS(c)) | ( (uint32_t) (HTONS(d)) << 16 ) ), \
( (uint32_t) (HTONS(e)) | ( (uint32_t) (HTONS(f)) << 16 ) ), \
( (uint32_t) (HTONS(g)) | ( (uint32_t) (HTONS(h)) << 16 ) ), \
}
#define TCP_SERVER_IPV6_ADDRESS MAKE_IPV6_ADDRESS( 0xFE80, 0, 0, 0, 0x29D, 0x6BFF, 0xFE9D, 0xE2B4)
#define TCP_SERVER_PORT (50007)
#define MAX_TCP_RECV_BUFFER_SIZE (20)
#define RTOS_TASK_MILLISECONDS_TO_WAIT (1000)
#define SOCKET_DISCONNECT_TIMEOUT (0)
bool received_msg_from_server;
cy_rslt_t tcp_ipv6_client_recv_handler(
cy_socket_t client_handle,
void *arg)
{
cy_rslt_t result ;
uint32_t bytes_received = 0;
char rx_buffer[MAX_TCP_RECV_BUFFER_SIZE];
result =
cy_socket_recv(client_handle, rx_buffer, MAX_TCP_RECV_BUFFER_SIZE,
received_msg_from_server = true;
return result;
}
void snippet_tcp_ipv6_client()
{
cy_rslt_t result;
(void)(result);
uint32_t bytes_sent = 0;
.port = TCP_SERVER_PORT
};
char tx_buffer[] = "Message to TCP server";
.
callback = tcp_ipv6_client_recv_handler,
.arg = NULL
};
for(;;)
{
if(received_msg_from_server)
{
break;
}
cy_rtos_delay_milliseconds(RTOS_TASK_MILLISECONDS_TO_WAIT);
}
}
@ CY_SOCKET_IP_VER_V6
IPv6 protocol.
Definition: cy_secure_sockets.h:87
#define CY_SOCKET_DOMAIN_AF_INET6
Domain option for cy_socket_create() - IPv6 internet protocols.
Definition: cy_secure_sockets_constants.h:48
uint32_t v6[4]
IPv6 address in network byte order.
Definition: cy_secure_sockets.h:149
Code Snippet 6: Create UDP Socket
This code snippet demonstrates how to initialize and create a UDP socket using an IPv4 address domain.
void snippet_create_udp_socket()
{
cy_rslt_t result;
(void)(result);
}
#define CY_SOCKET_IPPROTO_UDP
Protocol option for cy_socket_create() - UDP.
Definition: cy_secure_sockets_constants.h:60
#define CY_SOCKET_TYPE_DGRAM
Type parameter for cy_socket_create() - Datagram.
Definition: cy_secure_sockets_constants.h:53
Code Snippet 7: UDP Client - Send data to a UDP server using an IPv4 address
This code snippet demonstrates how to create a UDP client using an IPv4 address domain and send data to a UDP server. After sending data to the UDP server, this UDP client waits for a response message from the server.
#define MAKE_IPV4_ADDRESS(a, b, c, d) ((((uint32_t) d) << 24) | \
(((uint32_t) c) << 16) | \
(((uint32_t) b) << 8) |\
((uint32_t) a))
#define UDP_SERVER_IP_ADDRESS MAKE_IPV4_ADDRESS(192, 168, 18, 9)
#define UDP_SERVER_PORT (50007)
#define MAX_UDP_RECV_BUFFER_SIZE (20)
#define RTOS_TASK_MILLISECONDS_TO_WAIT (1000)
bool received_msg_from_udp_server;
cy_rslt_t udp_client_recv_handler(
cy_socket_t socket_handle,
void *arg)
{
cy_rslt_t result ;
uint32_t bytes_received = 0;
char rx_buffer[MAX_UDP_RECV_BUFFER_SIZE];
received_msg_from_udp_server = true;
return result;
}
void snippet_udp_client()
{
cy_rslt_t result;
(void)(result);
uint32_t bytes_sent = 0;
.port = UDP_SERVER_PORT
};
char tx_buffer[] = "Message to UDP server";
.arg = NULL
};
for(;;)
{
if(received_msg_from_udp_server)
{
break;
}
cy_rtos_delay_milliseconds(RTOS_TASK_MILLISECONDS_TO_WAIT);
}
}
cy_rslt_t cy_socket_recvfrom(cy_socket_t handle, void *buffer, uint32_t length, int flags, cy_socket_sockaddr_t *src_addr, uint32_t *src_addr_length, uint32_t *bytes_received)
Receives a UDP datagram for the specified socket.
cy_rslt_t cy_socket_sendto(cy_socket_t handle, const void *buffer, uint32_t length, int flags, const cy_socket_sockaddr_t *dest_addr, uint32_t address_length, uint32_t *bytes_sent)
Sends a UDP datagram over a specified socket.
Code Snippet 8: UDP Server - Receive data from a UDP client using an IPv4 address
This code snippet demonstrates how to create a UDP server using an IPv4 address domain and receive data from a UDP client.
#define MAKE_IPV4_ADDRESS(a, b, c, d) ((((uint32_t) d) << 24) | \
(((uint32_t) c) << 16) | \
(((uint32_t) b) << 8) |\
((uint32_t) a))
#define UDP_SERVER_IP_ADDRESS MAKE_IPV4_ADDRESS(192, 168, 18, 9)
#define UDP_SERVER_PORT (50007)
#define MAX_UDP_RECV_BUFFER_SIZE (20)
bool received_msg_from_udp_client;
cy_rslt_t udp_server_recv_handler(
cy_socket_t socket_handle,
void *arg)
{
cy_rslt_t result ;
uint32_t bytes_received = 0;
char rx_buffer[MAX_UDP_RECV_BUFFER_SIZE];
received_msg_from_udp_client = true;
return result;
}
void snippet_udp_server()
{
cy_rslt_t result;
(void)(result);
.port = UDP_SERVER_PORT
};
.arg = NULL
};
result =
cy_socket_bind(server_handle, &udp_server_addr,
sizeof(udp_server_addr));
for(;;)
{
if(received_msg_from_udp_client)
{
break;
}
cy_rtos_delay_milliseconds(RTOS_TASK_MILLISECONDS_TO_WAIT);
}
}
Code Snippet 9: IPv4 multicast group - Join and leave an IPv4 multicast group
This code snippet demonstrates how to join an IPv4 multicast group, send a packet to the IPv4 multicast address, receive a packet from the IPv4 multicast group, and leave the IPv4 multicast group.
#define MAKE_IPV4_ADDRESS(a, b, c, d) ((((uint32_t) d) << 24) | \
(((uint32_t) c) << 16) | \
(((uint32_t) b) << 8) |\
((uint32_t) a))
#define IPV4_MULTICAST_GROUP_ADDRESS MAKE_IPV4_ADDRESS(224, 1, 1, 1)
#define UDP_PORT (50007)
#define IPV4_DEVICE_ADDRESS MAKE_IPV4_ADDRESS(192, 168, 18, 9)
#define MAX_UDP_RECV_BUFFER_SIZE (20)
void snippet_udp_ipv4_multicast_join_leave()
{
cy_rslt_t result;
uint32_t bytes_sent = 0;
uint32_t bytes_received = 0;
(void)(result);
char tx_buffer[] = "Message to multicast group";
char rx_buffer[MAX_UDP_RECV_BUFFER_SIZE];
.
ip.
v4 = IPV4_DEVICE_ADDRESS,
};
.
ip.
v4 = IPV4_MULTICAST_GROUP_ADDRESS,
};
.port = UDP_PORT
};
result =
cy_socket_bind(handle, &socket_address,
sizeof(socket_address));
}
#define CY_SOCKET_SOL_IP
Level option for cy_socket_setsockopt() - IP protocol-level option.
Definition: cy_secure_sockets_constants.h:69
#define CY_SOCKET_SO_JOIN_MULTICAST_GROUP
Join an IPv4 (or) IPv6 multicast group.
Definition: cy_secure_sockets_constants.h:296
#define CY_SOCKET_SO_LEAVE_MULTICAST_GROUP
Leave an IPv4 (or) IPv6 multicast group.
Definition: cy_secure_sockets_constants.h:306
IP Address Structure.
Definition: cy_secure_sockets.h:143
Option value type for CY_SOCKET_SO_JOIN_MULTICAST_GROUP, and CY_SOCKET_SO_LEAVE_MULTICAST_GROUP socke...
Definition: cy_secure_sockets.h:175
cy_socket_ip_address_t if_addr
Local IP address of the interface.
Definition: cy_secure_sockets.h:177
cy_socket_ip_address_t multi_addr
IP multicast address of the group.
Definition: cy_secure_sockets.h:176
Code Snippet 10: IPv6 multicast group - Join and leave an IPv6 multicast group
This code snippet demonstrates how to join an IPv6 multicast group, send a packet to the IPv6 multicast address, receive a packet from the IPv6 multicast group, and leave the IPv6 multicast group.
#define HTONS(x) ( ( ( (x) & 0x0000FF00) >> 8 ) | ((x) & 0x000000FF) << 8 )
#define MAKE_IPV6_ADDRESS(a, b, c, d, e, f, g, h) { \
( (uint32_t) (HTONS(a)) | ( (uint32_t) (HTONS(b)) << 16 ) ), \
( (uint32_t) (HTONS(c)) | ( (uint32_t) (HTONS(d)) << 16 ) ), \
( (uint32_t) (HTONS(e)) | ( (uint32_t) (HTONS(f)) << 16 ) ), \
( (uint32_t) (HTONS(g)) | ( (uint32_t) (HTONS(h)) << 16 ) ), \
}
#define IPV6_MULTICAST_GROUP_ADDRESS MAKE_IPV6_ADDRESS( 0XFF02, 0, 0, 0, 0, 0, 0, 0XFB)
#define UDP_PORT (50007)
#define IPV6_DEVICE_ADDRESS MAKE_IPV6_ADDRESS( 0xFE80, 0, 0, 0, 0x29D, 0x6BFF, 0xFE9D, 0xE2B4)
void snippet_udp_ipv6_multicast_join_leave()
{
cy_rslt_t result;
uint32_t bytes_sent = 0;
uint32_t bytes_received = 0;
(void)(result);
char tx_buffer[] = "Message to multicast group";
char rx_buffer[MAX_UDP_RECV_BUFFER_SIZE];
.
ip.
v6 = IPV6_DEVICE_ADDRESS,
};
.
ip.
v6 = IPV6_MULTICAST_GROUP_ADDRESS,
};
.port = UDP_PORT
};
result =
cy_socket_bind(handle, &socket_address,
sizeof(socket_address));
}
Code Snippet 11: Enable broadcast messages - Enable broadcast messages, send a broadcast packet, and receive a broadcast packet.
This code snippet demonstrates how to enable broadcast messages, and send and receive a broadcast packet.
#define MAKE_IPV4_ADDRESS(a, b, c, d) ((((uint32_t) d) << 24) | \
(((uint32_t) c) << 16) | \
(((uint32_t) b) << 8) |\
((uint32_t) a))
#define BROADCAST_ADDRESS MAKE_IPV4_ADDRESS(255, 255, 255, 255)
#define IP_ADDRESS_ANY MAKE_IPV4_ADDRESS(0, 0, 0, 0)
#define UDP_PORT (50007)
#define MAX_UDP_RECV_BUFFER_SIZE (20)
void snippet_enable_broadcast_messages()
{
cy_rslt_t result;
uint32_t bytes_sent = 0;
uint32_t bytes_received = 0;
uint8_t broadcast_enable = 1;
(void)(result);
char tx_buffer[] = "Broadcasting Message";
char rx_buffer[MAX_UDP_RECV_BUFFER_SIZE];
.port = UDP_PORT
};
.port = UDP_PORT
};
result =
cy_socket_bind(handle, &socket_address_any,
sizeof(socket_address_any));
}
#define CY_SOCKET_SO_BROADCAST
Enable/disable sending and receiving broadcast messages on the socket.
Definition: cy_secure_sockets_constants.h:332
Code Snippet 12: Get the current time from the NTP server - Send an NTP request packet to the NTP server, and receive an NTP reply packet.
This code snippet demonstrates how to get the current time from the NTP server using a UDP socket.
#define NTOHL(x) ((((x) & (uint32_t)0x000000ffUL) << 24) | \
(((x) & (uint32_t)0x0000ff00UL) << 8) | \
(((x) & (uint32_t)0x00ff0000UL) >> 8) | \
(((x) & (uint32_t)0xff000000UL) >> 24))
#define NTP_SERVER "pool.ntp.org"
#define NTP_SERVER_PORT_NUM (123)
#define NTP_EPOCH (86400U * (365U * 70U + 17U))
#define NTP_LEAP_INDICATOR_CLOCK_UNSYNCRONIZED (3)
#define NTP_VERSION_NUM_V3 (3)
#define NTP_MODE_CLIENT (3)
typedef struct
{
unsigned int mode : 3;
unsigned int vn : 3;
unsigned int li : 2;
uint8_t stratum;
int8_t poll;
uint8_t precision;
uint32_t root_delay;
uint32_t root_dispersion;
uint32_t reference_identifier;
uint32_t reference_timestamp_seconds;
uint32_t reference_timestamp_fraction;
uint32_t originate_timestamp_seconds;
uint32_t originate_timestamp_fraction;
uint32_t receive_timestamp_seconds;
uint32_t receive_timestamp_fraction;
uint32_t transmit_timestamp_seconds;
uint32_t transmit_timestamp_fraction;
} ntp_packet_t;
void snippet_get_ntp_time()
{
cy_rslt_t result;
uint32_t bytes_sent = 0;
uint32_t bytes_received = 0;
uint32_t seconds;
(void)(result);
(void)(seconds);
ntp_packet_t ntp_request;
ntp_packet_t ntp_reply;
.port = NTP_SERVER_PORT_NUM
};
memset(&ntp_request, 0, sizeof(ntp_packet_t));
ntp_request.li = NTP_LEAP_INDICATOR_CLOCK_UNSYNCRONIZED;
ntp_request.vn = NTP_VERSION_NUM_V3;
ntp_request.mode = NTP_MODE_CLIENT;
result =
cy_socket_sendto(handle, &ntp_request,
sizeof(ntp_request), 0, &socket_address, (uint32_t)
sizeof(socket_address), &bytes_sent);
result =
cy_socket_recvfrom(handle, &ntp_reply,
sizeof(ntp_reply), 0, NULL, NULL, &bytes_received);
seconds = NTOHL(ntp_reply.transmit_timestamp_seconds) - NTP_EPOCH;
}
cy_rslt_t cy_socket_deinit(void)
Releases the resources allocated in cy_socket_init function.
cy_rslt_t cy_socket_delete(cy_socket_t handle)
Releases the resources allocated for the socket by the cy_socket_create function.
cy_rslt_t cy_socket_gethostbyname(const char *hostname, cy_socket_ip_version_t ip_ver, cy_socket_ip_address_t *addr)
Resolves a host name using Domain Name Service.
Code Snippet 13: Connect to secure server in PKCS mode - TLS connection using PKCS mode for secured kit (CY8CKIT-064S0S2-4343W)
This code snippet demonstrates establishing a TLS (secure TCP) connection using a Secure PSoC6 kit with PKCS mode. NOTE: The device credentials and RootCA certificates should be provisioned in the PSoC6 secure hardware before running this snippet.
#ifdef CY_SECURE_SOCKETS_PKCS_SUPPORT
#define PORT 443
#define HOSTNAME "www.httpbin.org"
#ifdef CY_TFM_PSA_SUPPORTED
static struct ns_mailbox_queue_t ns_mailbox_queue;
static void tfm_ns_multi_core_boot(void)
{
int32_t ret;
if (tfm_ns_wait_for_s_cpu_ready())
{
for (;;)
{
}
}
ret = tfm_ns_mailbox_init(&ns_mailbox_queue);
if (ret != MAILBOX_SUCCESS)
{
for (;;)
{
}
}
}
#endif
void snippet_secure_sockets_tls_connect_pkcs()
{
cy_rslt_t result;
(void)(result);
cy_nw_ip_address_t nw_ip_addr;
char buf[16];
#ifdef CY_TFM_PSA_SUPPORTED
tfm_ns_multi_core_boot();
tfm_ns_interface_init();
#endif
nw_ip_addr.version = NW_IP_IPV4;
nw_ip_addr.ip.v4 = ip_addr.
ip.
v4;
cy_nw_ntoa(&nw_ip_addr, buf);
printf("IP Address : %s \n", buf);
}
#endif
cy_socket_ip_version_t version
IP version cy_socket_ip_version_t.
Definition: cy_secure_sockets.h:144
uint16_t port
Port Number in host byte order.
Definition: cy_secure_sockets.h:158
Troubleshooting
Problem1: cy_socket_listen() fails if called on more than one socket.
Description: The default lwIP configuration provided by the Middleware Core library defines the MEMP_NUM_TCP_PCB_LISTEN option to 1; therefore, if cy_socket_listen() is called for the second socket, the function fails with the error code CY_RSLT_MODULE_SECURE_SOCKETS_NOMEM.
Solution: Change MEMP_NUM_TCP_PCB_LISTEN value in lwipopts.h to support more than one server socket.
Problem2: Sometimes, the cy_socket_recv() function does not return for 10 seconds.
Description: cy_socket_recv() returns after 10 seconds if the requested number of bytes is not available in the socket. This happens because the default receive timeout is configured as 10 seconds when the socket is created.
Solution: Change the default receive timeout value for the socket by calling the cy_socket_setsockopt() function with the CY_SOCKET_SO_RCVTIMEO socket option with the required timeout value.
Problem3: TCP packets are dropped.
Description: When an application is consuming data at a lower rate, the network stack continues to receive the data at the rate it arrives from the peer. At some point, the network stack's receive queue can overflow causing packets to get dropped.
Solution: Applications consuming data at a lower rate should adjust the TCP receive queue size and TCP Window size so that when the receive queue size becomes full, the TCP window size also becomes zero. To change the TCP receive queue size, change the DEFAULT_TCP_RECVMBOX_SIZE macro value in the lwipopts.h file. To change the TCP Window size, define the TCP_WND macro in lwipopts.h to override the default value defined the opt.h file.
Problem4: cy_socket_create() function fails with the CY_RSLT_MODULE_SECURE_SOCKETS_NOMEM error while creating multiple sockets.
Description: The maximum number of TCP and UDP sockets that can be created depends on the network stack configuration. Trying to create more than the maximum value configured can cause the cy_socket_create() function to return the error CY_RSLT_MODULE_SECURE_SOCKETS_NOMEM.
Solution: Configure the maximum number of TCP and UDP sockets to be supported by changing the MEMP_NUM_TCP_PCB and MEMP_NUM_UDP_PCB values respectively in the lwipopts.h file. Also note that the total number of TCP and UDP configurations should not exceed the value of the MEMP_NUM_NETCONN macro defined in the lwipopts.h file.
Problem5: An existing socket cannot be reused to establish a new connection just with socket disconnect.
Description: lwIP does not support re-connect on a disconnected socket. Once a connected TCP socket is disconnected, it cannot be reused for a new connection or re-connection.
Solution: Delete the disconnected socket and create a new socket using cy_socket_create, and try to connect with the new socket using cy_socket_connect.
Problem6: cy_socket_sendto() with multicast destination addresses fails on the SoftAP interface.
Description: If a socket is used for multicast operations over the SoftAP interface without binding it to the SoftAP interface, cy_socket_sendto() fails with the CY_RSLT_MODULE_SECURE_SOCKETS_ERROR_ROUTING error.
Solution: Bind the socket to the SoftAP interface using the cy_socket_setsockopt() function with the CY_SOCKET_SO_BINDTODEVICE socket option.