Chau Vo / Mbed 2 deprecated F103-Web-Server

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

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

Revision:
31:2e4b6de6c2f3
Parent:
30:15e23257e786
Child:
32:db2e8ea06ee1
--- a/main.cpp	Sun Jan 11 13:53:53 2015 +0000
+++ b/main.cpp	Sat Jan 24 20:49:24 2015 +0000
@@ -14,20 +14,20 @@
 #include "Watchdog.h"
 
 
-//Debug is disabled by default
+/** Debug option
+ *
+ */
 #if 1
 //Enable debug
 #include <cstdio>
-#define DBG(x, ...) std::printf("[main : DBG]"x"\r\n", ##__VA_ARGS__); 
-#define WARN(x, ...) std::printf("[main : WARN]"x"\r\n", ##__VA_ARGS__); 
-#define ERR(x, ...) std::printf("[main : ERR]"x"\r\n", ##__VA_ARGS__); 
-
+#define DBG(x, ...) std::printf("[main : DBG]"x"\r\n", ##__VA_ARGS__);
+#define WARN(x, ...) std::printf("[main : WARN]"x"\r\n", ##__VA_ARGS__);
+#define ERR(x, ...) std::printf("[main : ERR]"x"\r\n", ##__VA_ARGS__);
 #else
 //Disable debug
-#define DBG(x, ...) 
+#define DBG(x, ...)
 #define WARN(x, ...)
-#define ERR(x, ...) 
-
+#define ERR(x, ...)
 #endif
 
 
@@ -49,18 +49,18 @@
                                      0x5212, // UDP server port, not used
                                      0x8888, // 1st run? 0xA5A5 = configured
                                      0x6212, 0x6313, 0x6414, // MAC
-                                     
+
                                      // this section is for the TCP server that this device connects to in TCP client mode
                                      0x7212, 0x7313, // 0xA5A5 = auto transmit status, time period
                                      0x8212, 0x8313,0x8414, 0x8515, // TCP server IP address
                                      0x9212, // TCP server port
-                                     
+
                                      // this section is for selecting protocol, not used
                                      0xA212, // 0xA5A5 = enable TCP server
                                      0xA313, // 0xA5A5 = eanble TCP client
                                      0xA414  // 0xA5A5 = enable UDP server
-                                     };
-                                     
+                                    };
+
 
 /*
 * Network configuration
@@ -110,11 +110,9 @@
 uint16_t u16enable_tcp_client, u16enable_tcp_server;// flags for enabling TCP client or TCP server
 
 #define NET_BUF_LEN         256
-#define RPC_BUF_LEN         256
 char tcp_receiving_buffer[NET_BUF_LEN];
-char tcp_sending_buffer[NET_BUF_LEN]; // socket buffer
 char udp_receiving_buffer[NET_BUF_LEN];
-char rpc_outbuf[RPC_BUF_LEN]; // rpc output buffer
+char network_output_buffer[NET_BUF_LEN]; // output buffer for TCP/UDP control command
 
 
 /*
@@ -251,10 +249,11 @@
 /*
 * Threads
 */
