Webserver only w/o any other functions, single thread. Running on STM32F013+W5500

Dependencies:   NTPClient W5500Interface Watchdog device_configuration eeprom_flash mbed-rpc-nucleo mbed-rtos mbed

Fork of F103-Serial-to-Ethernet by Chau Vo

Files at this revision

API Documentation at this revision

Comitter:
olympux
Date:
Sat Oct 25 10:47:05 2014 +0000
Parent:
18:ca499a2e7da6
Child:
20:71c7950fdd91
Commit message:
1. Added processing many frames in one tcp packet.; 2. Separate process tcp packet received in a function.

Changed in this revision

main.cpp Show annotated file Show diff for this revision Revisions of this file
my_eeprom_funcs.lib Show annotated file Show diff for this revision Revisions of this file
readme.txt Show annotated file Show diff for this revision Revisions of this file
--- a/main.cpp	Tue Oct 21 20:39:15 2014 +0000
+++ b/main.cpp	Sat Oct 25 10:47:05 2014 +0000
@@ -106,7 +106,8 @@
 #define NTP
 
 #define TCP_SERVER_WAIT_CLIENT_TIMEOUT     200
-#define TCP_SERVER_RECEIVE_TIMEOUT         3000
+#define TCP_SERVER_RECEIVE_TIMEOUT         2000
+#define TCP_CLIENT_RECEIVE_TIMEOUT         100
 #define UDP_SERVER_RECEIVE_TIMEOUT         200
 
 
@@ -143,9 +144,9 @@
 uint16_t u16tcp_server_port; // directly loaded from eeprom
 uint16_t u16enable_tcp_client, u16enable_tcp_server;// flags for enabling TCP client or TCP server
 
-char tcp_client_buffer[256]; // socket buffer
-char udp_server_buffer[256];
-char tcp_server_buffer[256];
+char tcp_receiving_buffer[256];
+char tcp_sending_buffer[256]; // socket buffer
+char udp_receiving_buffer[256];
 
 
 /*
@@ -272,7 +273,70 @@
 }
 
 
-
+/*
+* Procedure to process receiving protocol
+*/
+void process_received_tcp_data(char* received_buffer, int len)
+{
+    char* received_frame;
+    int pos;
+    
+    while (len >= RECEIVING_PROTOCOL_LENGTH) {
+        // find device ID
+        DBG("Checking device ID...");
+        char* id = strstr(received_buffer, DEVICE_ID);
+        if (id == NULL) {
+            DBG("No device ID found");
+            break;
+        }
+        pos = id - received_buffer;
+        DBG("Found a frame at %d", pos);
+        
+        // extract this frame
+        received_frame = &received_buffer[pos];
+        // calculate the rest
+        received_buffer = &received_buffer[pos + RECEIVING_PROTOCOL_LENGTH];
+        len -= RECEIVING_PROTOCOL_LENGTH;
+        
+        // process this received frame
+        // firstly, update outputs if required
+        // digital outputs
+        if (received_frame[RECEIVING_PROTOCOL_EN_DO_POS] == RECEIVING_PROTOCOL_ENABLE_OUTPUT) {
+            DBG("Update digital outputs");
+            char str_dout[9];
+            memcpy(str_dout, &received_frame[RECEIVING_PROTOCOL_DO_POS], 8);
+            str_dout[8] = '\0';
+            update_digital_outputs(str_dout);
+        }
+        // analog output 0
+        if (received_frame[RECEIVING_PROTOCOL_EN_A0O_POS] == RECEIVING_PROTOCOL_ENABLE_OUTPUT) {
+            DBG("Update analog output 0");
+        }
+        // analog output 1
+        if (received_buffer[RECEIVING_PROTOCOL_EN_A1O_POS] == RECEIVING_PROTOCOL_ENABLE_OUTPUT) {
+            DBG("Update analog output 1");
+        }
+        // UART
+        if (received_frame[RECEIVING_PROTOCOL_EN_UART_POS] == RECEIVING_PROTOCOL_ENABLE_OUTPUT) {
+            DBG("UART data: ");
+            char str_uart[33];
+            memcpy(str_uart, &received_frame[RECEIVING_PROTOCOL_UART_POS], 32);
+            str_uart[32] = '\0';
+            printf("%s\r\n", str_uart);
+        }
+                            
+        // then, check query status command and sending protocol if required
+        if (received_frame[RECEIVING_PROTOCOL_COMMAND_POS] == QUERY_STATUS_COMMAND) {
+            DBG("Requested to send device status through TCP");
+            // sending protocol
+            update_sending_frame(tcp_sending_buffer);
+            tcp_client.send_all(tcp_sending_buffer, SENDING_PROTOCOL_LENGTH);
+            DBG("Sent");
+        }
+    }
+    
+    DBG("Successful");
+}
 
 
 int main()
