Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Dependencies: EthernetInterface NetworkAPI mbed-rtos mbed
Fork of NetRelais by
controller.cpp
00001 /** 00002 * Copyright (c) 2012, Roy van Dam <roy@vandam-innovations.com> 00003 * All rights reserved. 00004 * 00005 * Redistribution and use in source and binary forms, with or without 00006 * modification, are permitted provided that the following conditions are met: 00007 * 00008 * 1. Redistributions of source code must retain the above copyright notice, this 00009 * list of conditions and the following disclaimer. 00010 * 2. Redistributions in binary form must reproduce the above copyright notice, 00011 * this list of conditions and the following disclaimer in the documentation 00012 * and/or other materials provided with the distribution. 00013 * 00014 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 00015 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 00016 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 00017 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR 00018 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 00019 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 00020 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 00021 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 00022 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 00023 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 00024 */ 00025 00026 #include "controller.hpp" 00027 00028 Controller::~Controller() 00029 { 00030 this->stop(); 00031 } 00032 00033 int 00034 Controller::start(int port, int max_pending) 00035 { 00036 if (this->_network.server.open() < 0) { 00037 printf("Could not open server socket.\n\r"); 00038 return -1; 00039 } 00040 00041 if (this->_network.server.bind(port) < 0) { 00042 printf("Could not bind server socket to port '%d'.\n\r", port); 00043 return -1; 00044 } 00045 00046 if (this->_network.server.listen(max_pending) < 0) { 00047 printf("Could not put server socket into listening mode.\n\r"); 00048 return -1; 00049 } 00050 00051 return 0; 00052 } 00053 00054 int 00055 Controller::stop() 00056 { 00057 this->_network.server.close(); 00058 this->_network.client.close(); 00059 return 0; 00060 } 00061 00062 int 00063 Controller::dispatch() 00064 { 00065 int result = 0; 00066 network::Buffer buffer(256); 00067 00068 while (this->_network.server.getStatus() == network::Socket::Listening) { 00069 if (this->_network.server.accept(this->_network.client) < 0) { 00070 printf("Warning: failed to accept connection.\n\r"); 00071 continue; 00072 } 00073 00074 printf("Client connected '%s:%d'.\n\r", 00075 this->_network.client.getRemoteEndpoint().getAddress().toString().c_str(), 00076 this->_network.client.getRemoteEndpoint().getPort()); 00077 00078 while (this->_network.client.getStatus() == network::Socket::Connected) { 00079 buffer.flush(); 00080 00081 switch (this->_network.client.read(buffer)) { 00082 case -1: 00083 printf("Warning: failed to read data from client.\n\r"); 00084 break; 00085 00086 case 0: 00087 printf("Connection closed.\n\r"); 00088 break; 00089 00090 default: 00091 printf("Received %d bytes.\n\r%s\r", buffer.length(), (char *)buffer.data()); 00092 00093 // Parse command 00094 result = this->_parseCommand(buffer); 00095 00096 // Format reply code 00097 buffer.flush(); 00098 buffer.length(std::snprintf( 00099 (char *)buffer.data(), buffer.size(), 00100 "e;%i;", result)); 00101 00102 if (buffer.length() < 4) { 00103 printf("Warning: failed to format error reply.\n\r"); 00104 continue; 00105 } 00106 00107 if (this->_network.client.write(buffer) < 0) { 00108 printf("Warning: failed to reply.\n\r"); 00109 } 00110 continue; 00111 } 00112 00113 this->_network.client.shutdown(); 00114 this->_network.client.close(); 00115 } 00116 } 00117 00118 return 0; 00119 } 00120 00121 int 00122 Controller::_parseCommand(network::Buffer &buffer) 00123 { 00124 int index = 0; 00125 network::Buffer response(32); 00126 char *cursor = (char *)buffer.data(); 00127 00128 enum Controller::ParseState state = Controller::S_Init; 00129 enum Controller::Command command = Controller::C_None; 00130 00131 while (cursor != NULL) { 00132 switch (state) { 00133 case Controller::S_Init: { 00134 if (((*cursor) == 'r') && ((*(cursor + 1)) == ':')) { 00135 command = Controller::C_Read; 00136 state = Controller::S_Index; 00137 cursor += 2; 00138 continue; 00139 } 00140 00141 if (((*cursor) == 'w') && ((*(cursor + 1)) == ':')) { 00142 command = Controller::C_Write; 00143 state = Controller::S_Index; 00144 cursor += 2; 00145 continue; 00146 } 00147 00148 return Controller::E_InvalidCommand; 00149 } 00150 00151 case Controller::S_Index: { 00152 if (std::sscanf(cursor, "%d;", &index) != 1) { 00153 return Controller::E_InvalidFormat; 00154 } 00155 00156 char *offset; 00157 switch (command) { 00158 case Controller::C_Read: { 00159 offset = std::strchr(cursor, ';'); 00160 break; 00161 } 00162 00163 case Controller::C_Write: { 00164 offset = std::strchr(cursor, ':'); 00165 break; 00166 } 00167 } 00168 00169 if (offset == NULL) { 00170 return Controller::E_InvalidFormat; 00171 } 00172 00173 cursor = offset + 1; 00174 state = Controller::S_Execute; 00175 continue; 00176 } 00177 00178 case Controller::S_Execute: { 00179 switch (command) { 00180 case Controller::C_Read: { 00181 DigitalIn *input = this->getInput(index); 00182 if (input == NULL) { 00183 return Controller::E_UnknownIndex; 00184 } 00185 00186 response.length(std::snprintf( 00187 (char *)response.data(), response.size(), 00188 "r:%d:%d;", index, input->read())); 00189 00190 if (response.length() < 6) { 00191 printf("Warning: failed to format reply.\n\r"); 00192 return Controller::E_Internal; 00193 } 00194 00195 if (this->_network.client.write(response) < 0) { 00196 printf("Warning: failed to reply on read request.\n\r"); 00197 return Controller::E_Internal; 00198 } 00199 00200 if ((*cursor) == 0 || (*(cursor + 1)) == 0) { 00201 return 0; 00202 } 00203 00204 command = Controller::C_None; 00205 state = Controller::S_Init; 00206 continue; 00207 } 00208 00209 case Controller::C_Write: { 00210 DigitalOut *output = this->getOutput(index); 00211 if (output == NULL) { 00212 return Controller::E_UnknownIndex; 00213 } 00214 00215 int value = 0; 00216 if (std::sscanf(cursor, "%d;", &value) != 1) { 00217 return Controller::E_InvalidFormat; 00218 } 00219 00220 char *offset = std::strchr(cursor, ';'); 00221 if (offset == NULL) { 00222 return Controller::E_InvalidFormat; 00223 } 00224 cursor = offset + 1; 00225 00226 if (value != 0 && value != 1) { 00227 return Controller::E_InvalidValue; 00228 } 00229 00230 output->write(value); 00231 00232 if ((*cursor) == 0 || (*(cursor + 1)) == 0) { 00233 return 0; 00234 } 00235 00236 command = Controller::C_None; 00237 state = Controller::S_Init; 00238 continue; 00239 } 00240 } 00241 } 00242 } 00243 } 00244 00245 return 0; 00246 } 00247 00248 00249 int 00250 Controller::addOutput(DigitalOut *output) 00251 { 00252 if (this->_outputExists(output)) { 00253 return false; 00254 } 00255 00256 this->_io.output.push_back(output); 00257 return true; 00258 } 00259 00260 int 00261 Controller::addInput(DigitalIn *input) 00262 { 00263 if (this->_inputExists(input)) { 00264 return false; 00265 } 00266 00267 this->_io.input.push_back(input); 00268 return true; 00269 } 00270 00271 DigitalOut * 00272 Controller::getOutput(size_t index) 00273 { 00274 Controller::DigitalOutputList::iterator output; 00275 output = this->_io.output.begin(); 00276 output = output + (int)index; 00277 00278 if (output >= this->_io.output.end()) { 00279 return NULL; 00280 } 00281 00282 return (*output); 00283 } 00284 00285 DigitalIn * 00286 Controller::getInput(size_t index) 00287 { 00288 DigitalInputList::iterator input; 00289 input = this->_io.input.begin(); 00290 input = input + (int)index; 00291 00292 if (input >= this->_io.input.end()) { 00293 return NULL; 00294 } 00295 00296 return (*input); 00297 } 00298 00299 bool 00300 Controller::_outputExists(DigitalOut *output) 00301 { 00302 DigitalOutputList::iterator entry; 00303 entry = this->_io.output.begin(); 00304 for (;entry != this->_io.output.end(); entry++) { 00305 if (output == (*entry)) { 00306 return true; 00307 } 00308 } 00309 00310 return false; 00311 } 00312 00313 bool 00314 Controller::_inputExists(DigitalIn *input) 00315 { 00316 Controller::DigitalInputList::iterator entry; 00317 entry = this->_io.input.begin(); 00318 for (;entry != this->_io.input.end(); entry++) { 00319 if (input == (*entry)) { 00320 return true; 00321 } 00322 } 00323 00324 return false; 00325 }
Generated on Tue Jul 19 2022 10:03:11 by
