Machine Vision Status TCP Server

Dependencies:   C12832 EthernetInterface mbed-rtos mbed ConfigFile

Committer:
dwini
Date:
Wed Mar 11 10:26:35 2015 +0000
Revision:
4:339a85b66476
Parent:
3:254a2671a8e3
Child:
5:7a32c081a3fa
Add ability of external triggering.

Who changed what in which revision?

UserRevisionLine numberNew contents of line
dwini 1:8efef658d90b 1 #include "TcpDaemon.h"
dwini 1:8efef658d90b 2 #include "Log.h"
dwini 1:8efef658d90b 3
dwini 2:a8eebf64cd3e 4 // Incoming message end
dwini 1:8efef658d90b 5 #define END_MSG_SEQUENCE "\r\n"
dwini 1:8efef658d90b 6
dwini 1:8efef658d90b 7 namespace MachineVision{
dwini 1:8efef658d90b 8 /*
dwini 1:8efef658d90b 9 * TcpDaemon constructor
dwini 1:8efef658d90b 10 *
dwini 1:8efef658d90b 11 * @server_port the port the daemon will be listening on
dwini 1:8efef658d90b 12 */
dwini 4:339a85b66476 13 TcpDaemon::TcpDaemon(int server_port, PinName accept_led_pin, PinName receive_led_pin, PinName trigger_pin)
dwini 4:339a85b66476 14 : receive_led(receive_led_pin), accept_led(accept_led_pin), trigger(trigger_pin) {
dwini 1:8efef658d90b 15 this->server_port = server_port;
dwini 1:8efef658d90b 16 this->keepListening = true;
dwini 2:a8eebf64cd3e 17 this->receive_led = 0;
dwini 3:254a2671a8e3 18 this->accept_led = 0;
dwini 1:8efef658d90b 19 }
dwini 1:8efef658d90b 20
dwini 1:8efef658d90b 21 /*
dwini 1:8efef658d90b 22 * Make the daemon start listening for incoming connections
dwini 1:8efef658d90b 23 */
dwini 1:8efef658d90b 24 void TcpDaemon::startListening() {
dwini 1:8efef658d90b 25 if (this->bindSocket()) {
dwini 1:8efef658d90b 26 this->doListen();
dwini 1:8efef658d90b 27 }
dwini 1:8efef658d90b 28 }
dwini 1:8efef658d90b 29
dwini 1:8efef658d90b 30 /*
dwini 1:8efef658d90b 31 * Bind to server socket
dwini 1:8efef658d90b 32 *
dwini 1:8efef658d90b 33 * @return true on success
dwini 1:8efef658d90b 34 */
dwini 1:8efef658d90b 35 bool TcpDaemon::bindSocket() {
dwini 1:8efef658d90b 36 if(server.bind(server_port) < 0) {
dwini 1:8efef658d90b 37 Log::e("Bind failed. Error\r\n");
dwini 1:8efef658d90b 38 return false;
dwini 1:8efef658d90b 39 } else {
dwini 1:8efef658d90b 40 Log::d("Bind ok\r\n");
dwini 3:254a2671a8e3 41 server.set_blocking(false, TCP_ACCEPT_TIMEOUT); // Set tot non-blocking
dwini 1:8efef658d90b 42 return true;
dwini 1:8efef658d90b 43 }
dwini 1:8efef658d90b 44 }
dwini 4:339a85b66476 45
dwini 4:339a85b66476 46 void TcpDaemon::checkTrigger(void) {
dwini 4:339a85b66476 47 if (trigger.hasBeenTriggered()) {
dwini 4:339a85b66476 48 if (client.send_all(TRIGGER_MSG, sizeof(TRIGGER_MSG)-1) > 0) { // -1 for removing \0
dwini 4:339a85b66476 49 Log::v("Successfully send trigger to client\r\n");
dwini 4:339a85b66476 50 } else {
dwini 4:339a85b66476 51 Log::w("Could not send trigger to client\r\n");
dwini 4:339a85b66476 52 }
dwini 4:339a85b66476 53 }
dwini 4:339a85b66476 54 }
dwini 1:8efef658d90b 55
dwini 1:8efef658d90b 56 /*
dwini 1:8efef658d90b 57 * Listen for incoming connections
dwini 1:8efef658d90b 58 */
dwini 1:8efef658d90b 59 void TcpDaemon::doListen() {
dwini 1:8efef658d90b 60
dwini 1:8efef658d90b 61 // Listen for incoming connection
dwini 1:8efef658d90b 62 if (server.listen(MAX_BACKLOG) < 0) {
dwini 1:8efef658d90b 63 Log::w("Listen failed\r\n");
dwini 1:8efef658d90b 64 return;
dwini 1:8efef658d90b 65 }
dwini 1:8efef658d90b 66
dwini 3:254a2671a8e3 67 Log::d("Listening for incoming connection ...\r\n");
dwini 1:8efef658d90b 68 while (this->keepListening) {
dwini 3:254a2671a8e3 69
dwini 3:254a2671a8e3 70 // Visual indication
dwini 3:254a2671a8e3 71 accept_led = !accept_led;
dwini 1:8efef658d90b 72
dwini 1:8efef658d90b 73 // Accept connection from an incoming client
dwini 3:254a2671a8e3 74 if (server.accept(client) >= 0) {
dwini 1:8efef658d90b 75 Log::d("Client connected: %s\r\n", client.get_address());
dwini 1:8efef658d90b 76
dwini 1:8efef658d90b 77 // Set non-blocking
dwini 1:8efef658d90b 78 client.set_blocking(false, TCP_TIMEOUT);
dwini 1:8efef658d90b 79
dwini 1:8efef658d90b 80 while (client.is_connected()) {
dwini 1:8efef658d90b 81 // Keep receiving messages from the client
dwini 1:8efef658d90b 82 int read_size = 0;
dwini 1:8efef658d90b 83 int total_read_size = 0;
dwini 1:8efef658d90b 84 char * end = NULL;
dwini 2:a8eebf64cd3e 85 int i_read = 0;
dwini 1:8efef658d90b 86
dwini 2:a8eebf64cd3e 87 int buffer_size = BUFFER_SIZE;
dwini 2:a8eebf64cd3e 88 char * buffer_offset = buffer;
dwini 2:a8eebf64cd3e 89
dwini 2:a8eebf64cd3e 90 // Read full message from client
dwini 2:a8eebf64cd3e 91 Log::v("Waiting for message\r\n");
dwini 2:a8eebf64cd3e 92 do {
dwini 2:a8eebf64cd3e 93 read_size = client.receive(buffer_offset, buffer_size);
dwini 2:a8eebf64cd3e 94 receive_led = !receive_led;
dwini 1:8efef658d90b 95
dwini 2:a8eebf64cd3e 96 if (read_size > 0) {
dwini 2:a8eebf64cd3e 97 total_read_size += read_size;
dwini 2:a8eebf64cd3e 98
dwini 2:a8eebf64cd3e 99 // Null-terminate string
dwini 2:a8eebf64cd3e 100 buffer[total_read_size] = '\0';
dwini 2:a8eebf64cd3e 101 Log::v("Received partial: %s\r\n", buffer);
dwini 2:a8eebf64cd3e 102
dwini 2:a8eebf64cd3e 103 // Search for END
dwini 2:a8eebf64cd3e 104 end = strstr(buffer, END_MSG_SEQUENCE);
dwini 2:a8eebf64cd3e 105
dwini 2:a8eebf64cd3e 106 buffer_size = BUFFER_SIZE-total_read_size;
dwini 2:a8eebf64cd3e 107 buffer_offset = buffer+total_read_size;
dwini 2:a8eebf64cd3e 108 } else if (total_read_size > 0) { // Increment i_read (max timeouts for message)
dwini 2:a8eebf64cd3e 109 i_read++;
dwini 2:a8eebf64cd3e 110 }
dwini 4:339a85b66476 111
dwini 4:339a85b66476 112 checkTrigger();
dwini 3:254a2671a8e3 113 } while (client.is_connected() && total_read_size < BUFFER_SIZE && end == NULL && i_read < MAX_READ_TIMEOUTS);
dwini 1:8efef658d90b 114
dwini 3:254a2671a8e3 115 if (end == NULL) {
dwini 3:254a2671a8e3 116 if (total_read_size >= BUFFER_SIZE) {
dwini 1:8efef658d90b 117 Log::w("Buffer full\r\n");
dwini 3:254a2671a8e3 118 } else if (i_read == MAX_READ_TIMEOUTS) {
dwini 3:254a2671a8e3 119 Log::w("Partial message received. MAX_READ_TIMEOUTS reached.\r\n");
dwini 1:8efef658d90b 120 }
dwini 3:254a2671a8e3 121
dwini 3:254a2671a8e3 122 } else {
dwini 3:254a2671a8e3 123 // Full string received, lets do our thing
dwini 3:254a2671a8e3 124 Log::v("Received: %s\r\n", buffer);
dwini 1:8efef658d90b 125 }
dwini 1:8efef658d90b 126 }
dwini 1:8efef658d90b 127
dwini 1:8efef658d90b 128 Log::d("Client disconnected\r\n");
dwini 1:8efef658d90b 129 fflush(stdout);
dwini 1:8efef658d90b 130 client.close();
dwini 1:8efef658d90b 131 }
dwini 1:8efef658d90b 132 }
dwini 1:8efef658d90b 133 }
dwini 1:8efef658d90b 134 }