@@ -332,7 +396,7 @@
 
 
     /*
-    * Network processor
+    * Network loop processor
     */
     while (true) {
 #ifdef TCP_CLIENT
@@ -355,8 +419,17 @@
                 osEvent evt = auto_update_queue.get(1); // timeout after 1ms
                 if (evt.status == osEventMessage) {
                     DBG("Updating...");
-                    update_sending_frame(tcp_client_buffer);
-                    tcp_sock.send_all(tcp_client_buffer, SENDING_PROTOCOL_LENGTH);
+                    update_sending_frame(tcp_sending_buffer);
+                    tcp_sock.send_all(tcp_sending_buffer, SENDING_PROTOCOL_LENGTH);
+                }
+                
+                // check to receive or timeout
+                tcp_sock.set_blocking(false, TCP_CLIENT_RECEIVE_TIMEOUT);
+                n = tcp_sock.receive(tcp_receiving_buffer, sizeof(tcp_receiving_buffer));
+                if (n > 0) {
+                    // got some data, test it
+                    DBG("TCP client received %d bytes: %s", n, tcp_receiving_buffer);
+                    process_received_tcp_data(tcp_receiving_buffer, n);
                 }
             }
         } // if tcp client enabled && auto transmit
@@ -378,63 +451,12 @@
                 // loop waiting and receiving data within timeout
                 tcp_client.set_blocking(false, TCP_SERVER_RECEIVE_TIMEOUT); // Timeout after x seconds
                 while (true) {
-                    n = tcp_client.receive(tcp_server_buffer, sizeof(tcp_server_buffer));
+                    n = tcp_client.receive(tcp_receiving_buffer, sizeof(tcp_receiving_buffer));
                     if (n <= 0) break;
                     
                     // got some data, test it
-                    DBG("TCP server received: %s", tcp_server_buffer);
-                    // process received data
-                    switch (n) {
-                        // length 58-bytes, Receiving protocol
-                        case RECEIVING_PROTOCOL_LENGTH: {
-                            DBG("Checking device ID...");
-                            // check device id
-                            char* id = strstr(tcp_server_buffer, DEVICE_ID);
-                            if (id == NULL)
-                                break;
-                            else if ((id - tcp_server_buffer) > 0)
-                                break;
-                            DBG("Correct.");
-                            
-                            // firstly, update outputs if required
-                            // digital outputs
-                            if (tcp_server_buffer[RECEIVING_PROTOCOL_EN_DO_POS] == RECEIVING_PROTOCOL_ENABLE_OUTPUT) {
-                                DBG("Update digital outputs");
-                                char str_dout[9];
-                                memcpy(str_dout, &tcp_server_buffer[RECEIVING_PROTOCOL_DO_POS], 8);
-                                str_dout[8] = '\0';
-                                update_digital_outputs(str_dout);
-                            }
-                            // analog output 0
-                            if (tcp_server_buffer[RECEIVING_PROTOCOL_EN_A0O_POS] == RECEIVING_PROTOCOL_ENABLE_OUTPUT) {
-                                DBG("Update analog output 0");
-                            }
-                            // analog output 1
-                            if (tcp_server_buffer[RECEIVING_PROTOCOL_EN_A1O_POS] == RECEIVING_PROTOCOL_ENABLE_OUTPUT) {
-                                DBG("Update analog output 1");
-                            }
-                            // UART
-                            if (tcp_server_buffer[RECEIVING_PROTOCOL_EN_UART_POS] == RECEIVING_PROTOCOL_ENABLE_OUTPUT) {
-                                DBG("UART data: ");
-                                char str_uart[33];
-                                memcpy(str_uart, &tcp_server_buffer[RECEIVING_PROTOCOL_UART_POS], 32);
-                                str_uart[32] = '\0';
-                                printf("%s\r\n", str_uart);
-                            }
-                            
-                            // then, check query status command and sending protocol if required
-                            if (tcp_server_buffer[RECEIVING_PROTOCOL_COMMAND_POS] == QUERY_STATUS_COMMAND) {
-                                DBG("Sent device status through TCP");
-                                // sending protocol
-                                update_sending_frame(tcp_server_buffer);
-                                tcp_client.send_all(tcp_server_buffer, SENDING_PROTOCOL_LENGTH);
-                            }
-                            
-                            break;
-                        }
-                        default:
-                            break;
-                    }
+                    DBG("TCP server received: %s", tcp_receiving_buffer);
+                    process_received_tcp_data(tcp_receiving_buffer, n);
                 } // end loop if no data received within timeout
                 tcp_client.close();
             } // if client connected
