Machine Vision Status TCP Server
Dependencies: C12832 EthernetInterface mbed-rtos mbed ConfigFile
TcpDaemon.cpp@4:339a85b66476, 2015-03-11 (annotated)
- 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?
User | Revision | Line number | New 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 | } |