Skip to content
Permalink
f34160b818
Switch branches/tags

Name already in use

A tag already exists with the provided branch name. Many Git commands accept both tag and branch names, so creating this branch may cause unexpected behavior. Are you sure you want to create this branch?
Go to file
 
 
Cannot retrieve contributors at this time
743 lines (635 sloc) 27.6 KB
/******************************************************************************
* File Name: tcp_server.c
*
* Description: This file contains declaration of task and functions related to
* TCP server operation.
*
* Related Document: See README.md
*
*
*******************************************************************************
* $ Copyright 2021-2023 Cypress Semiconductor $
*******************************************************************************/
/* Header file includes */
#include "cyhal.h"
#include "cybsp.h"
#include "cy_retarget_io.h"
/* FreeRTOS header file */
#include <FreeRTOS.h>
#include <task.h>
/* Cypress secure socket header file */
#include "cy_secure_sockets.h"
/* Wi-Fi connection manager header files */
#include "cy_wcm.h"
#include "cy_wcm_error.h"
/* Standard C header file */
#include <string.h>
/* TCP server task header file. */
#include "tcp_server.h"
/* IP address related header files (part of the lwIP TCP/IP stack). */
#include "ip_addr.h"
/* Standard C header files */
#include <inttypes.h>
/*******************************************************************************
* Macros
********************************************************************************/
/* To use the Wi-Fi device in AP interface mode, set this macro as '1' */
#define USE_AP_INTERFACE (0)
#define MAKE_IP_PARAMETERS(a, b, c, d) ((((uint32_t) d) << 24) | \
(((uint32_t) c) << 16) | \
(((uint32_t) b) << 8) |\
((uint32_t) a))
#if(USE_AP_INTERFACE)
#define WIFI_INTERFACE_TYPE CY_WCM_INTERFACE_TYPE_AP
/* SoftAP Credentials: Modify SOFTAP_SSID and SOFTAP_PASSWORD as required */
#define SOFTAP_SSID "MY_SOFT_AP"
#define SOFTAP_PASSWORD "cyw43907"
/* Security type of the SoftAP. See 'cy_wcm_security_t' structure
* in "cy_wcm.h" for more details.
*/
#define SOFTAP_SECURITY_TYPE CY_WCM_SECURITY_WPA2_AES_PSK
#define SOFTAP_IP_ADDRESS_COUNT (2u)
#define SOFTAP_IP_ADDRESS MAKE_IP_PARAMETERS(192, 168, 10, 1)
#define SOFTAP_NETMASK MAKE_IP_PARAMETERS(255, 255, 255, 0)
#define SOFTAP_GATEWAY MAKE_IP_PARAMETERS(192, 168, 10, 1)
#define SOFTAP_RADIO_CHANNEL (1u)
#else
#define WIFI_INTERFACE_TYPE CY_WCM_INTERFACE_TYPE_STA
/* Wi-Fi Credentials: Modify WIFI_SSID, WIFI_PASSWORD, and WIFI_SECURITY_TYPE
* to match your Wi-Fi network credentials.
* Note: Maximum length of the Wi-Fi SSID and password is set to
* CY_WCM_MAX_SSID_LEN and CY_WCM_MAX_PASSPHRASE_LEN as defined in cy_wcm.h file.
*/
#define WIFI_SSID "MY_WIFI_SSID"
#define WIFI_PASSWORD "MY_WIFI_PASSWORD"
/* Security type of the Wi-Fi access point. See 'cy_wcm_security_t' structure
* in "cy_wcm.h" for more details.
*/
#define WIFI_SECURITY_TYPE CY_WCM_SECURITY_WPA2_AES_PSK
/* Maximum number of connection retries to a Wi-Fi network. */
#define MAX_WIFI_CONN_RETRIES (10u)
/* Wi-Fi re-connection time interval in milliseconds */
#define WIFI_CONN_RETRY_INTERVAL_MSEC (1000u)
#endif /* USE_AP_INTERFACE */
/* TCP server related macros. */
#define TCP_SERVER_PORT (50007)
#define TCP_SERVER_MAX_PENDING_CONNECTIONS (3u)
#define TCP_SERVER_RECV_TIMEOUT_MS (500u)
#define MAX_TCP_RECV_BUFFER_SIZE (20u)
/* TCP keep alive related macros. */
#define TCP_KEEP_ALIVE_IDLE_TIME_MS (10000u)
#define TCP_KEEP_ALIVE_INTERVAL_MS (1000u)
#define TCP_KEEP_ALIVE_RETRY_COUNT (2u)
/* Length of the LED ON/OFF command issued from the TCP server. */
#define TCP_LED_CMD_LEN (1)
/* LED ON and LED OFF commands. */
#define LED_ON_CMD '1'
#define LED_OFF_CMD '0'
/* Interrupt priority of the user button. */
#define USER_BTN_INTR_PRIORITY (5)
/* Debounce delay for user button. */
#define DEBOUNCE_DELAY_MS (50)
/*******************************************************************************
* Function Prototypes
********************************************************************************/
static cy_rslt_t create_tcp_server_socket(void);
static cy_rslt_t tcp_connection_handler(cy_socket_t socket_handle, void *arg);
static cy_rslt_t tcp_receive_msg_handler(cy_socket_t socket_handle, void *arg);
static cy_rslt_t tcp_disconnection_handler(cy_socket_t socket_handle, void *arg);
static void isr_button_press( void *callback_arg, cyhal_gpio_event_t event);
#if(USE_AP_INTERFACE)
static cy_rslt_t softap_start(void);
#else
static cy_rslt_t connect_to_wifi_ap(void);
#endif /* USE_AP_INTERFACE */
/*******************************************************************************
* Global Variables
********************************************************************************/
/* Secure socket variables. */
cy_socket_sockaddr_t tcp_server_addr, peer_addr;
cy_socket_t server_handle, client_handle;
/* Size of the peer socket address. */
uint32_t peer_addr_len;
/* Flags to track the LED state. */
bool led_state = CYBSP_LED_STATE_OFF;
/* TCP server task handle. */
extern TaskHandle_t server_task_handle;
/* Flag variable to check if TCP client is connected. */
bool client_connected;
/*******************************************************************************
* Function Name: tcp_server_task
*******************************************************************************
* Summary:
* Task used to establish a connection to a TCP client.
*
* Parameters:
* void *args : Task parameter defined during task creation (unused)
*
* Return:
* void
*
*******************************************************************************/
void tcp_server_task(void *arg)
{
cy_rslt_t result = CY_RSLT_SUCCESS;
cyhal_gpio_callback_data_t cb_data =
{
.callback = isr_button_press,
.callback_arg = (void*)NULL
};
cy_wcm_config_t wifi_config = { .interface = WIFI_INTERFACE_TYPE };
/* Variable to store number of bytes sent over TCP socket. */
uint32_t bytes_sent = 0;
/* Variable to receive LED ON/OFF command from the user button ISR. */
uint32_t led_state_cmd = LED_OFF_CMD;
/* Initialize the user button (CYBSP_SW1) and register interrupt on falling edge. */
cyhal_gpio_init(CYBSP_SW1, CYHAL_GPIO_DIR_INPUT, CYHAL_GPIO_DRIVE_PULLUP, CYBSP_BTN_OFF);
cyhal_gpio_register_callback(CYBSP_SW1, &cb_data);
cyhal_gpio_enable_event(CYBSP_SW1, CYHAL_GPIO_IRQ_FALL, USER_BTN_INTR_PRIORITY, true);
/* Initialize Wi-Fi connection manager. */
result = cy_wcm_init(&wifi_config);
if (result != CY_RSLT_SUCCESS)
{
printf("Wi-Fi Connection Manager initialization failed! Error code: 0x%08"PRIx32"\n", (uint32_t)result);
CY_ASSERT(0);
}
printf("Wi-Fi Connection Manager initialized.\r\n");
#if(USE_AP_INTERFACE)
/* Start the Wi-Fi device as a Soft AP interface. */
result = softap_start();
if (result != CY_RSLT_SUCCESS)
{
printf("Failed to Start Soft AP! Error code: 0x%08"PRIx32"\n", (uint32_t)result);
CY_ASSERT(0);
}
#else
/* Connect to Wi-Fi AP */
result = connect_to_wifi_ap();
if(result != CY_RSLT_SUCCESS )
{
printf("\n Failed to connect to Wi-Fi AP! Error code: 0x%08"PRIx32"\n", (uint32_t)result);
CY_ASSERT(0);
}
#endif /* USE_AP_INTERFACE */
/* Initialize secure socket library. */
result = cy_socket_init();
if (result != CY_RSLT_SUCCESS)
{
printf("Secure Socket initialization failed! Error code: 0x%08"PRIx32"\n", (uint32_t)result);
CY_ASSERT(0);
}
printf("Secure Socket initialized\n");
/* Create TCP server socket. */
result = create_tcp_server_socket();
if (result != CY_RSLT_SUCCESS)
{
printf("Failed to create socket! Error code: 0x%08"PRIx32"\n", (uint32_t)result);
CY_ASSERT(0);
}
/* Start listening on the TCP server socket. */
result = cy_socket_listen(server_handle, TCP_SERVER_MAX_PENDING_CONNECTIONS);
if (result != CY_RSLT_SUCCESS)
{
cy_socket_delete(server_handle);
printf("cy_socket_listen returned error. Error code: 0x%08"PRIx32"\n", (uint32_t)result);
CY_ASSERT(0);
}
else
{
printf("===============================================================\n");
printf("Listening for incoming TCP client connection on Port: %d\n",
tcp_server_addr.port);
}
while(true)
{
/* Wait till user button is pressed to send LED ON/OFF command to TCP client. */
xTaskNotifyWait(0, 0, &led_state_cmd, portMAX_DELAY);
/* Disable the GPIO signal falling edge detection until the command is
* sent to the TCP client.
*/
cyhal_gpio_enable_event(CYBSP_SW1, CYHAL_GPIO_IRQ_FALL, USER_BTN_INTR_PRIORITY, false);
/* Wait till the debounce period of the user button. */
vTaskDelay(DEBOUNCE_DELAY_MS/portTICK_PERIOD_MS);
if(!cyhal_gpio_read(CYBSP_SW1))
{
/* Send LED ON/OFF command to TCP client if there is an active
* TCP client connection.
*/
if(client_connected)
{
/* Send the command to TCP client. */
result = cy_socket_send(client_handle, &led_state_cmd, TCP_LED_CMD_LEN,
CY_SOCKET_FLAGS_NONE, &bytes_sent);
if(result == CY_RSLT_SUCCESS )
{
if(led_state_cmd == LED_ON_CMD)
{
printf("LED ON command sent to TCP client\n");
}
else
{
printf("LED OFF command sent to TCP client\n");
}
}
else
{
printf("Failed to send command to client. Error code: 0x%08"PRIx32"\n", (uint32_t)result);
if(result == CY_RSLT_MODULE_SECURE_SOCKETS_CLOSED)
{
/* Disconnect the socket. */
cy_socket_disconnect(client_handle, 0);
/* Delete the socket. */
cy_socket_delete(client_handle);
}
}
}
}
/* Enable the GPIO signal falling edge detection. */
cyhal_gpio_enable_event(CYBSP_SW1, CYHAL_GPIO_IRQ_FALL, USER_BTN_INTR_PRIORITY, true);
}
}
#if(!USE_AP_INTERFACE)
/*******************************************************************************
* Function Name: connect_to_wifi_ap()
*******************************************************************************
* Summary:
* Connects to Wi-Fi AP using the user-configured credentials, retries up to a
* configured number of times until the connection succeeds.
*
*******************************************************************************/
static cy_rslt_t connect_to_wifi_ap(void)
{
cy_rslt_t result = CY_RSLT_SUCCESS;
uint8_t ssid_len = 0;
uint8_t pwd_len = 0;
/* Variables used by Wi-Fi connection manager.*/
cy_wcm_connect_params_t wifi_conn_param;
cy_wcm_ip_address_t ip_address;
/* Variable to track the number of connection retries to the Wi-Fi AP specified
* by WIFI_SSID macro.
*/
int conn_retries = 0;
/*Validate the length of SSID and password*/
ssid_len = (uint8_t)strlen(WIFI_SSID);
pwd_len = (uint8_t)strlen(WIFI_PASSWORD);
if(ssid_len == 0 || ssid_len > CY_WCM_MAX_SSID_LEN )
{
printf("SSID - invalid length error \n");
return CY_RSLT_WCM_BAD_SSID_LEN;
}
if(pwd_len == 0 || pwd_len > CY_WCM_MAX_PASSPHRASE_LEN )
{
printf("AP credentials passphrase length error\n");
return CY_RSLT_WCM_BAD_PASSPHRASE_LEN;
}
/* Set the Wi-Fi SSID, password and security type. */
memset(&wifi_conn_param, 0, sizeof(cy_wcm_connect_params_t));
memcpy(wifi_conn_param.ap_credentials.SSID, WIFI_SSID, sizeof(WIFI_SSID));
memcpy(wifi_conn_param.ap_credentials.password, WIFI_PASSWORD, sizeof(WIFI_PASSWORD));
wifi_conn_param.ap_credentials.security = WIFI_SECURITY_TYPE;
printf("Connecting to Wi-Fi Network: %s\n", WIFI_SSID);
/* Join the Wi-Fi AP. */
for(conn_retries = 0; conn_retries < MAX_WIFI_CONN_RETRIES; conn_retries++ )
{
result = cy_wcm_connect_ap(&wifi_conn_param, &ip_address);
if(result == CY_RSLT_SUCCESS)
{
printf("Successfully connected to Wi-Fi network '%s'.\n",
wifi_conn_param.ap_credentials.SSID);
printf("IP Address Assigned: %s\n", ip4addr_ntoa((const ip4_addr_t *)&ip_address.ip.v4));
/* IP address and TCP port number of the TCP server */
tcp_server_addr.ip_address.ip.v4 = ip_address.ip.v4;
tcp_server_addr.ip_address.version = CY_SOCKET_IP_VER_V4;
tcp_server_addr.port = TCP_SERVER_PORT;
return result;
}
printf("Connection to Wi-Fi network failed with error code 0x%08"PRIx32"\n."
"Retrying in %d ms...\n", (uint32_t)result, WIFI_CONN_RETRY_INTERVAL_MSEC);
vTaskDelay(pdMS_TO_TICKS(WIFI_CONN_RETRY_INTERVAL_MSEC));
}
/* Stop retrying after maximum retry attempts. */
printf("Exceeded maximum Wi-Fi connection attempts\n");
return result;
}
#endif /* USE_AP_INTERFACE */
#if(USE_AP_INTERFACE)
/********************************************************************************
* Function Name: softap_start
********************************************************************************
* Summary:
* This function configures device in AP mode and initializes
* a SoftAP with the given credentials (SOFTAP_SSID, SOFTAP_PASSWORD and
* SOFTAP_SECURITY_TYPE).
*
* Parameters:
* void
*
* Return:
* cy_rslt_t: Returns CY_RSLT_SUCCESS if the Soft AP is started successfully,
* a WCM error code otherwise.
*
*******************************************************************************/
static cy_rslt_t softap_start(void)
{
cy_rslt_t result = CY_RSLT_SUCCESS;
/* Initialize the Wi-Fi device as a Soft AP. */
cy_wcm_ap_credentials_t softap_credentials = {SOFTAP_SSID, SOFTAP_PASSWORD,
SOFTAP_SECURITY_TYPE};
cy_wcm_ip_setting_t softap_ip_info = {
.ip_address = {.version = CY_WCM_IP_VER_V4, .ip.v4 = SOFTAP_IP_ADDRESS},
.gateway = {.version = CY_WCM_IP_VER_V4, .ip.v4 = SOFTAP_GATEWAY},
.netmask = {.version = CY_WCM_IP_VER_V4, .ip.v4 = SOFTAP_NETMASK}};
cy_wcm_ap_config_t softap_config = {softap_credentials, SOFTAP_RADIO_CHANNEL,
softap_ip_info,
NULL};
/* Start the the Wi-Fi device as a Soft AP. */
result = cy_wcm_start_ap(&softap_config);
if(result == CY_RSLT_SUCCESS)
{
printf("Wi-Fi Device configured as Soft AP\n");
printf("Connect TCP client device to the network: SSID: %s Password:%s\n",
SOFTAP_SSID, SOFTAP_PASSWORD);
printf("SofAP IP Address : %s\n\n",
ip4addr_ntoa((const ip4_addr_t *)&softap_ip_info.ip_address.ip.v4));
/* IP address and TCP port number of the TCP server. */
tcp_server_addr.ip_address.ip.v4 = softap_ip_info.ip_address.ip.v4;
tcp_server_addr.ip_address.version = CY_SOCKET_IP_VER_V4;
tcp_server_addr.port = TCP_SERVER_PORT;
}
return result;
}
#endif /* USE_AP_INTERFACE */
/*******************************************************************************
* Function Name: create_tcp_server_socket
*******************************************************************************
* Summary:
* Function to create a socket and set the socket options
*
*******************************************************************************/
static cy_rslt_t create_tcp_server_socket(void)
{
cy_rslt_t result = CY_RSLT_SUCCESS;
/* TCP socket receive timeout period. */
uint32_t tcp_recv_timeout = TCP_SERVER_RECV_TIMEOUT_MS;
/* Variables used to set socket options. */
cy_socket_opt_callback_t tcp_receive_option;
cy_socket_opt_callback_t tcp_connection_option;
cy_socket_opt_callback_t tcp_disconnection_option;
/* Create a TCP socket */
result = cy_socket_create(CY_SOCKET_DOMAIN_AF_INET, CY_SOCKET_TYPE_STREAM,
CY_SOCKET_IPPROTO_TCP, &server_handle);
if(result != CY_RSLT_SUCCESS)
{
printf("Failed to create socket! Error code: 0x%08"PRIx32"\n", (uint32_t)result);
return result;
}
/* Set the TCP socket receive timeout period. */
result = cy_socket_setsockopt(server_handle, CY_SOCKET_SOL_SOCKET,
CY_SOCKET_SO_RCVTIMEO, &tcp_recv_timeout,
sizeof(tcp_recv_timeout));
if(result != CY_RSLT_SUCCESS)
{
printf("Set socket option: CY_SOCKET_SO_RCVTIMEO failed\n");
return result;
}
/* Register the callback function to handle connection request from a TCP client. */
tcp_connection_option.callback = tcp_connection_handler;
tcp_connection_option.arg = NULL;
result = cy_socket_setsockopt(server_handle, CY_SOCKET_SOL_SOCKET,
CY_SOCKET_SO_CONNECT_REQUEST_CALLBACK,
&tcp_connection_option, sizeof(cy_socket_opt_callback_t));
if(result != CY_RSLT_SUCCESS)
{
printf("Set socket option: CY_SOCKET_SO_CONNECT_REQUEST_CALLBACK failed\n");
return result;
}
/* Register the callback function to handle messages received from a TCP client. */
tcp_receive_option.callback = tcp_receive_msg_handler;
tcp_receive_option.arg = NULL;
result = cy_socket_setsockopt(server_handle, CY_SOCKET_SOL_SOCKET,
CY_SOCKET_SO_RECEIVE_CALLBACK,
&tcp_receive_option, sizeof(cy_socket_opt_callback_t));
if(result != CY_RSLT_SUCCESS)
{
printf("Set socket option: CY_SOCKET_SO_RECEIVE_CALLBACK failed\n");
return result;
}
/* Register the callback function to handle disconnection. */
tcp_disconnection_option.callback = tcp_disconnection_handler;
tcp_disconnection_option.arg = NULL;
result = cy_socket_setsockopt(server_handle, CY_SOCKET_SOL_SOCKET,
CY_SOCKET_SO_DISCONNECT_CALLBACK,
&tcp_disconnection_option, sizeof(cy_socket_opt_callback_t));
if(result != CY_RSLT_SUCCESS)
{
printf("Set socket option: CY_SOCKET_SO_DISCONNECT_CALLBACK failed\n");
return result;
}
/* Bind the TCP socket created to Server IP address and to TCP port. */
result = cy_socket_bind(server_handle, &tcp_server_addr, sizeof(tcp_server_addr));
if(result != CY_RSLT_SUCCESS)
{
printf("Failed to bind to socket! Error code: 0x%08"PRIx32"\n", (uint32_t)result);
}
return result;
}
/*******************************************************************************
* Function Name: tcp_connection_handler
*******************************************************************************
* Summary:
* Callback function to handle incoming TCP client connection.
*
* Parameters:
* cy_socket_t socket_handle: Connection handle for the TCP server socket
* void *args : Parameter passed on to the function (unused)
*
* Return:
* cy_result result: Result of the operation
*
*******************************************************************************/
static cy_rslt_t tcp_connection_handler(cy_socket_t socket_handle, void *arg)
{
cy_rslt_t result = CY_RSLT_SUCCESS;
/* TCP keep alive parameters. */
int keep_alive = 1;
uint32_t keep_alive_interval = TCP_KEEP_ALIVE_INTERVAL_MS;
uint32_t keep_alive_count = TCP_KEEP_ALIVE_RETRY_COUNT;
uint32_t keep_alive_idle_time = TCP_KEEP_ALIVE_IDLE_TIME_MS;
/* Accept new incoming connection from a TCP client.*/
result = cy_socket_accept(socket_handle, &peer_addr, &peer_addr_len,
&client_handle);
if(result == CY_RSLT_SUCCESS)
{
printf("Incoming TCP connection accepted\n");
printf("IP Address : %s\n\n",
ip4addr_ntoa((const ip4_addr_t *)&peer_addr.ip_address.ip.v4));
printf("Press the user button to send LED ON/OFF command to the TCP client\n");
/* Set the TCP keep alive interval. */
result = cy_socket_setsockopt(client_handle, CY_SOCKET_SOL_TCP,
CY_SOCKET_SO_TCP_KEEPALIVE_INTERVAL,
&keep_alive_interval, sizeof(keep_alive_interval));
if(result != CY_RSLT_SUCCESS)
{
printf("Set socket option: CY_SOCKET_SO_TCP_KEEPALIVE_INTERVAL failed\n");
return result;
}
/* Set the retry count for TCP keep alive packet. */
result = cy_socket_setsockopt(client_handle, CY_SOCKET_SOL_TCP,
CY_SOCKET_SO_TCP_KEEPALIVE_COUNT,
&keep_alive_count, sizeof(keep_alive_count));
if(result != CY_RSLT_SUCCESS)
{
printf("Set socket option: CY_SOCKET_SO_TCP_KEEPALIVE_COUNT failed\n");
return result;
}
/* Set the network idle time before sending the TCP keep alive packet. */
result = cy_socket_setsockopt(client_handle, CY_SOCKET_SOL_TCP,
CY_SOCKET_SO_TCP_KEEPALIVE_IDLE_TIME,
&keep_alive_idle_time, sizeof(keep_alive_idle_time));
if(result != CY_RSLT_SUCCESS)
{
printf("Set socket option: CY_SOCKET_SO_TCP_KEEPALIVE_IDLE_TIME failed\n");
return result;
}
/* Enable TCP keep alive. */
result = cy_socket_setsockopt(client_handle, CY_SOCKET_SOL_SOCKET,
CY_SOCKET_SO_TCP_KEEPALIVE_ENABLE,
&keep_alive, sizeof(keep_alive));
if(result != CY_RSLT_SUCCESS)
{
printf("Set socket option: CY_SOCKET_SO_TCP_KEEPALIVE_ENABLE failed\n");
return result;
}
/* Set the client connection flag as true. */
client_connected = true;
}
else
{
printf("Failed to accept incoming client connection. Error code: 0x%08"PRIx32"\n", (uint32_t)result);
printf("===============================================================\n");
printf("Listening for incoming TCP client connection on Port: %d\n",
tcp_server_addr.port);
}
return result;
}
/*******************************************************************************
* Function Name: tcp_receive_msg_handler
*******************************************************************************
* Summary:
* Callback function to handle incoming TCP client messages.
*
* Parameters:
* cy_socket_t socket_handle: Connection handle for the TCP client socket
* void *args : Parameter passed on to the function (unused)
*
* Return:
* cy_result result: Result of the operation
*
*******************************************************************************/
static cy_rslt_t tcp_receive_msg_handler(cy_socket_t socket_handle, void *arg)
{
char message_buffer[MAX_TCP_RECV_BUFFER_SIZE] = {0};
cy_rslt_t result = CY_RSLT_SUCCESS;
/* Variable to store number of bytes received from TCP client. */
uint32_t bytes_received = 0;
result = cy_socket_recv(socket_handle, message_buffer, MAX_TCP_RECV_BUFFER_SIZE,
CY_SOCKET_FLAGS_NONE, &bytes_received);
if(result == CY_RSLT_SUCCESS)
{
/* Terminate the received string with '\0'. */
message_buffer[bytes_received] = '\0';
printf("\r\nAcknowledgement from TCP Client: %s\n", message_buffer);
/* Set the LED state based on the acknowledgement received from the TCP client. */
if(strcmp(message_buffer, "LED ON ACK") == 0)
{
led_state = CYBSP_LED_STATE_ON;
}
else
{
led_state = CYBSP_LED_STATE_OFF;
}
}
else
{
printf("Failed to receive acknowledgement from the TCP client. Error: 0x%08"PRIx32"\n",
(uint32_t)result);
if(result == CY_RSLT_MODULE_SECURE_SOCKETS_CLOSED)
{
/* Disconnect the socket. */
cy_socket_disconnect(socket_handle, 0);
/* Delete the socket. */
cy_socket_delete(socket_handle);
}
}
printf("===============================================================\n");
printf("Press the user button to send LED ON/OFF command to the TCP client\n");
return result;
}
/*******************************************************************************
* Function Name: tcp_disconnection_handler
*******************************************************************************
* Summary:
* Callback function to handle TCP client disconnection event.
*
* Parameters:
* cy_socket_t socket_handle: Connection handle for the TCP client socket
* void *args : Parameter passed on to the function (unused)
*
* Return:
* cy_result result: Result of the operation
*
*******************************************************************************/
static cy_rslt_t tcp_disconnection_handler(cy_socket_t socket_handle, void *arg)
{
cy_rslt_t result;
/* Disconnect the TCP client. */
result = cy_socket_disconnect(socket_handle, 0);
/* Delete the socket. */
cy_socket_delete(socket_handle);
/* Set the client connection flag as false. */
client_connected = false;
printf("TCP Client disconnected! Please reconnect the TCP Client\n");
printf("===============================================================\n");
printf("Listening for incoming TCP client connection on Port:%d\n",
tcp_server_addr.port);
/* Set the LED state to OFF when the TCP client disconnects. */
led_state = CYBSP_LED_STATE_OFF;
return result;
}
/*******************************************************************************
* Function Name: isr_button_press
*******************************************************************************
*
* Summary:
* GPIO interrupt service routine. This function detects button presses and
* sets the command to be sent to TCP client.
*
* Parameters:
* void *callback_arg : pointer to the variable passed to the ISR
* cyhal_gpio_event_t event : GPIO event type
*
* Return:
* void
*
*******************************************************************************/
static void isr_button_press( void *callback_arg, cyhal_gpio_event_t event)
{
BaseType_t xHigherPriorityTaskWoken = pdFALSE;
/* Variable to hold the LED ON/OFF command to be sent to the TCP client. */
uint32_t led_state_cmd;
/* Set the command to be sent to TCP client. */
if(led_state == CYBSP_LED_STATE_ON)
{
led_state_cmd = LED_OFF_CMD;
}
else
{
led_state_cmd = LED_ON_CMD;
}
/* Set the flag to send command to TCP client. */
xTaskNotifyFromISR(server_task_handle, led_state_cmd,
eSetValueWithoutOverwrite, &xHigherPriorityTaskWoken);
/* Force a context switch if xHigherPriorityTaskWoken is now set to pdTRUE. */
portYIELD_FROM_ISR(xHigherPriorityTaskWoken);
}
/* [] END OF FILE */