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:
Mon Dec 29 23:38:26 2014 +0000
Parent:
27:22f289beceb8
Child:
29:bc052f283ada
Commit message:
Support RPC with TCP/UDP server

Changed in this revision

main.cpp Show annotated file Show diff for this revision Revisions of this file
protocol.txt 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	Mon Dec 29 21:40:55 2014 +0000
+++ b/main.cpp	Mon Dec 29 23:38:26 2014 +0000
@@ -169,6 +169,7 @@
 char tcp_receiving_buffer[256];
 char tcp_sending_buffer[256]; // socket buffer
 char udp_receiving_buffer[256];
+char rpc_outbuf[256]; // rpc output buffer
 
 
 /*
@@ -240,7 +241,7 @@
 
 // Prototypes
 int ethernet_init(void);
-void process_control_command(char* received_buffer, int len);
+int 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);
@@ -388,10 +389,14 @@
                     n = tcp_client.receive(tcp_receiving_buffer, sizeof(tcp_receiving_buffer));
                     if (n <= 0) break;
                     
-                    // got some data, test it
+                    // got some data, process it
                     tcp_receiving_buffer[n] = '\0'; // for debugging purpose
                     DBG("TCP server received: %s", tcp_receiving_buffer);
-                    process_control_command(tcp_receiving_buffer, n);
+                    n = process_control_command(tcp_receiving_buffer, n);
+                    // send rpc reply back to client, NNIO protocol always returns 0
+                    if (n > 0) {
+                        tcp_client.send_all(rpc_outbuf, strlen(rpc_outbuf));
+                    }
                 } // end loop if no data received within timeout
             } // if client connected
             tcp_client.close();
@@ -433,13 +438,20 @@
             } // while (n > 0), config loop
         } // if (config_mode_flag)
         else if ((n > 0) && (!discovery_mode_flag)) { // process control packages sent using UDP
-            process_control_command(udp_receiving_buffer, n);
+            n = process_control_command(udp_receiving_buffer, n);
+            // send rpc reply back to client, NNIO protocol always returns 0
+            if (n > 0) {
+                udp_server.sendTo(ep_udp_client, rpc_outbuf, strlen(rpc_outbuf));
+            }
         }
 #endif
     } // network processor
 }
 
 
+/*
+ * Process NNCF commands
+ */
 void process_config_command(char* received_buffer, int len)
 {
     DBG("Processing configuration command");
@@ -542,13 +554,14 @@
 }
 
 /*
-* Procedure to process receiving protocol, which includes command to control outputs
-*/
-void process_control_command(char* received_buffer, int len)
+ * Procedure to process receiving protocol, which includes command to control outputs
+ * Return: 0 if NNIO protocol; length of rpc output buffer if rpc; -1 if rpc failed
+ */
+int process_control_command(char* received_buffer, int len)
 {
     char* received_frame;
     int pos;
-    char inbuf[256], outbuf[256];
+    char inbuf[256];
     
     DBG("Processing control command");
     
@@ -557,19 +570,25 @@
     inbuf[len] = '\r'; // use inbuf for RPC protocol
     inbuf[len+1] = '\n';
     inbuf[len+2] = '\0'; // add CR-LF
-    DBG("inbuf = %s", inbuf);
     if ((len > 0) && (inbuf[0] == '/')) {
         bool result;
-        result = RPC::call(inbuf, outbuf);
+        DBG("Rpc command = %s", inbuf);
+        result = RPC::call(inbuf, rpc_outbuf);
         if (result) {
-            DBG("I: %s O: %s\n", inbuf, outbuf);
+            // calculate length of rpc_outbuf
+            int i = strlen(rpc_outbuf);
+            DBG("Rpc reply (%d bytes): %s", i, rpc_outbuf);
+            return i; // return length of rpc_outbuf
         }
         else {
             ERR("Failed: %s", inbuf);
+            return -1;
         }
     }
     
-    // NNIO protocol
+    /*
+     * This section below is  for NNIO protocol
+     */
     while (len >= RECEIVING_PROTOCOL_LENGTH) {
         // find device ID
         DBG("Checking device ID...");
@@ -625,7 +644,9 @@
             DBG("Sent");
         }
     }
+    
     DBG("Successfully processed.");
+    return 0;
 }
 
 
