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

Revision:
26:09e0dd020900
Parent:
25:48dd18cc147c
Child:
27:22f289beceb8
--- a/main.cpp	Sun Dec 07 00:18:07 2014 +0000
+++ b/main.cpp	Wed Dec 24 13:23:33 2014 +0000
@@ -72,10 +72,6 @@
 Watchdog wdt;
 
 
-void update_digital_outputs(char* buf);
-void update_sending_frame(char* buf);
-
-
 
 /*
 * EEPROM section
@@ -161,9 +157,9 @@
 
 #define RECEIVING_PROTOCOL_LENGTH           58
 #define SENDING_PROTOCOL_LENGTH             39
-#define QUERY_CMD_LENGTH                    6
+#define QUERY_NETWORK_CONFIG_CMD_LENGTH     6
 #define SET_NETWORK_CONFIG_CMD_LENGTH       19
-#define UPDATE_TCP_SERVER_INFO_CMD_LENGTH   12
+#define UPDATE_TCP_SERVER_INFO_COMMAND_LENGTH   12
 
 #define QUERY_DISCOVERY_CMD                 "NNIODS"
 #define QUERY_IP_CMD                        "NNIOIP"
@@ -218,6 +214,15 @@
 Queue<bool, 1> auto_update_queue;
 
 
+
+// Prototypes
+int ethernet_init(void);
+void process_control_command(char* received_buffer, int len);
+void process_config_command(char* received_buffer, int len);
+void update_digital_outputs(char* buf);
+void update_sending_frame(char* buf);
+
+
 /*
 * Threads
 */
@@ -240,118 +245,6 @@
 }
 
 
-/*
-* Ethernet init
-*/
-int ethernet_init(void) {
-    int dhcp_ret, ret;
-    
-    DBG("Start initialising ethernet");
-    
-    // if not configured, try dhcp
-    dhcp_ret = -1;
-    if (configured_ip != DEFAULT_ENABLE_FLAG_VALUE) {
-        DBG("Connecting DHCP server...");
-        dhcp_ret = eth.init(u8mac);
-        if (dhcp_ret == 0)
-            dhcp_ret = eth.connect();
-    }
-    
-    if (dhcp_ret != 0) {
-        DBG("No DHCP, load static IP configuration");
-        ret = eth.init(u8mac, str_ip_addr, str_ip_subnet, str_ip_gateway); // static
-    } else {
-        snprintf(str_ip_addr, 16, "%s", eth.getIPAddress());
-        snprintf(str_ip_subnet, 16, "%s", eth.getNetworkMask());
-        snprintf(str_ip_gateway, 16, "%s", eth.getGateway());
-        ret = 0;
-    }
-
-    if (ret == 0) {
-        DBG("Initialized, MAC: %s", eth.getMACAddress());
-    } else {
-        ERR("Error eth.init() - ret = %d", ret);
-        return -1;
-    }
-
-    ret = eth.connect();
-    if (!ret) {
-        DBG("IP: %s, MASK: %s, GW: %s", eth.getIPAddress(), eth.getNetworkMask(), eth.getGateway());
-    } else {
-        ERR("Error eth.connect() - ret = %d", ret);
-        return -1;
-    }
-    
-    return 0;
-}
-
-
-/*
-* Procedure to process receiving protocol
-*/
-void process_received_net_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';
-            uart.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()
 {
     int n, ret;
@@ -446,7 +339,7 @@
                 if (n > 0) {
                     // got some data, test it
                     DBG("TCP client received %d bytes: %s", n, tcp_receiving_buffer);
-                    process_received_net_data(tcp_receiving_buffer, n);
+                    process_control_command(tcp_receiving_buffer, n);
                 }
             }
         } // if tcp client enabled && auto transmit
@@ -474,7 +367,7 @@
                     
                     // got some data, test it
                     DBG("TCP server received: %s", tcp_receiving_buffer);