-// Timer thread for auto update
-void auto_update_timer_thread(void const* args) {
+// Timer thread for auto update in TCP client function
+void auto_update_timer_thread(void const* args)
+{
     bool update_flag = true;
-    
+
     Thread::wait(500);
     while(true) {
         auto_update_queue.put(&update_flag);
@@ -264,7 +263,8 @@
 
 
 // WDT reset
-void wdt_reset_thread(void const* args) {
+void wdt_reset_thread(void const* args)
+{
     while (true)
         wdt.Service();
 }
@@ -273,31 +273,32 @@
 int main()
 {
     int n, ret;
-    
+
     Thread::wait(500); // turn on delay
-        
+
     /*
     * Configure
     */
     uart.baud(115200);
     DBG("\r\nStarting...");
-    
+
+    // check watchdog
     if (wdt.WatchdogCausedReset())
         DBG("Watchdog caused reset.");
     wdt.Configure(4);
-    
+
     /*
     * FLASH
     */
     load_eeprom_network();
     load_eeprom_tcpserver();
-    
+
     /*
     * UI threads
     */
     Thread t2(auto_update_timer_thread);
     Thread t3(wdt_reset_thread);
-    
+
     /*
     * Ethernet
     */
@@ -306,13 +307,13 @@
         ERR("Ethernet initialisation failed. App halted.");
         while (true) {};
     }
-    
+
     Thread::wait(2000); // TCP/UDP stack delay
 
-/*
-* UDP server
-* TCP server/client
-*/
+    /*
+    * UDP server
+    * TCP server/client
+    */
 #ifdef UDP_SERVER
     ret = udp_server.bind(udp_server_local_port);
     DBG("UDP server started (sock.bind = %d)...", ret);
@@ -329,7 +330,7 @@
 #ifdef TCP_CLIENT
 
 #endif
-    
+
     /*
     * Network loop processor
     */
@@ -341,21 +342,20 @@
                 ret = tcp_sock.connect(str_server_ip_addr, u16tcp_server_port); // timeout is default in connect() in W5500.h
                 if (ret > -1) {
                     DBG("Successfully connected to %s on port %d", str_server_ip_addr, u16tcp_server_port);
-                }
-                else {
+                } else {
                     ERR("Unable to connect to %s on port %d", str_server_ip_addr, u16tcp_server_port);
                 }
             }
-                
+
             // transmit data if connected
             if (tcp_sock.is_connected()) {
                 osEvent evt = auto_update_queue.get(1); // timeout after 1ms
                 if (evt.status == osEventMessage) {
                     DBG("Updating...");
-                    update_sending_frame(tcp_sending_buffer);
-                    tcp_sock.send_all(tcp_sending_buffer, SENDING_PROTOCOL_LENGTH);
+                    update_sending_frame(network_output_buffer);
+                    tcp_sock.send_all(network_output_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));
@@ -374,26 +374,37 @@
         if (1) {
             // wait for client within timeout
             ret = tcp_server.accept(tcp_client);
-            
+
             // tcp client connected
             if (ret > -1) {
                 DBG("Connection from: %s", tcp_client.get_address());
-                
+
                 // loop waiting and receiving data within timeout
                 tcp_client.set_blocking(false, TCP_SERVER_RECEIVE_TIMEOUT); // Timeout after x seconds
-                while (true) {
+                while (tcp_client.is_connected()) {
                     n = tcp_client.receive(tcp_receiving_buffer, sizeof(tcp_receiving_buffer));
                     if (n <= 0) break;
-                    
+
                     // got some data, process it
                     tcp_receiving_buffer[n] = '\0'; // for debugging purpose
                     DBG("TCP server received: %s", tcp_receiving_buffer);
                     n = process_control_command(tcp_receiving_buffer, n);
-                    // send rpc reply back to client, NNIO protocol always returns 0
+                    // send reply back to client, NNIO protocol always returns 0
+                    // RPC-style protocol
                     if (n > 0) {
-                        rpc_outbuf[n] = '\0';
-                        tcp_client.send_all(rpc_outbuf, strlen(rpc_outbuf));
-                    }
+                        network_output_buffer[n] = '\0';
+                        tcp_client.send_all(network_output_buffer, strlen(network_output_buffer));
+                    } // RPC-style protocol
+                    else if (n == 0) {
+                        // then, check query status command and sending protocol if required
+                        if (tcp_receiving_buffer[RECEIVING_PROTOCOL_COMMAND_POS] == QUERY_STATUS_COMMAND) {
+                            DBG("Requested to send device status through TCP");
+                            // sending protocol
+                            update_sending_frame(network_output_buffer);
+                            tcp_client.send_all(network_output_buffer, SENDING_PROTOCOL_LENGTH);
+                            DBG("Sent");
+                        }
+                    } // NNIO protocol
                 } // end loop if no data received within timeout
             } // if client connected
             tcp_client.close();
@@ -402,9 +413,9 @@
 
 #ifdef UDP_SERVER // configuration and control, both NNIO and RPC-style
         bool discovery_mode_flag, config_mode_flag;
-        
+
         n = udp_server.receiveFrom(ep_udp_client, udp_receiving_buffer, sizeof(udp_receiving_buffer));
-        
+
         // check to see if it is a query command
         // if yes, is it a discovery command or an ip query to enter config mode
         discovery_mode_flag = false;
@@ -421,11 +432,10 @@
             DBG("Entered configuration mode...");
             DBG("!!! RESET when finished");
         } // NNCFIP
-        
+
         // if received NNCFIP, enter config mode
         if (config_mode_flag) {
-            while (n > 0)
-            {
+            while (n > 0) {
                 // got some data, test it
                 DBG("UDP received (%s) from (%s:%d)", udp_receiving_buffer, ep_udp_client.get_address(), ep_udp_client.get_port());
                 process_config_command(udp_receiving_buffer, n);
@@ -438,9 +448,20 @@
         else if ((n > 0) && (!discovery_mode_flag)) {
             n = process_control_command(udp_receiving_buffer, n);
             // send rpc reply back to client, NNIO protocol always returns 0
+            // RPC-style protocol
             if (n > 0) {
-                rpc_outbuf[n] = '\0';
-                udp_server.sendTo(ep_udp_client, rpc_outbuf, strlen(rpc_outbuf));
+                network_output_buffer[n] = '\0';
+                udp_server.sendTo(ep_udp_client, network_output_buffer, strlen(network_output_buffer));
+            } // RPC-style protocol
+            else if (n == 0) {
+                // then, check query status command and sending protocol if required
+                if (udp_receiving_buffer[RECEIVING_PROTOCOL_COMMAND_POS] == QUERY_STATUS_COMMAND) {
+                    DBG("Requested to send device status through UDP");
+                    // sending protocol
+                    update_sending_frame(network_output_buffer);
+                    udp_server.sendTo(ep_udp_client, network_output_buffer, SENDING_PROTOCOL_LENGTH);
+                    DBG("Sent");
+                }
             }
         }
 #endif
@@ -454,13 +475,13 @@
 void process_config_command(char* received_buffer, int len)
 {
     DBG("Processing configuration command");
-    
+
     // a configuration command always starts with NN
     if ((received_buffer[0] == 'N') && (received_buffer[1] == 'N') &&
-        (received_buffer[2] == 'C') && (received_buffer[3] == 'F')) {
+            (received_buffer[2] == 'C') && (received_buffer[3] == 'F')) {
         switch (len) {
-            // length = 6, a QUERY command (discovery command, TCP port, or UDP port)
-            // Format: NNCFDS, NNCFTP, NNCFUP, NNCFTM
+                // length = 6, a QUERY command (discovery command, TCP port, or UDP port)
+                // Format: NNCFDS, NNCFTP, NNCFUP, NNCFTM
             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()));
@@ -564,10 +585,10 @@
     char* received_frame;
     bool rpc_style;
     int pos;
-    char inbuf[RPC_BUF_LEN];
-    
+    char inbuf[NET_BUF_LEN];
+
     DBG("Processing control command");
-    
+
     /*
      * This section is for RPC-style command
      */
@@ -580,14 +601,13 @@
     if ((len > 0) && (inbuf[0] == '/')) {
         char obj_name[32];
         bool result;
-        
+
         rpc_style = true;
         // find RPC object name
         for (int i = 1; i < strlen(inbuf); i++) {
             if (inbuf[i] != '/') {
                 obj_name[i-1] = inbuf[i];
-            }
-            else {
+            } else {
                 obj_name[i-1] = '\0';
                 break;
             }
@@ -596,24 +616,23 @@
         /*
          * execute RPC command, return reply length and reply in rpc_outbuf
          */
-        result = RPC::call(inbuf, rpc_outbuf);
+        result = RPC::call(inbuf, network_output_buffer);
         if (result) {
             // re-arrange output buffer as following: object_name:output_value
-            strcpy(inbuf, rpc_outbuf); // use inbuf as temp
-            strcpy(rpc_outbuf, obj_name); // rpc object name
-            strcat(rpc_outbuf, ":");
-            strcat(rpc_outbuf, inbuf); // concat rpc reply
-            strcat(rpc_outbuf, "\r\n"); // CR-LF
-            int j = strlen(rpc_outbuf);
-            DBG("Reply of rpc command on \"%s\" (%d bytes): %s", obj_name, j, rpc_outbuf);
+            strcpy(inbuf, network_output_buffer); // use inbuf as temp
+            strcpy(network_output_buffer, obj_name); // rpc object name
+            strcat(network_output_buffer, ":");
+            strcat(network_output_buffer, inbuf); // concat rpc reply
+            strcat(network_output_buffer, "\r\n"); // CR-LF
+            int j = strlen(network_output_buffer);
+            DBG("Reply of rpc command on \"%s\" (%d bytes): %s", obj_name, j, network_output_buffer);
             return j; // return length of rpc_outbuf
-        }
-        else {
+        } else {
             ERR("Failed: %s", inbuf);
             return -1;
         }
     }
-    
+
     /*
      * This section below is  for NNIO protocol
      */
@@ -627,13 +646,13 @@
         }
         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
@@ -662,17 +681,8 @@
             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("Successfully processed.");
     return 0;
 }
@@ -681,11 +691,12 @@
 /*
 * W5500 Ethernet init
 */
-int ethernet_init(void) {
+int ethernet_init(void)
+{
     int dhcp_ret, ret;
-    
+
     DBG("Initialising ethernet...");
-    
+
     // if not configured, try dhcp
     dhcp_ret = -1;
     if (configured_ip != DEFAULT_ENABLE_FLAG_VALUE) {
@@ -694,7 +705,7 @@
         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
@@ -719,7 +730,7 @@
         ERR("Error eth.connect() - ret = %d", ret);
         return -1;
     }
-    
+
     return 0;
 }
 
@@ -727,9 +738,10 @@
 /*
 * Update digital outputs according to receiving protocol
 */
-void update_digital_outputs(char* buf) {
+void update_digital_outputs(char* buf)
+{
     DBG("Digital outputs: %s", buf);
-    
+
     dout0 = (buf[0] == DIGITAL_HIGH)? 1 : 0;
     dout1 = (buf[1] == DIGITAL_HIGH)? 1 : 0;
     dout2 = (buf[2] == DIGITAL_HIGH)? 1 : 0;
@@ -743,11 +755,12 @@
 /*
 * Prepare a frame for sending protocol, which includes status of I/Os
 */
-void update_sending_frame(char* buf) {
+void update_sending_frame(char* buf)
+{
     memcpy(&buf[SENDING_PROTOCOL_ID_POS], DEVICE_CONTROL_CODE, 4); // device id
     memcpy(&buf[SENDING_PROTOCOL_MAC_POS], &u8mac, 6);
     memcpy(&buf[SENDING_PROTOCOL_IP_POS], &u8ip_addr, 4);
-    
+
     buf[SENDING_PROTOCOL_DI_POS+0] = (din0 == 1) ? DIGITAL_HIGH : DIGITAL_LOW;
     buf[SENDING_PROTOCOL_DI_POS+1] = (din1 == 1) ? DIGITAL_HIGH : DIGITAL_LOW;
     buf[SENDING_PROTOCOL_DI_POS+2] = (din2 == 1) ? DIGITAL_HIGH : DIGITAL_LOW;
@@ -756,7 +769,7 @@
     buf[SENDING_PROTOCOL_DI_POS+5] = (din5 == 1) ? DIGITAL_HIGH : DIGITAL_LOW;
     buf[SENDING_PROTOCOL_DI_POS+6] = (din6 == 1) ? DIGITAL_HIGH : DIGITAL_LOW;
     buf[SENDING_PROTOCOL_DI_POS+7] = (din7 == 1) ? DIGITAL_HIGH : DIGITAL_LOW;
-    
+
     buf[SENDING_PROTOCOL_DO_POS+0] = (dout0 == 1) ? DIGITAL_HIGH : DIGITAL_LOW;
     buf[SENDING_PROTOCOL_DO_POS+1] = (dout1 == 1) ? DIGITAL_HIGH : DIGITAL_LOW;
     buf[SENDING_PROTOCOL_DO_POS+2] = (dout2 == 1) ? DIGITAL_HIGH : DIGITAL_LOW;
@@ -765,7 +778,7 @@
     buf[SENDING_PROTOCOL_DO_POS+5] = (dout5 == 1) ? DIGITAL_HIGH : DIGITAL_LOW;
     buf[SENDING_PROTOCOL_DO_POS+6] = (dout6 == 1) ? DIGITAL_HIGH : DIGITAL_LOW;
     buf[SENDING_PROTOCOL_DO_POS+7] = (dout7 == 1) ? DIGITAL_HIGH : DIGITAL_LOW;
-    
+
     uint16_t val = ain0.read_u16(); // 16-bits normalised
     memcpy(&buf[SENDING_PROTOCOL_AI0_POS], &val, 2); // LSB MSB
     val = ain1.read_u16(); // 16-bits normalised