Machine Vision Status TCP Server
Dependencies: C12832 EthernetInterface mbed-rtos mbed ConfigFile
TcpDaemon.cpp
- Committer:
- dwini
- Date:
- 2015-03-11
- Revision:
- 5:7a32c081a3fa
- Parent:
- 4:339a85b66476
- Child:
- 7:23c8d34000eb
File content as of revision 5:7a32c081a3fa:
#include "TcpDaemon.h" #include "Log.h" #include "StatusIndicator.h" // Incoming 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, PinName accept_led_pin, PinName receive_led_pin, PinName trigger_pin, StatusIndicator * indicator) : receive_led(receive_led_pin), accept_led(accept_led_pin), trigger(trigger_pin) { this->server_port = server_port; this->keepListening = true; this->receive_led = 0; this->accept_led = 0; this->status_indicator = indicator; } /* * 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"); server.set_blocking(false, TCP_ACCEPT_TIMEOUT); // Set tot non-blocking return true; } } void TcpDaemon::checkTrigger(void) { if (trigger.hasBeenTriggered()) { if (client.send_all(TRIGGER_MSG, sizeof(TRIGGER_MSG)-1) > 0) { // -1 for removing \0 Log::v("Successfully send trigger to client\r\n"); } else { Log::w("Could not send trigger to client\r\n"); } } } /* * Listen for incoming connections */ void TcpDaemon::doListen() { // Listen for incoming connection if (server.listen(MAX_BACKLOG) < 0) { Log::w("Listen failed\r\n"); return; } Log::d("Listening for incoming connection ...\r\n"); while (this->keepListening) { // Visual indication accept_led = !accept_led; // Accept connection from an incoming client if (server.accept(client) >= 0) { 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; int i_read = 0; int buffer_size = BUFFER_SIZE; char * buffer_offset = buffer; // Read full message from client Log::v("Waiting for message\r\n"); do { read_size = client.receive(buffer_offset, buffer_size); receive_led = !receive_led; if (read_size > 0) { total_read_size += read_size; // Null-terminate string buffer[total_read_size] = '\0'; Log::v("Received partial: %s\r\n", buffer); // Search for END end = strstr(buffer, END_MSG_SEQUENCE); buffer_size = BUFFER_SIZE-total_read_size; buffer_offset = buffer+total_read_size; } else if (total_read_size > 0) { // Increment i_read (max timeouts for message) i_read++; } checkTrigger(); } while (client.is_connected() && total_read_size < BUFFER_SIZE && end == NULL && i_read < MAX_READ_TIMEOUTS); if (end == NULL) { if (total_read_size >= BUFFER_SIZE) { Log::w("Buffer full\r\n"); } else if (i_read == MAX_READ_TIMEOUTS) { Log::w("Partial message received. MAX_READ_TIMEOUTS reached.\r\n"); } } else { // Full string received, lets do our thing Log::v("Received: %s\r\n", buffer); if (strcmp(buffer, STR_OK) == 0) { status_indicator->setStatus(OK); } else if (strcmp(buffer, STR_FAIL) == 0) { status_indicator->setStatus(FAIL); } else if (strcmp(buffer, STR_CLEAR) == 0) { status_indicator->setStatus(CLEAR); } else { Log::w("Received unknown message: %s\r\n", buffer); } } } Log::d("Client disconnected\r\n"); fflush(stdout); client.close(); } } } }