-                    process_received_net_data(tcp_receiving_buffer, n);
+                    process_control_command(tcp_receiving_buffer, n);
                 } // end loop if no data received within timeout
             } // if client connected
             tcp_client.close();
@@ -489,134 +382,252 @@
         // check to see if it is a query command
         // if yes, is it a discovery command or an ip query to enter config mode
         config_mode_flag = false;
-        if ((n == QUERY_CMD_LENGTH) && (strstr(udp_receiving_buffer, QUERY_DISCOVERY_CMD) != NULL)) {
+        if ((n == QUERY_NETWORK_CONFIG_CMD_LENGTH) && (strstr(udp_receiving_buffer, QUERY_DISCOVERY_CMD) != NULL)) {
             DBG("Received discovery command");
             char str[50];
             sprintf(str, "%s%s%s", DEVICE_ID, eth.getMACAddress(), eth.getIPAddress());
             udp_server.sendTo(ep_udp_client, str, strlen(str));
         } // NNIODS
-        else if ((n == QUERY_CMD_LENGTH) && (strstr(udp_receiving_buffer, QUERY_IP_CMD) != NULL)) {
+        else if ((n == QUERY_NETWORK_CONFIG_CMD_LENGTH) && (strstr(udp_receiving_buffer, QUERY_IP_CMD) != NULL)) {
             config_mode_flag = true;
             DBG("Enabled configuration mode...");
             DBG("!!! RESET when finished");
-        }
+        } // NNIOIP
         
+        // if received NNIOIP, enter config mode
         if (config_mode_flag) {
-            // if receive any config command, stay in config mode forever
-            while (n > 0) {
+            while (n > 0)
+            {
                 // got some data, test it
                 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
-                // a configuration command always starts with NN
-                if ((udp_receiving_buffer[0] == 'N') && (udp_receiving_buffer[1] == 'N')) {
-                    switch (n) {
-                        // length = 6, a QUERY command (discovery command, TCP port, or UDP port)
-                        // Format: NNIODS, NNIOTP, NNIOUP, NNIOTM
-                        case QUERY_CMD_LENGTH:
-                            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_receiving_buffer, QUERY_SUBNET_CMD) != NULL) {
-                                udp_server.sendTo(ep_udp_client, eth.getNetworkMask(), strlen(eth.getNetworkMask()));
-                            } // NNIOSN
-                            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_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_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_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_receiving_buffer, QUERY_UPDATE_TIME_CMD) != NULL) {
-    #ifdef NTP
-                                char str_time[50];
-                                
-                                DBG("Trying to update time...");
-                                if (ntp.setTime("0.pool.ntp.org") == 0) {
-                                    DBG("Set time successfully");
-                                    time_t ctTime;
-                                    ctTime = time(NULL);
-                                    
-                                    DBG("Time is set to (UTC): %s", ctime(&ctTime));
-                                    sprintf(str_time, "%s", ctime(&ctTime));
-                                    udp_server.sendTo(ep_udp_client, str_time, strlen(str_time));
-                                }
-                                else {
-                                    WARN("Error");
-                                    sprintf(str_time, "ERR");
-                                    udp_server.sendTo(ep_udp_client, str_time, strlen(str_time));
-                                }
-    #elif
-                                WARN("NTP disabled");
-                                sprintf(str_time, "DIS");
-                                udp_server.sendTo(ep_udp_client, str_time, strlen(str_time));
-    #endif
-                            } // NNIOTM
-            
-                            break;
-                        // length = 19, SET NETWORK CONFIGURATION
-                        // Format: 4E 4E 49 4F      C0 A8 00 78        FF FF FF 00            C0 A8 00 01      00 00 01
-                        //        (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_receiving_buffer, DEVICE_ID);
-                            if (id == NULL)
-                                break;
-                            else if ((id - udp_receiving_buffer) > 0)
-                                break;
-            
-                            DBG("Received user configuration");
-                            write_eeprom_network(&udp_receiving_buffer[strlen(DEVICE_ID)]); // parameters from 5th char, 15-bytes
-                            break;
-                        }
-                        // length = 12, SET TCP SERVER CONFIGURATION
-                        // auto update & its time period, TCP server configuration (IP & port)
-                        // 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_receiving_buffer, DEVICE_ID);
-                            if (id == NULL)
-                                break;
-                            else if ((id - udp_receiving_buffer) > 0)
-                                break;
-                            
-                            DBG("Received TCP server configuration");
-                            write_eeprom_tcpserver(&udp_receiving_buffer[strlen(DEVICE_ID)]); // parameters from 5th char
-                            break;
-                        }
-                        default:
-                            break;
-                    } // switch (n), check configuration command length
-                } // if starts with NN, a config command
-                else { // if not a command, check to see if it is a 6-byte data package
-                    // process 6-byte data package
-                }
-                
+                process_config_command(udp_receiving_buffer, n);
                 // wait to receive new config command
                 udp_server.set_blocking(true);
                 n = udp_server.receiveFrom(ep_udp_client, udp_receiving_buffer, sizeof(udp_receiving_buffer));
