From c4415a9dba8f37aa68b12e5b48f1cd299dd581cc Mon Sep 17 00:00:00 2001 From: Martin Errenst Date: Sat, 28 Jul 2018 22:05:05 +0200 Subject: [PATCH] add example code for a telnet echo server (still WIP) --- examples/telnet_echo/Makefile | 4 + examples/telnet_echo/telnet_echo.c | 167 +++++++++++++++++++++++++++++ 2 files changed, 171 insertions(+) create mode 100644 examples/telnet_echo/Makefile create mode 100644 examples/telnet_echo/telnet_echo.c diff --git a/examples/telnet_echo/Makefile b/examples/telnet_echo/Makefile new file mode 100644 index 0000000..9d1da9d --- /dev/null +++ b/examples/telnet_echo/Makefile @@ -0,0 +1,4 @@ +# Makefile for access_point example +PROGRAM=telnet_echo + +include ../../common.mk diff --git a/examples/telnet_echo/telnet_echo.c b/examples/telnet_echo/telnet_echo.c new file mode 100644 index 0000000..5c0d6b0 --- /dev/null +++ b/examples/telnet_echo/telnet_echo.c @@ -0,0 +1,167 @@ +/** + * Very basic example showing usage of netconn data receive echo over telnet. + * the connection. + * + * This example code is in the public domain. + */ +#include + +#include +#include +#include +#include +#include + +#include + +#include + +#define TELNET_PORT 23 +#define ECHO_PREFIX "\r\nYou entered: " +#define ECHO_POSTFIX "\r\n" +#define INPUT_ERROR "\r\nERROR: input line too long - try again.\r\n" +#define BYE "\r\nBYE\r\n" + +static void telnetTask(void *pvParameters); + +static void heartbeatTask(void *pvParameters){ + while(1){ + vTaskDelay(1000 / portTICK_PERIOD_MS); + printf("Uptime %d seconds\r\n", xTaskGetTickCount() * portTICK_PERIOD_MS / 1000); + } +} + +void user_init(void) +{ + uart_set_baud(0, 115200); + printf("SDK version:%s\n", sdk_system_get_sdk_version()); + + struct sdk_station_config config = { + .ssid = WIFI_SSID, + .password = WIFI_PASS, + }; + + sdk_wifi_set_opmode(STATION_MODE); + sdk_wifi_station_set_config(&config); + sdk_wifi_station_connect(); + + xTaskCreate(telnetTask, "telnetTask", 512, NULL, 2, NULL); + xTaskCreate(heartbeatTask, "heardbeatTask", 512, NULL, 2, NULL); +} + +/* Telnet task listens on port 23, returns some status information and then closes + the connection if you connect to it. + */ +static void telnetTask(void *pvParameters) +{ + struct netconn *nc = netconn_new(NETCONN_TCP); + if (!nc) + { + printf("Status monitor: Failed to allocate socket.\r\n"); + return; + } + netconn_bind(nc, IP_ANY_TYPE, TELNET_PORT); + netconn_listen(nc); + + while (1) + { + struct netconn *client = NULL; +#ifdef DEBUG + printf("waiting for new connection\n"); +#endif + err_t err = netconn_accept(nc, &client); + + if (err != ERR_OK) + { + if (client){ + netconn_delete(client); + } + continue; + } + + ip_addr_t client_addr; + uint16_t port_ignore; + netconn_peer(client, &client_addr, &port_ignore); + // TODO check return codes + char buf[80]; + snprintf(buf, sizeof(buf), "Uptime %d seconds\r\n", xTaskGetTickCount() * portTICK_PERIOD_MS / 1000); + netconn_write(client, buf, strlen(buf), NETCONN_COPY); + snprintf(buf, sizeof(buf), "Free heap %d bytes\r\n", (int) xPortGetFreeHeapSize()); + netconn_write(client, buf, strlen(buf), NETCONN_COPY); + char abuf[40]; + snprintf(buf, sizeof(buf), "Your address is %s\r\n\r\n", ipaddr_ntoa_r(&client_addr, abuf, sizeof(abuf))); + netconn_write(client, buf, strlen(buf), NETCONN_COPY); + + char input_line[160] = {'\0'}; + size_t buffer_pos = 0; + while(err == ERR_OK) + { + struct netbuf *nb; + if ((err = netconn_recv(client, &nb)) == ERR_OK) { + char *data_in = NULL; + uint16_t data_len = 0; + err = netbuf_data(nb, (void*)&data_in, &data_len); + + if(err != ERR_OK){ + if(nb != NULL){ + netbuf_delete(nb); + } + break; + } +#ifdef DEBUG + printf("input[%d]: %s\n", data_len, data_in); +#endif + // check for termination request + if((data_len == 1 && data_in[0] == 0x04) || (data_len == 2 && data_in[0] == 0xFF && data_in[1] == 0xEC)){ +#ifdef DEBUG + printf("exit requested\n"); +#endif + err = netconn_write(client, BYE, strlen(BYE), NETCONN_NOFLAG); + if(nb != NULL){ + netbuf_delete(nb); + } + break; + } + + // check if there's space left in the buffer + if(buffer_pos + data_len < sizeof(input_line)) { + // copy data into input buffer + if(data_len > 0){ + memcpy(&input_line[buffer_pos], (char*)data_in, strlen(data_in)); + buffer_pos += data_len; + // check for line ending + if((data_len >= 2) && + (((data_in[data_len-2] == 0x0D) && (data_in[data_len-1] == 0x00)) + || + ((data_in[data_len-2] == '\r') && (data_in[data_len-1] == '\n')))){ // \r\n +#ifdef DEBUG + printf("got line ending\n"); +#endif + netconn_write(client, ECHO_PREFIX, strlen(ECHO_PREFIX), NETCONN_NOFLAG); + netconn_write(client, input_line, strlen(input_line), NETCONN_COPY); + netconn_write(client, ECHO_POSTFIX, strlen(ECHO_POSTFIX), NETCONN_NOFLAG); + + // set buffer to zero, otherwise we would have to add the null byte by hand + memset(input_line, 0, sizeof(input_line)); + buffer_pos = 0; + } + } + } else { + netconn_write(client, INPUT_ERROR, strlen(INPUT_ERROR), NETCONN_NOFLAG); + memset(input_line, 0, sizeof(input_line)); + buffer_pos = 0; + } + } + if(nb != NULL){ + netbuf_delete(nb); + } + } + memset(input_line, 0, sizeof(input_line)); + buffer_pos = 0; + netconn_close(client); + netconn_delete(client); +#ifdef DEBUG + printf("connection close\n"); +#endif + } +}