Machine Vision Status TCP Server
Dependencies: C12832 EthernetInterface mbed-rtos mbed ConfigFile
Revision 1:8efef658d90b, committed 2015-03-05
- Comitter:
- dwini
- Date:
- Thu Mar 05 13:18:28 2015 +0000
- Parent:
- 0:bef69e35f486
- Child:
- 2:a8eebf64cd3e
- Commit message:
- Create TCP Daemon and some logging (most of TRex code).
Changed in this revision
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Log.h Thu Mar 05 13:18:28 2015 +0000 @@ -0,0 +1,81 @@ +#include <stdio.h> +#include <stdarg.h> +#include <ctime> + +#ifndef LOG_HEADER +#define LOG_HEADER + +#define DEBUG_MODE 1 + +using namespace std; + +namespace MachineVision{ + + class Log{ + public: + static void e(char* fmt, ...) { + char buffer [80]; + Log::getTimestamp(buffer); + + va_list args; + va_start(args,fmt); + printf("%s ", buffer); + printf("[ERROR] "); + vprintf(fmt,args); + va_end(args); + } + + static void w(char* fmt, ...) { + char buffer [80]; + Log::getTimestamp(buffer); + + va_list args; + va_start(args,fmt); + printf("%s ", buffer); + printf("[WARNING] "); + vprintf(fmt,args); + va_end(args); + } + + static void d(char* fmt, ...) { + #ifdef DEBUG_MODE + char buffer [80]; + Log::getTimestamp(buffer); + + va_list args; + va_start(args,fmt); + printf("%s ", buffer); + printf("[DEBUG] "); + vprintf(fmt,args); + va_end(args); + #endif + } + + static void v(char* fmt, ...) { + #ifdef DEBUG_MODE + char buffer [80]; + Log::getTimestamp(buffer); + + va_list args; + va_start(args,fmt); + printf("%s ", buffer); + printf("[VERBOSE] "); + vprintf(fmt,args); + va_end(args); + #endif + } + + private: + static void getTimestamp(char * buffer) { + time_t rawtime; + struct tm * timeinfo; + + time (&rawtime); + timeinfo = localtime (&rawtime); + + strftime(buffer, 80, "%d-%m-%Y|%H:%M:%S", timeinfo); + } + }; +} + +#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/TcpDaemon.cpp Thu Mar 05 13:18:28 2015 +0000 @@ -0,0 +1,109 @@ +#include "TcpDaemon.h" +#include "Log.h" + +// Incomming message end +#define END_MSG_SEQUENCE "\r\n" + +namespace MachineVision{ + /* + * TcpDaemon constructor + * + * @server_port the port the daemon will be listening on + */ + TcpDaemon::TcpDaemon(int server_port) { + this->server_port = server_port; + this->keepListening = true; + } + + /* + * Make the daemon start listening for incoming connections + */ + void TcpDaemon::startListening() { + if (this->bindSocket()) { + this->doListen(); + } + } + + /* + * Bind to server socket + * + * @return true on success + */ + bool TcpDaemon::bindSocket() { + if(server.bind(server_port) < 0) { + Log::e("Bind failed. Error\r\n"); + return false; + } else { + Log::d("Bind ok\r\n"); + return true; + } + } + + /* + * Listen for incoming connections + */ + void TcpDaemon::doListen() { + + // Listen for incoming connection + if (server.listen(MAX_BACKLOG) < 0) { + Log::w("Listen failed\r\n"); + return; + } + + while (this->keepListening) { + Log::d("Listening for incoming connection ...\r\n"); + + // Accept connection from an incoming client + if (server.accept(client) < 0) { + Log::w("Client accept failed\r\n"); + } else { + Log::d("Client connected: %s\r\n", client.get_address()); + + // Set non-blocking + client.set_blocking(false, TCP_TIMEOUT); + + while (client.is_connected()) { + // Keep receiving messages from the client + int read_size = 0; + int total_read_size = 0; + char * end = NULL; + + while((read_size = client.receive(buffer, BUFFER_SIZE)) > 0) { + total_read_size = read_size; + + // Null-terminate string + this->buffer[total_read_size] = '\0'; + Log::v("Received partial: %s\r\n", this->buffer); + + // Keep reading until full message is received + end = strstr(this->buffer, END_MSG_SEQUENCE); // Find END_MSG_SEQUENCE + while (total_read_size < BUFFER_SIZE && end == NULL) { + read_size = client.receive(this->buffer+total_read_size, BUFFER_SIZE-total_read_size); + if (read_size != -1) { + total_read_size += read_size; + end = strstr(this->buffer, END_MSG_SEQUENCE); + } + Log::v("Waiting for rest of message\r\n"); + } + } + + if (total_read_size > 0) { + if (end == NULL) { + Log::w("Buffer full\r\n"); + } else { + // Null-terminate string + this->buffer[total_read_size] = '\0'; + + // Full string received, lets do our thing + Log::v("Received: %s", this->buffer); + } + } + } + + Log::d("Client disconnected\r\n"); + fflush(stdout); + client.close(); + } + } + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/TcpDaemon.h Thu Mar 05 13:18:28 2015 +0000 @@ -0,0 +1,51 @@ +#include "EthernetInterface.h" + +#ifndef TCP_DAEMON_HEADER +#define TCP_DAEMON_HEADER + +#define MAX_BACKLOG 1 + +namespace MachineVision{ + + class TcpDaemon{ + public: + const static int BUFFER_SIZE = 512; + const static int TCP_TIMEOUT = 1000; + + private: + int server_port; + TCPSocketServer server; + TCPSocketConnection client; + + char buffer[BUFFER_SIZE+1]; + bool keepListening; + + public: + /* + * TcpDaemon constructor + * + * @server_port the port the daemon will be listening on + */ + TcpDaemon(int server_port); + + /* + * Make the daemon start listening for incoming connections + */ + void startListening(); + + private: + /* + * Bind to server socket + * + * @return true on success + */ + bool bindSocket(); + + /* + * Listen for incoming connections + */ + void doListen(); + }; +} + +#endif
--- a/main.cpp Thu Mar 05 10:10:22 2015 +0000 +++ b/main.cpp Thu Mar 05 13:18:28 2015 +0000 @@ -1,8 +1,12 @@ #include "mbed.h" #include "EthernetInterface.h" #include "C12832.h" +#include "Log.h" +#include "TcpDaemon.h" -#define ECHO_SERVER_PORT 6666 +#define MAX_BACKLOG 1 +#define TCP_SERVER_PORT 6666 + #define LCD_LINE_HEIGHT 12 #define DELAY_INDICATION 0 @@ -11,17 +15,21 @@ #define STR_CLEAR "CLEAR" Serial pc(USBTX,USBRX); -DigitalOut myled(LED1); +DigitalOut error_led(LED1); C12832 lcd(p5, p7, p6, p8, p11); PwmOut rOut (p23); PwmOut gOut (p24); PwmOut bOut (p25); +using namespace MachineVision; + void setLcdServerInfo(char * ip) { lcd.cls(); lcd.locate(0,0); - lcd.printf("IP: %s - Port: %d", ip, ECHO_SERVER_PORT); + lcd.printf("IP: %s", ip); + lcd.locate(0,14); + lcd.printf("Port: %d", TCP_SERVER_PORT); } void setRGB(int r, int g, int b) { @@ -55,20 +63,7 @@ initRgb(); pc.baud(115200); - EthernetInterface eth; - printf("Requesting IP address from DHCP\r\n"); - eth.init(); //Use DHCP - eth.connect(); - printf("IP Address is %s\r\n", eth.getIPAddress()); - printf("Listening on port %d\r\n", ECHO_SERVER_PORT); - - // Set ip on LCD - setLcdServerInfo(eth.getIPAddress()); - - TCPSocketServer server; - server.bind(ECHO_SERVER_PORT); - server.listen(); - + // Status check for (int i = 0; i < 4; i++) { indicateOk(); @@ -76,43 +71,30 @@ } clearRGB(); - while (true) { - printf("Awaiting client connection ...\r\n"); - setLcdServerInfo(eth.getIPAddress()); - lcd.locate(0, LCD_LINE_HEIGHT); - lcd.printf("Awaiting connection ..."); + EthernetInterface eth; + Log::v("Requesting IP address from DHCP\r\n"); + eth.init(); //Use DHCP + + if (eth.connect() < 0) { + Log::w("Could not retrieve IP address from DHCP\r\n"); + setLcdServerInfo("No ip address"); + } else { + Log::v("IP Address is %s\r\n", eth.getIPAddress()); - TCPSocketConnection client; - server.accept(client); - //client.set_blocking(false, 5000); // Timeout after (1.5)s - - printf("Client connected: %s\r\n", client.get_address()); + // Set ip on LCD setLcdServerInfo(eth.getIPAddress()); - lcd.locate(0, LCD_LINE_HEIGHT); - lcd.printf("Client: %s", client.get_address()); - - char buffer[256]; - while (true) { - int n = client.receive(buffer, sizeof(buffer)); - if (n <= 0) { - break; - } else { - if (strcmp(STR_FAIL, buffer) == 0) { - printf("Received FAIL\r\n"); - indicateFail(); - } else if (strcmp(STR_OK, buffer) == 0) { - printf("Received OK\r\n"); - indicateOk(); - } else if (strcmp(STR_CLEAR, buffer) == 0) { - printf("Clearing\r\n"); - clearRGB(); - } else { - printf("Unknown message %s\r\n", buffer); - } - } - } - - printf("Client disconnected\r\n"); - client.close(); + + // Start the daemon + TcpDaemon daemon(TCP_SERVER_PORT); + Log::v("TCP daemon listening @ TCP_SERVER_PORT = %d\r\n", TCP_SERVER_PORT); + daemon.startListening(); + } + + // Should never be reached + while (true) { + error_led = 1; + wait(0.25); + error_led = 0; + wait(0.25); } }