Machine Vision Status TCP Server
Dependencies: C12832 EthernetInterface mbed-rtos mbed ConfigFile
TcpDaemon.cpp@9:60ce5e733ea6, 2015-06-15 (annotated)
- Committer:
- dwini
- Date:
- Mon Jun 15 14:41:41 2015 +0000
- Revision:
- 9:60ce5e733ea6
- Parent:
- 8:845dfadaa70d
Add config file
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 | 5:7a32c081a3fa | 3 | #include "StatusIndicator.h" |
dwini | 1:8efef658d90b | 4 | |
dwini | 2:a8eebf64cd3e | 5 | // Incoming message end |
dwini | 1:8efef658d90b | 6 | #define END_MSG_SEQUENCE "\r\n" |
dwini | 1:8efef658d90b | 7 | |
dwini | 1:8efef658d90b | 8 | namespace MachineVision{ |
dwini | 1:8efef658d90b | 9 | /* |
dwini | 1:8efef658d90b | 10 | * TcpDaemon constructor |
dwini | 1:8efef658d90b | 11 | * |
dwini | 1:8efef658d90b | 12 | * @server_port the port the daemon will be listening on |
dwini | 1:8efef658d90b | 13 | */ |
dwini | 8:845dfadaa70d | 14 | TcpDaemon::TcpDaemon(int server_port, PinName accept_led_pin, PinName receive_led_pin, StatusIndicator * indicator) |
dwini | 7:23c8d34000eb | 15 | : receive_led(receive_led_pin), accept_led(accept_led_pin) { |
dwini | 1:8efef658d90b | 16 | this->server_port = server_port; |
dwini | 1:8efef658d90b | 17 | this->keepListening = true; |
dwini | 2:a8eebf64cd3e | 18 | this->receive_led = 0; |
dwini | 3:254a2671a8e3 | 19 | this->accept_led = 0; |
dwini | 5:7a32c081a3fa | 20 | this->status_indicator = indicator; |
dwini | 1:8efef658d90b | 21 | } |
dwini | 1:8efef658d90b | 22 | |
dwini | 1:8efef658d90b | 23 | /* |
dwini | 1:8efef658d90b | 24 | * Make the daemon start listening for incoming connections |
dwini | 1:8efef658d90b | 25 | */ |
dwini | 1:8efef658d90b | 26 | void TcpDaemon::startListening() { |
dwini | 1:8efef658d90b | 27 | if (this->bindSocket()) { |
dwini | 1:8efef658d90b | 28 | this->doListen(); |
dwini | 1:8efef658d90b | 29 | } |
dwini | 1:8efef658d90b | 30 | } |
dwini | 1:8efef658d90b | 31 | |
dwini | 1:8efef658d90b | 32 | /* |
dwini | 1:8efef658d90b | 33 | * Bind to server socket |
dwini | 1:8efef658d90b | 34 | * |
dwini | 1:8efef658d90b | 35 | * @return true on success |
dwini | 1:8efef658d90b | 36 | */ |
dwini | 1:8efef658d90b | 37 | bool TcpDaemon::bindSocket() { |
dwini | 1:8efef658d90b | 38 | if(server.bind(server_port) < 0) { |
dwini | 1:8efef658d90b | 39 | Log::e("Bind failed. Error\r\n"); |
dwini | 1:8efef658d90b | 40 | return false; |
dwini | 1:8efef658d90b | 41 | } else { |
dwini | 1:8efef658d90b | 42 | Log::d("Bind ok\r\n"); |
dwini | 3:254a2671a8e3 | 43 | server.set_blocking(false, TCP_ACCEPT_TIMEOUT); // Set tot non-blocking |
dwini | 1:8efef658d90b | 44 | return true; |
dwini | 1:8efef658d90b | 45 | } |
dwini | 1:8efef658d90b | 46 | } |
dwini | 1:8efef658d90b | 47 | |
dwini | 1:8efef658d90b | 48 | /* |
dwini | 1:8efef658d90b | 49 | * Listen for incoming connections |
dwini | 1:8efef658d90b | 50 | */ |
dwini | 1:8efef658d90b | 51 | void TcpDaemon::doListen() { |
dwini | 1:8efef658d90b | 52 | |
dwini | 1:8efef658d90b | 53 | // Listen for incoming connection |
dwini | 1:8efef658d90b | 54 | if (server.listen(MAX_BACKLOG) < 0) { |
dwini | 1:8efef658d90b | 55 | Log::w("Listen failed\r\n"); |
dwini | 1:8efef658d90b | 56 | return; |
dwini | 1:8efef658d90b | 57 | } |
dwini | 1:8efef658d90b | 58 | |
dwini | 3:254a2671a8e3 | 59 | Log::d("Listening for incoming connection ...\r\n"); |
dwini | 1:8efef658d90b | 60 | while (this->keepListening) { |
dwini | 3:254a2671a8e3 | 61 | |
dwini | 3:254a2671a8e3 | 62 | // Visual indication |
dwini | 3:254a2671a8e3 | 63 | accept_led = !accept_led; |
dwini | 1:8efef658d90b | 64 | |
dwini | 1:8efef658d90b | 65 | // Accept connection from an incoming client |
dwini | 3:254a2671a8e3 | 66 | if (server.accept(client) >= 0) { |
dwini | 1:8efef658d90b | 67 | Log::d("Client connected: %s\r\n", client.get_address()); |
dwini | 1:8efef658d90b | 68 | |
dwini | 1:8efef658d90b | 69 | // Set non-blocking |
dwini | 1:8efef658d90b | 70 | client.set_blocking(false, TCP_TIMEOUT); |
dwini | 1:8efef658d90b | 71 | |
dwini | 1:8efef658d90b | 72 | while (client.is_connected()) { |
dwini | 1:8efef658d90b | 73 | // Keep receiving messages from the client |
dwini | 1:8efef658d90b | 74 | int read_size = 0; |
dwini | 1:8efef658d90b | 75 | int total_read_size = 0; |
dwini | 1:8efef658d90b | 76 | char * end = NULL; |
dwini | 2:a8eebf64cd3e | 77 | int i_read = 0; |
dwini | 1:8efef658d90b | 78 | |
dwini | 2:a8eebf64cd3e | 79 | int buffer_size = BUFFER_SIZE; |
dwini | 2:a8eebf64cd3e | 80 | char * buffer_offset = buffer; |
dwini | 2:a8eebf64cd3e | 81 | |
dwini | 2:a8eebf64cd3e | 82 | // Read full message from client |
dwini | 2:a8eebf64cd3e | 83 | Log::v("Waiting for message\r\n"); |
dwini | 2:a8eebf64cd3e | 84 | do { |
dwini | 2:a8eebf64cd3e | 85 | read_size = client.receive(buffer_offset, buffer_size); |
dwini | 2:a8eebf64cd3e | 86 | receive_led = !receive_led; |
dwini | 1:8efef658d90b | 87 | |
dwini | 2:a8eebf64cd3e | 88 | if (read_size > 0) { |
dwini | 2:a8eebf64cd3e | 89 | total_read_size += read_size; |
dwini | 2:a8eebf64cd3e | 90 | |
dwini | 2:a8eebf64cd3e | 91 | // Null-terminate string |
dwini | 2:a8eebf64cd3e | 92 | buffer[total_read_size] = '\0'; |
dwini | 2:a8eebf64cd3e | 93 | Log::v("Received partial: %s\r\n", buffer); |
dwini | 2:a8eebf64cd3e | 94 | |
dwini | 2:a8eebf64cd3e | 95 | // Search for END |
dwini | 2:a8eebf64cd3e | 96 | end = strstr(buffer, END_MSG_SEQUENCE); |
dwini | 2:a8eebf64cd3e | 97 | |
dwini | 2:a8eebf64cd3e | 98 | buffer_size = BUFFER_SIZE-total_read_size; |
dwini | 2:a8eebf64cd3e | 99 | buffer_offset = buffer+total_read_size; |
dwini | 2:a8eebf64cd3e | 100 | } else if (total_read_size > 0) { // Increment i_read (max timeouts for message) |
dwini | 2:a8eebf64cd3e | 101 | i_read++; |
dwini | 2:a8eebf64cd3e | 102 | } |
dwini | 3:254a2671a8e3 | 103 | } while (client.is_connected() && total_read_size < BUFFER_SIZE && end == NULL && i_read < MAX_READ_TIMEOUTS); |
dwini | 1:8efef658d90b | 104 | |
dwini | 3:254a2671a8e3 | 105 | if (end == NULL) { |
dwini | 3:254a2671a8e3 | 106 | if (total_read_size >= BUFFER_SIZE) { |
dwini | 1:8efef658d90b | 107 | Log::w("Buffer full\r\n"); |
dwini | 3:254a2671a8e3 | 108 | } else if (i_read == MAX_READ_TIMEOUTS) { |
dwini | 3:254a2671a8e3 | 109 | Log::w("Partial message received. MAX_READ_TIMEOUTS reached.\r\n"); |
dwini | 1:8efef658d90b | 110 | } |
dwini | 3:254a2671a8e3 | 111 | |
dwini | 3:254a2671a8e3 | 112 | } else { |
dwini | 3:254a2671a8e3 | 113 | // Full string received, lets do our thing |
dwini | 3:254a2671a8e3 | 114 | Log::v("Received: %s\r\n", buffer); |
dwini | 5:7a32c081a3fa | 115 | |
dwini | 5:7a32c081a3fa | 116 | if (strcmp(buffer, STR_OK) == 0) { |
dwini | 5:7a32c081a3fa | 117 | status_indicator->setStatus(OK); |
dwini | 5:7a32c081a3fa | 118 | } else if (strcmp(buffer, STR_FAIL) == 0) { |
dwini | 5:7a32c081a3fa | 119 | status_indicator->setStatus(FAIL); |
dwini | 5:7a32c081a3fa | 120 | } else if (strcmp(buffer, STR_CLEAR) == 0) { |
dwini | 5:7a32c081a3fa | 121 | status_indicator->setStatus(CLEAR); |
dwini | 5:7a32c081a3fa | 122 | } else { |
dwini | 5:7a32c081a3fa | 123 | Log::w("Received unknown message: %s\r\n", buffer); |
dwini | 5:7a32c081a3fa | 124 | } |
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 | } |