network/softap_tcp_server/main.c

/*
* EVALUATION AND USE OF THIS SOFTWARE IS SUBJECT TO THE TERMS AND
* CONDITIONS OF THE CONTROLLING LICENSE AGREEMENT FOUND AT LICENSE.md
* IN THIS SDK. IF YOU DO NOT AGREE TO THE LICENSE TERMS AND CONDITIONS,
* PLEASE RETURN ALL SOURCE FILES TO SILICON LABORATORIES.
* (c) Copyright 2018, Silicon Laboratories Inc. All rights reserved.
*/
/* Documentation for this app is available online.
* See https://docs.silabs.com/gecko-os/4/standard/latest/sdk/examples/network/softap-tcp-server
*/
#include "gos.h"
#define TCP_SERVER_PORT 2000
#define WELCOME_MSG "Welcome to the TCP Echo Server\r\n"
#define APPLICATION_START_LINE "\r\nSoftAP TCP Server Example starting ..."
/*************************************************************************************************/
void gos_app_init(void)
{
gos_result_t result;
char buffer[32];
GOS_LOG(APPLICATION_START_LINE);
if (GOS_FAILED(result, gos_load_app_settings("settings.ini")))
{
GOS_LOG("Failed to load settings, err:%d", result);
return;
}
gos_tcp_register_server_event_handlers(tcp_client_connect_handler, tcp_client_disconnect_handler, tcp_client_receive_handler);
GOS_LOG("Starting SoftAP...");
{
GOS_LOG("Failed to start SoftAP, err:%d", result);
return;
}
GOS_LOG("Softap name: %s", GOS_GET_SETTING_STR("softap.ssid", buffer));
GOS_LOG("Softap password: %s", GOS_GET_SETTING_STR("softap.passkey", buffer));
GOS_LOG("Starting TCP Echo Server...");
if (GOS_FAILED(result, gos_tcp_listen(GOS_INTERFACE_SOFTAP, TCP_SERVER_PORT)))
{
GOS_LOG("Failed to start TCP Server: %d", result);
return;
}
GOS_LOG("TCP Echo Server listening on: %s:%u", GOS_GET_SETTING_STR("softap.dns_server.url", buffer), TCP_SERVER_PORT);
}
/*************************************************************************************************/
static void softap_event_handler(const gos_softap_client_t *info)
{
char mac_str[32];
char ip_str[32];
GOS_LOG("SoftAP Client: %s (%s) - %s", mac_to_str(&info->mac, mac_str),
ipv4_to_str(info->ipv4_address, ip_str),
info->valid ? "Connected" : "Disconnected");
}
/*************************************************************************************************/
static void tcp_client_connect_handler(gos_handle_t handle)
{
char host_buffer[64];
uint16_t local_port, remote_port;
if (gos_tcp_get_client_info(handle, host_buffer, sizeof(host_buffer), &local_port, &remote_port) == GOS_SUCCESS)
{
GOS_LOG("TCP Client: %s:%u connected", host_buffer, remote_port);
gos_tcp_write(handle, WELCOME_MSG, sizeof(WELCOME_MSG)-1, false);
}
}
/*************************************************************************************************/
static void tcp_client_disconnect_handler(gos_handle_t handle)
{
GOS_LOG("TCP Client: %d disconnected", handle);
}
/*************************************************************************************************/
static void tcp_client_receive_handler(gos_handle_t handle)
{
#define STREAM_READ_TIMEOUT 100
gos_result_t result;
const uint32_t start_time = gos_rtos_get_time();
// NOTE: We do NOT want to spend too much time in this loop reading the RX stream data
// as it will starve the rest of the system.
// Thus we break out of the loop after STREAM_READ_TIMEOUT milliseconds.
// Another RX event will be triggered if more data is available.
while ((gos_rtos_get_time() - start_time) < STREAM_READ_TIMEOUT)
{
gos_buffer_t buffer = {.size = 0 };
if (GOS_FAILED(result, gos_tcp_poll(handle, &buffer.size, NULL)) || buffer.size == 0)
{
break;
}
if (GOS_FAILED(result, gos_tcp_read_with_buffer(handle, &buffer)))
{
GOS_LOG("Failed to read from stream %d, err:%d", handle, result);
break;
}
GOS_LOG("Rx data:");
gos_write_log((const char*)buffer.data, buffer.size);
if (GOS_FAILED(result, gos_tcp_write(handle, buffer.data, buffer.size, false)))
{
GOS_LOG("Failed to write to stream %d, err:%d", handle, result);
break;
}
}
}