-            } // while (n > 0): config commands processor
+            } // while (n > 0), config loop
         } // if (config_mode_flag)
-        else if (n > 0) { // process other data packages sent using UDP
-            process_received_net_data(udp_receiving_buffer, n);
+        else if (n > 0) { // process control packages sent using UDP
+            process_control_command(udp_receiving_buffer, n);
         }
 #endif
     } // network processor
 }
 
+
+void process_config_command(char* received_buffer, int len)
+{
+    // process received data
+    // a configuration command always starts with NN
+    if ((received_buffer[0] == 'N') && (received_buffer[1] == 'N')) {
+        switch (len) {
+            // length = 6, a QUERY command (discovery command, TCP port, or UDP port)
+            // Format: NNIODS, NNIOTP, NNIOUP, NNIOTM
+            case QUERY_NETWORK_CONFIG_CMD_LENGTH:
+                if (strstr(received_buffer, QUERY_IP_CMD) != NULL) {
+                    udp_server.sendTo(ep_udp_client, eth.getIPAddress(), strlen(eth.getIPAddress()));
+                } // NNIOIP
+                else if (strstr(received_buffer, QUERY_SUBNET_CMD) != NULL) {
+                    udp_server.sendTo(ep_udp_client, eth.getNetworkMask(), strlen(eth.getNetworkMask()));
+                } // NNIOSN
+                else if (strstr(received_buffer, QUERY_GATEWAY_CMD) != NULL) {
+                    udp_server.sendTo(ep_udp_client, eth.getGateway(), strlen(eth.getGateway()));
+                } // NNIOGW
+                else if (strstr(received_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(received_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(received_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(received_buffer, QUERY_UPDATE_TIME_CMD) != NULL) {
+#ifdef NTP
+                    char str_time[50];
+
+                    DBG("Trying to update time...");
+                    if (ntp.setTime("0.pool.ntp.org") == 0) {
+                        DBG("Set time successfully");
+                        time_t ctTime;
+                        ctTime = time(NULL);
+
+                        DBG("Time is set to (UTC): %s", ctime(&ctTime));
+                        sprintf(str_time, "%s", ctime(&ctTime));
+                        udp_server.sendTo(ep_udp_client, str_time, strlen(str_time));
+                    } else {
+                        WARN("Error");
+                        sprintf(str_time, "ERR");
+                        udp_server.sendTo(ep_udp_client, str_time, strlen(str_time));
+                    }
+#elif
+                    WARN("NTP disabled");
+                    sprintf(str_time, "DIS");
+                    udp_server.sendTo(ep_udp_client, str_time, strlen(str_time));
+#endif
+                } // NNIOTM
+
+                break;
+                // length = 19, SET NETWORK CONFIGURATION
+                // Format: 4E 4E 49 4F      C0 A8 00 78        FF FF FF 00            C0 A8 00 01      00 00 01
+                //        (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(received_buffer, DEVICE_ID);
+                if (id == NULL)
+                    break;
+                else if ((id - received_buffer) > 0)
+                    break;
+
+                DBG("Received user configuration");
+                write_eeprom_network(&received_buffer[strlen(DEVICE_ID)]); // parameters from 5th char, 15-bytes
+                break;
+            }
+            // length = 12, SET TCP SERVER CONFIGURATION
+            // auto update & its time period, TCP server configuration (IP & port)
+            // 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_COMMAND_LENGTH: {
+                char* id = strstr(received_buffer, DEVICE_ID);
+                if (id == NULL)
+                    break;
+                else if ((id - received_buffer) > 0)
+                    break;
+
+                DBG("Received TCP server configuration");
+                write_eeprom_tcpserver(&received_buffer[strlen(DEVICE_ID)]); // parameters from 5th char
+                break;
+            }
+            default:
+                break;
+        } // switch (n), check configuration command length
+    } // if starts with NN, a config command
+    else { // if not a command, check to see if it is a 6-byte data package
+        // process 6-byte data package
+    }
+}
+
 /*
-* Update digital outputs following receiving frame from TCP client
+* Procedure to process receiving protocol, which includes command to control outputs
+*/
+void process_control_command(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");
+            //TODO Update analog output
+        }
+        // analog output 1
+        if (received_buffer[RECEIVING_PROTOCOL_EN_A1O_POS] == RECEIVING_PROTOCOL_ENABLE_OUTPUT) {
+            DBG("Update analog output 1");
+            //TODO Update analog output
+        }
+        // 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';
+            uart.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");
+}
+
+
+/*
+* W5500 Ethernet init
+*/
+int ethernet_init(void) {
+    int dhcp_ret, ret;
+    
+    DBG("Start initialising ethernet");
+    
+    // if not configured, try dhcp
+    dhcp_ret = -1;
+    if (configured_ip != DEFAULT_ENABLE_FLAG_VALUE) {
+        DBG("Connecting DHCP server...");
+        dhcp_ret = eth.init(u8mac);
+        if (dhcp_ret == 0)
+            dhcp_ret = eth.connect();
+    }
+    
+    if (dhcp_ret != 0) {
+        DBG("No DHCP, load static IP configuration");
+        ret = eth.init(u8mac, str_ip_addr, str_ip_subnet, str_ip_gateway); // static
+    } else {
+        snprintf(str_ip_addr, 16, "%s", eth.getIPAddress());
+        snprintf(str_ip_subnet, 16, "%s", eth.getNetworkMask());
+        snprintf(str_ip_gateway, 16, "%s", eth.getGateway());
+        ret = 0;
+    }
+
+    if (ret == 0) {
+        DBG("Initialized, MAC: %s", eth.getMACAddress());
+    } else {
+        ERR("Error eth.init() - ret = %d", ret);
+        return -1;
+    }
+
+    ret = eth.connect();
+    if (!ret) {
+        DBG("IP: %s, MASK: %s, GW: %s", eth.getIPAddress(), eth.getNetworkMask(), eth.getGateway());
+    } else {
+        ERR("Error eth.connect() - ret = %d", ret);
+        return -1;
+    }
+    
+    return 0;
+}
+
+
+/*
+* Update digital outputs according to receiving protocol
 */
 void update_digital_outputs(char* buf) {
     DBG("Digital outputs: %s", buf);
@@ -631,6 +642,9 @@
     dout7 = (buf[7] == DIGITAL_HIGH)? 1 : 0;
 }
 
+/*
+* Prepare a frame for sending protocol, which includes status of I/Os
+*/
 void update_sending_frame(char* buf) {
     memcpy(&buf[SENDING_PROTOCOL_ID_POS], DEVICE_ID, 4); // device id
     memcpy(&buf[SENDING_PROTOCOL_MAC_POS], &u8mac, 6);