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
Diff: main.cpp
- Revision:
- 26:09e0dd020900
- Parent:
- 25:48dd18cc147c
- Child:
- 27:22f289beceb8
diff -r 48dd18cc147c -r 09e0dd020900 main.cpp --- 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);