@@ -446,47 +468,47 @@
 // ALWAYS ENABLED, ONLY FOR CONFIGRATION
 #ifdef UDP_SERVER
         // wait for udp packet within timeout
-        n = udp_server.receiveFrom(ep_udp_client, udp_server_buffer, sizeof(udp_server_buffer));
+        n = udp_server.receiveFrom(ep_udp_client, udp_receiving_buffer, sizeof(udp_receiving_buffer));
         if (n <= 0) continue;
 
         // got some data, test it
-        DBG("UDP received (%s) from (%s) and port (%d)", udp_server_buffer, ep_udp_client.get_address(), ep_udp_client.get_port());
+        DBG("UDP received (%s) from (%s) and port (%d)", udp_receiving_buffer, ep_udp_client.get_address(), ep_udp_client.get_port());
         // process received data
         switch (n) {
             // length = 6, a QUERY command (discovery command, TCP port, or UDP port)
             // Format: NNIODS, NNIOTP, NNIOUP, NNIOTM
             case QUERY_CMD_LENGTH:
                 // discovery command
-                if (strstr(udp_server_buffer, QUERY_DISCOVERY_CMD) != NULL) {
+                if (strstr(udp_receiving_buffer, QUERY_DISCOVERY_CMD) != NULL) {
                     char str[30];
                     sprintf(str, "%s%s", DEVICE_ID, eth.getIPAddress());
                     udp_server.sendTo(ep_udp_client, str, strlen(str));
                 } // NNIODS
-                else if (strstr(udp_server_buffer, QUERY_IP_CMD) != NULL) {
+                else if (strstr(udp_receiving_buffer, QUERY_IP_CMD) != NULL) {
                     udp_server.sendTo(ep_udp_client, eth.getIPAddress(), strlen(eth.getIPAddress()));
                 } // NNIOIP
-                else if (strstr(udp_server_buffer, QUERY_SUBNET_CMD) != NULL) {
+                else if (strstr(udp_receiving_buffer, QUERY_SUBNET_CMD) != NULL) {
                     udp_server.sendTo(ep_udp_client, eth.getNetworkMask(), strlen(eth.getNetworkMask()));
                 } // NNIOSN
-                else if (strstr(udp_server_buffer, QUERY_GATEWAY_CMD) != NULL) {
+                else if (strstr(udp_receiving_buffer, QUERY_GATEWAY_CMD) != NULL) {
                     udp_server.sendTo(ep_udp_client, eth.getGateway(), strlen(eth.getGateway()));
                 } // NNIOGW
-                else if (strstr(udp_server_buffer, QUERY_MAC_CMD) != NULL) {
+                else if (strstr(udp_receiving_buffer, QUERY_MAC_CMD) != NULL) {
                     udp_server.sendTo(ep_udp_client, eth.getMACAddress(), strlen(eth.getMACAddress()));
                 } // NNIOMC
                 // ask for TCP server port
-                else if (strstr(udp_server_buffer, QUERY_TCP_PORT_CMD) != NULL) {
+                else if (strstr(udp_receiving_buffer, QUERY_TCP_PORT_CMD) != NULL) {
                     char port[5];
                     sprintf(port, "%5d", tcp_server_local_port);
                     udp_server.sendTo(ep_udp_client, port, strlen(port));
                 } // NNIOTP
                 // ask for UDP server port
-                else if (strstr(udp_server_buffer, QUERY_UDP_PORT_CMD) != NULL) {
+                else if (strstr(udp_receiving_buffer, QUERY_UDP_PORT_CMD) != NULL) {
                     char port[5];
                     sprintf(port, "%5d", udp_server_local_port);
                     udp_server.sendTo(ep_udp_client, port, strlen(port));
                 } // NNIOUP
-                else if (strstr(udp_server_buffer, QUERY_UPDATE_TIME_CMD) != NULL) {
+                else if (strstr(udp_receiving_buffer, QUERY_UPDATE_TIME_CMD) != NULL) {
 #ifdef NTP
                     char str_time[50];
                     
@@ -518,14 +540,14 @@
             //        (NNIO;            IP: 192.168.0.120; Subnet: 255.255.255.0; GW: 192.168.0.1; MAC: 0 0 1)
             case SET_NETWORK_CONFIG_CMD_LENGTH: {
                 // check device id
-                char* id = strstr(udp_server_buffer, DEVICE_ID);
+                char* id = strstr(udp_receiving_buffer, DEVICE_ID);
                 if (id == NULL)
                     break;
-                else if ((id - udp_server_buffer) > 0)
+                else if ((id - udp_receiving_buffer) > 0)
                     break;
 
                 DBG("Received user configuration");
-                write_eeprom_network(&udp_server_buffer[strlen(DEVICE_ID)]); // parameters from 5th char, 15-bytes
+                write_eeprom_network(&udp_receiving_buffer[strlen(DEVICE_ID)]); // parameters from 5th char, 15-bytes
                 break;
             }
             // length = 12, SET TCP SERVER CONFIGURATION
@@ -533,14 +555,14 @@
             // Format: 4E 4E 49 4F   'Y'     01   C0 A8 00 09   E0 2E (LSB MSB)
             //         NNIO          Auto   1s   192.168.0.9   12000
             case UPDATE_TCP_SERVER_INFO_CMD_LENGTH: {
-                char* id = strstr(udp_server_buffer, DEVICE_ID);
+                char* id = strstr(udp_receiving_buffer, DEVICE_ID);
                 if (id == NULL)
                     break;
-                else if ((id - udp_server_buffer) > 0)
+                else if ((id - udp_receiving_buffer) > 0)
                     break;
                 
                 DBG("Received TCP server configuration");
-                write_eeprom_tcpserver(&udp_server_buffer[strlen(DEVICE_ID)]); // parameters from 5th char
+                write_eeprom_tcpserver(&udp_receiving_buffer[strlen(DEVICE_ID)]); // parameters from 5th char
                 break;
             }
             default:
--- a/my_eeprom_funcs.lib	Tue Oct 21 20:39:15 2014 +0000
+++ b/my_eeprom_funcs.lib	Sat Oct 25 10:47:05 2014 +0000
@@ -1,1 +1,1 @@
-http://mbed.org/users/olympux/code/my_eeprom_funcs/#eea03d0eb95a
+http://mbed.org/users/olympux/code/my_eeprom_funcs/#241d1539914a
--- a/readme.txt	Tue Oct 21 20:39:15 2014 +0000
+++ b/readme.txt	Sat Oct 25 10:47:05 2014 +0000
@@ -1,4 +1,10 @@
+Features
 0. Wait for 2s after resetting for ethernet to work.
 1. When auto update enabled and no TCP server is running, module will try to connect to server which results in a timeout every 15s.
    This makes UDP packets take more time to be received and processed by the module. The result is slow UDP commands, such as Discovery.
-   To make it faster, start a TCP server on Hercules. The module will connect to it to transmit updates.
\ No newline at end of file
+   To make it faster, start a TCP server on Hercules. The module will connect to it to transmit updates.
+2. Process a tcp packet including many receiving frames
+
+
+v1.0 25/10/2014
+    + Added: process many receiving frames in one tcp packet