TCP-Server-sample

Files at this revision

API Documentation at this revision

Comitter:
YSI
Date:
Thu Apr 08 12:39:50 2021 +0000
Child:
1:263b4d8f37b9
Commit message:
TCP-Server-sample

Changed in this revision

.gitignore Show annotated file Show diff for this revision Revisions of this file
main.cpp Show annotated file Show diff for this revision Revisions of this file
main.h Show annotated file Show diff for this revision Revisions of this file
mbed-os.lib Show annotated file Show diff for this revision Revisions of this file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/.gitignore	Thu Apr 08 12:39:50 2021 +0000
@@ -0,0 +1,4 @@
+.build
+.mbed
+projectfiles
+*.py*
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/main.cpp	Thu Apr 08 12:39:50 2021 +0000
@@ -0,0 +1,139 @@
+#include "main.h"
+
+int main()
+{
+    Led = eth_status;
+    queue = mbed_event_queue();
+    while(1) if(eth_connect()) Led = recv();
+}
+
+bool eth_connect(void)
+{
+    switch(eth.get_connection_status())
+    {
+        case NSAPI_STATUS_DISCONNECTED:
+            eth.set_blocking(false);
+            eth.set_network(SocketAddress(IP_SERVER), SocketAddress("255.255.255.0"), SocketAddress("192.168.1.1")); // if not static eth.set_dhcp(true);
+            eth.attach(callback(&eth_event));
+            eth.connect();                              break;
+        case NSAPI_STATUS_GLOBAL_UP: return CONNECT;    break;
+        default:                                        break;
+    }
+    return false;
+}
+
+void eth_event(nsapi_event_t status, intptr_t param)
+{
+    switch(param)
+    {
+        case NSAPI_STATUS_DISCONNECTED: eth_status = RED_DISCONNECTED;  break;
+        case NSAPI_STATUS_CONNECTING:if(eth_status == BLUE_CLIENT) clientTCP->close();
+                                        eth_status = YELLOW_CONNECTING; break;
+        case NSAPI_STATUS_GLOBAL_UP:    eth_status = GREEN_GLOBAL_UP;
+                                        if(!CONNECT) serverTCP_connect();
+                                        else         serverTCP_event(); break;
+        default:                                                        break;
+    }
+}
+
+void eth_state(void)
+{
+    switch(eth.get_connection_status())
+    {
+        case NSAPI_STATUS_DISCONNECTED: eth_status = RED_DISCONNECTED;  break;
+        case NSAPI_STATUS_CONNECTING:   eth_status = YELLOW_CONNECTING; break;
+        case NSAPI_STATUS_GLOBAL_UP:    eth_status = GREEN_GLOBAL_UP;   break;
+        default:                                                        break;
+    }
+}
+
+bool serverTCP_connect(void)
+{
+    if(!CONNECT)
+        if(serverTCP.open(&eth) == NSAPI_ERROR_OK)
+            if(serverTCP.bind(PORT_SERVER) == NSAPI_ERROR_OK)
+                if(serverTCP.listen() == NSAPI_ERROR_OK)
+                {
+                    serverTCP.set_blocking(false);
+                    serverTCP.sigio(callback(&serverTCP_event));
+                    CONNECT = true;
+                }
+    return CONNECT;
+}
+
+void serverTCP_event(void)
+{
+    queue->call(&serverTCP_accept);
+}
+
+void serverTCP_accept(void)
+{
+    if(eth_status == GREEN_GLOBAL_UP)
+    {
+        nsapi_error_t ack = NSAPI_ERROR_WOULD_BLOCK;
+        eth_status = MAGENTA_ACCEPT;
+        clientTCP = serverTCP.accept(&ack);
+        switch(ack)
+        {
+            case NSAPI_ERROR_OK:
+                clientTCP->set_timeout(TIMEOUT_SERVER);   // config client bloquante avec timeout sinon limite de transmission a 1072 octets
+                eth_status = BLUE_CLIENT;
+            break;
+            case NSAPI_ERROR_NO_CONNECTION:
+                eth_state();
+                serverTCP_event();
+            break;
+            default:
+                eth_state();
+            break;
+        }
+    }
+}
+
+enum_status recv(void)
+{
+    if(eth_connect() && (eth_status == BLUE_CLIENT))
+    {
+        char buffer[BUFFER_SIZE] = {0};
+        nsapi_error_t ack = NSAPI_ERROR_WOULD_BLOCK, size = 0;
+        while((ack = clientTCP->recv(&buffer[size], BUFFER_SIZE-size)) > NSAPI_ERROR_OK) size += ack;
+        if(!size && (ack == NSAPI_ERROR_OK) || (ack == NSAPI_ERROR_NO_CONNECTION))
+        {
+            clientTCP->close();
+            eth_state();
+            serverTCP_event();
+        }
+        if(size)
+        {
+            string cmd(buffer);
+            for(char &c : cmd) if((c >= 'a') && (c <= 'z')) c += 'A'-'a';
+            if(!cmd.empty())
+            {
+                ostringstream ssend;
+                if(cmd.find("GET / HTTP") != string::npos)
+                {
+                    ssend << "HTTP/1.1 200 OK\r\nContent-Type: text/html; charset=utf-8\r\nAccess-Control-Allow-Origin: *\r\n\r\n";
+                    ssend << "<!DOCTYPE html>\r\n<html>\r\n\t<head>\r\n\t\t<title>" << MBED_PROJECT << "</title>\r\n\t\t<meta http-equiv=refresh content=10>\r\n\t</head>";
+                    ssend << "\r\n\t<body style=background-color:dimgray>\r\n\t\t<center>\r\n\t\t\t<h1>" << MBED_PROJECT << "</h1>\r\n\t\t</center>\r\n\t</body>\r\n</html>";
+                }
+                else ssend << "HTTP/1.1 204 No Content\r\n";
+                send(ssend.str());
+            }
+        }
+    }
+    return eth_status;
+}
+
+nsapi_error_t send(const string& buff)
+{
+    nsapi_error_t ack = NSAPI_ERROR_WOULD_BLOCK;
+    string ssend(buff+"\n");
+    if((eth_status == BLUE_CLIENT) && !buff.empty())
+        ack = clientTCP->send(ssend.c_str(), ssend.size());
+    //------------------- HTTP request must close
+    clientTCP->close();
+    eth_state();
+    serverTCP_event();
+    //-------------------
+    return ack;
+}
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/main.h	Thu Apr 08 12:39:50 2021 +0000
@@ -0,0 +1,35 @@
+#ifndef MAIN_H
+#define MAIN_H
+
+#define MBED_PROJECT    "TCP-sample"
+#define IP_SERVER       "192.168.1.25"
+#define PORT_SERVER     80
+#define TIMEOUT_SERVER  100
+#define BUFFER_SIZE     1072
+
+#include "mbed.h"
+#include "EthernetInterface.h"
+#include <sstream>
+
+EthernetInterface   eth;
+TCPSocket           serverTCP, *clientTCP;
+EventQueue          *queue = NULL;
+BusOut              Led(LED1, LED2, LED3);
+UnbufferedSerial    pc(USBTX, USBRX, 230400);
+
+bool CONNECT = false;
+
+enum enum_status { WHITE, CYAN, MAGENTA_ACCEPT, BLUE_CLIENT, YELLOW_CONNECTING, GREEN_GLOBAL_UP, RED_DISCONNECTED, BLACK_INITIALIZE }
+    eth_status = RED_DISCONNECTED;
+
+bool            eth_connect(void);
+void            eth_event(nsapi_event_t, intptr_t);
+void            eth_state(void);
+
+bool            serverTCP_connect(void);
+void            serverTCP_event(void);
+void            serverTCP_accept(void);
+
+enum_status     recv(void);
+nsapi_error_t   send(const string& buff);
+#endif
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/mbed-os.lib	Thu Apr 08 12:39:50 2021 +0000
@@ -0,0 +1,1 @@
+https://github.com/ARMmbed/mbed-os/#c73413893fb98aaaeda74513c981ac68adc8645d