--- a/protocol.txt	Mon Dec 29 21:40:55 2014 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,93 +0,0 @@
-CONFIGURATION SECTION (UDP)
-A configuration command always starts with "NN"
-1. DISCOVERY Command
-    + UDP broadcast: 192.168.0.255 to port 11000
-    + Send: NNIODS
-    + Receive: NNIO (4-bytes) MAC-address (6-bytes) IP-address
-1a. Query Command: IP, subnet, gateway, mac
-    + + Send: NNIOIP, NNIOSN, NNIOGW, NNIOMC
-
-2. TCP SERVER PORT Command
-    + Send: NNIOTP
-    + Receive: 10000
-
-3. UDP SERVER PORT Command
-    + Send: NNIOUP
-    + Receive: 11000
-
-4. Set time using NTP Command    
-    + Send NNIOTM
-    + Receive:
-      DIS: if NTP is disabled
-      ERR: if cannot update time
-      Successful: Fri Sep 26 20:28:01 2014 {0A}
-      
-5. Set new network configuration
-    + Send: 19 bytes in total, NNIO + 15-byte
-      NNIO         4-byte IP address    4-byte subnet    4-byte gateway   3-byte MAC
-      4E 4E 49 4F    C0 A8 00 78         FF FF FF 00       C0 A8 00 01     00 00 01
-
-6. Set TCP server info (only when the device is as a TCP client)
-    + Send: 12 bytes in total, NNIO + 8 bytes
-      NNIO         1-byte auto flag        1-byte time period (s)      4-byte IP       2-byte port (LSB MSB)
-      4E 4E 49 4F  'Y' or others            05 (5s)                   C0 A8 00 09       E0 2E (0x2EE0 = 12000)
-
-NOTE:
-1. Both TCP client and server are working. Can be enabled/disabled using u16enable_tcp_client/server flags in eeprom (not in use now).
-2. UDP server is always working.
-
-
-INTERFACING SECTION (TCP)
-4. Receiving Protocol: 58-bytes in total
-Ex in hex
-ID: 4E 4E 49 4F
-OP: 4F 4F 4F 4F 51
-IP: C0 A8 00 78
-DO: 48 48 48 48 48 48 48 48
-AO: 80 00 80 00 (no DAC)
-UART: 32-byte
-CR: 0D
-    
-    + Field ID (4-bytes) = NNIO
-    + Field OP (5-bytes): output control enable flag
-      Byte 1: Digital output
-      Byte 2: Analog output 0
-      Byte 3: Analog output 1
-      Byte 4: UART output
-      Byte 5: Command (Q: query status)
-      'O': enable controlling output
-      Others: disable controlling output
-      If Command is 'Q', device will update its outputs if needed and send its status including new outputs
-    + Field IP (4-bytes): device IP address
-    + Field DO[n] (8-bytes): digital output values
-      'H': output set to high
-      'L': output set to low
-    + Field AO_0 (2-bytes): 16-bit analog output value, channel 0
-      no DAC
-    + Field AO_1 (2-bytes): 16-bit analog output value, channel 1
-      no DAC
-    + UART output (32-bytes): max 32 bytes, stop string by NULL
-    + End char: CR
-    
-5. Sending Protocol: 39-bytes in total
-    + Field ID (4-bytes) = NNIO
-    + Field MAC (6-bytes)
-    + Field IP (4-bytes)
-    + Field DI[n]: 8-bit digital input values
-      'H' if input is HIGH
-      'L' if input is LOW
-    + Field DO[n]: 8-bit digital output values
-      'H' if output is HIGH
-      'L' if output is LOW
-    + Field AI_0 (2-bytes): analog 16-bit input value, normalised, channel 0
-      1st byte = LSB, 2nd byte = MSB
-    + Field AI_1 (2-bytes): analog 16-bit input value, normalised, channel 1
-      1st byte = LSB, 2nd byte = MSB
-    + Field AO_0 (2-bytes): 16-bit analog output value, channel 0
-      no DAC, fixed
-    + Field AO_1 (2-bytes): 16-bit analog output value, channel 1
-      no DAC, fixed
-    + End char: CR
-    
-6 Commands:
-    + QUERY STATUS ('Q')
\ No newline at end of file
--- a/readme.txt	Mon Dec 29 21:40:55 2014 +0000
+++ b/readme.txt	Mon Dec 29 23:38:26 2014 +0000
@@ -1,32 +1,9 @@
 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.
-2. Process a tcp packet including many receiving frames
-
-
-v1.0 25/10/2014
-    + Added: process many receiving frames in one tcp packet
-    + Bug: TCP server will reply with error #10061 if a previous tcp client connects and quickly disconnects.
-
-v1.1 15/11/2014
-    + Added: watchdog timer
-    + Modified: enter config mode forever when received discovery command
+    + NNIO module with NNIO protocol v2.0.
+    + Support RPC control commands using TCP/UDP server. No support RPC with TCP client.
 
-v1.1.1 27/11/2014
-    + Added: checking a configuration command to see if it starts with "NN". Otherwise, it could be data was sent using UDP connection.
-
-v1.2 30/11/2014
-    + Added: Discovery command now returns NNIO MAC IP
-    + Added: receive and process receiving protocol using UDP
-
-v1.2.1 01/12/2014 (demo version: git rev25)
-    + Modified: enter config mode with query ip command, not discovery command
-
-v2.0 24/12/2014
-    + Use official mbed-rtos
-    + Updated: configuration comands now use prefix NNCF, control commands use prefix NNIO.
-    + Run with demo software v2.0
-    + Added RPC through TCP/UDP: tested after fixed (Rpc)DigitalIn/Out names.
-      RPC control commands can be sent to TCP/UDP server on NNIO module. However, no reply yet, only debug with uart.
\ No newline at end of file
+v0.1 (29/12/2014)
+    + Imported F103_NNIO rev27:22f289beceb8
+    + Modified: process_control_command() with return value.
+      0 if NNIO protocol or RPC protocol without reply; length of RPC outbut buffer; or -1 if RPC failed.
+    + Modified: TCP server now checks to return data to client.
\ No newline at end of file