|
IBR-DTNSuite 0.6
|
00001 /* 00002 * ClientHandler.cpp 00003 * 00004 * Created on: 24.06.2009 00005 * Author: morgenro 00006 */ 00007 00008 #include "config.h" 00009 #include "Configuration.h" 00010 #include "api/ClientHandler.h" 00011 #include "api/BinaryStreamClient.h" 00012 #include "core/BundleCore.h" 00013 #include <ibrcommon/Logger.h> 00014 #include <ibrdtn/utils/Utils.h> 00015 00016 namespace dtn 00017 { 00018 namespace api 00019 { 00020 ProtocolHandler::ProtocolHandler(ClientHandler &client, ibrcommon::tcpstream &stream) 00021 : _client(client), _stream(stream) 00022 { 00023 } 00024 00025 ProtocolHandler::~ProtocolHandler() 00026 {} 00027 00028 ClientHandler::ClientHandler(ApiServerInterface &srv, Registration ®istration, ibrcommon::tcpstream *conn) 00029 : _srv(srv), _registration(registration), _stream(conn), _endpoint(dtn::core::BundleCore::local), _handler(NULL) 00030 { 00031 if ( dtn::daemon::Configuration::getInstance().getNetwork().getTCPOptionNoDelay() ) 00032 { 00033 _stream->enableNoDelay(); 00034 } 00035 } 00036 00037 ClientHandler::~ClientHandler() 00038 { 00039 delete _stream; 00040 } 00041 00042 Registration& ClientHandler::getRegistration() 00043 { 00044 return _registration; 00045 } 00046 00047 ApiServerInterface& ClientHandler::getAPIServer() 00048 { 00049 return _srv; 00050 } 00051 00052 void ClientHandler::setup() 00053 { 00054 } 00055 00056 void ClientHandler::run() 00057 { 00058 // signal the active connection to the server 00059 _srv.connectionUp(this); 00060 00061 std::string buffer; 00062 00063 while (_stream->good()) 00064 { 00065 if (_handler != NULL) 00066 { 00067 _handler->setup(); 00068 _handler->run(); 00069 delete _handler; 00070 _handler = NULL; 00071 continue; 00072 } 00073 00074 getline(*_stream, buffer); 00075 00076 std::vector<std::string> cmd = dtn::utils::Utils::tokenize(" ", buffer); 00077 if (cmd.size() == 0) continue; 00078 00079 try { 00080 if (cmd[0] == "protocol") 00081 { 00082 if (cmd[1] == "tcpcl") 00083 { 00084 // switch to binary protocol (old style api) 00085 _handler = new BinaryStreamClient(*this, *_stream); 00086 continue; 00087 } 00088 else 00089 { 00090 error(API_STATUS_NOT_ACCEPTABLE, "UNKNOWN PROTOCOL"); 00091 } 00092 } 00093 else 00094 { 00095 // forward to standard command set 00096 processCommand(cmd); 00097 } 00098 } catch (const std::exception&) { 00099 error(API_STATUS_BAD_REQUEST, "PROTOCOL ERROR"); 00100 } 00101 } 00102 } 00103 00104 void ClientHandler::error(STATUS_CODES code, const std::string &msg) 00105 { 00106 ibrcommon::MutexLock l(_write_lock); 00107 (*_stream) << code << " " << msg << std::endl; 00108 } 00109 00110 bool ClientHandler::__cancellation() 00111 { 00112 // close the stream 00113 (*_stream).close(); 00114 00115 return true; 00116 } 00117 00118 void ClientHandler::finally() 00119 { 00120 IBRCOMMON_LOGGER_DEBUG(60) << "ApiConnection down" << IBRCOMMON_LOGGER_ENDL; 00121 00122 // remove the client from the list in ApiServer 00123 _srv.connectionDown(this); 00124 00125 _registration.abort(); 00126 _srv.freeRegistration(_registration); 00127 00128 // close the stream 00129 try { 00130 (*_stream).close(); 00131 } catch (const ibrcommon::ConnectionClosedException&) { }; 00132 } 00133 00134 void ClientHandler::eventNodeAvailable(const dtn::core::Node &node) 00135 { 00136 } 00137 00138 void ClientHandler::eventNodeUnavailable(const dtn::core::Node &node) 00139 { 00140 } 00141 00142 void ClientHandler::processCommand(const std::vector<std::string> &cmd) 00143 { 00144 try { 00145 if (cmd[0] == "set") 00146 { 00147 if (cmd.size() < 2) throw ibrcommon::Exception("not enough parameters"); 00148 00149 if (cmd[1] == "endpoint") 00150 { 00151 if (cmd.size() < 3) throw ibrcommon::Exception("not enough parameters"); 00152 00153 ibrcommon::MutexLock l(_write_lock); 00154 _endpoint = dtn::core::BundleCore::local + "/" + cmd[2]; 00155 00156 // error checking 00157 if (_endpoint == dtn::data::EID()) 00158 { 00159 (*_stream) << API_STATUS_NOT_ACCEPTABLE << " INVALID ENDPOINT" << std::endl; 00160 _endpoint = dtn::core::BundleCore::local; 00161 } 00162 else 00163 { 00164 _registration.subscribe(_endpoint); 00165 (*_stream) << API_STATUS_ACCEPTED << " OK" << std::endl; 00166 } 00167 } 00168 else 00169 { 00170 ibrcommon::MutexLock l(_write_lock); 00171 (*_stream) << API_STATUS_BAD_REQUEST << " UNKNOWN COMMAND" << std::endl; 00172 } 00173 } 00174 else if (cmd[0] == "registration") 00175 { 00176 if (cmd.size() < 2) throw ibrcommon::Exception("not enough parameters"); 00177 00178 if (cmd[1] == "add") 00179 { 00180 if (cmd.size() < 3) throw ibrcommon::Exception("not enough parameters"); 00181 00182 ibrcommon::MutexLock l(_write_lock); 00183 dtn::data::EID endpoint(cmd[2]); 00184 00185 // error checking 00186 if (endpoint == dtn::data::EID()) 00187 { 00188 (*_stream) << API_STATUS_NOT_ACCEPTABLE << " INVALID EID" << std::endl; 00189 } 00190 else 00191 { 00192 _registration.subscribe(endpoint); 00193 (*_stream) << API_STATUS_ACCEPTED << " OK" << std::endl; 00194 } 00195 } 00196 else if (cmd[1] == "del") 00197 { 00198 if (cmd.size() < 3) throw ibrcommon::Exception("not enough parameters"); 00199 00200 ibrcommon::MutexLock l(_write_lock); 00201 dtn::data::EID endpoint(cmd[2]); 00202 00203 // error checking 00204 if (endpoint == dtn::data::EID()) 00205 { 00206 (*_stream) << API_STATUS_NOT_ACCEPTABLE << " INVALID EID" << std::endl; 00207 } 00208 else 00209 { 00210 _registration.unsubscribe(endpoint); 00211 (*_stream) << API_STATUS_ACCEPTED << " OK" << std::endl; 00212 } 00213 } 00214 else if (cmd[1] == "list") 00215 { 00216 ibrcommon::MutexLock l(_write_lock); 00217 const std::set<dtn::data::EID> &list = _registration.getSubscriptions(); 00218 00219 (*_stream) << API_STATUS_OK << " REGISTRATION LIST" << std::endl; 00220 for (std::set<dtn::data::EID>::const_iterator iter = list.begin(); iter != list.end(); iter++) 00221 { 00222 (*_stream) << (*iter).getString() << std::endl; 00223 } 00224 (*_stream) << std::endl; 00225 } 00226 else 00227 { 00228 ibrcommon::MutexLock l(_write_lock); 00229 (*_stream) << API_STATUS_BAD_REQUEST << " UNKNOWN COMMAND" << std::endl; 00230 } 00231 } 00232 else if (cmd[0] == "neighbor") 00233 { 00234 if (cmd.size() < 2) throw ibrcommon::Exception("not enough parameters"); 00235 00236 if (cmd[1] == "list") 00237 { 00238 ibrcommon::MutexLock l(_write_lock); 00239 const std::set<dtn::core::Node> nlist = dtn::core::BundleCore::getInstance().getNeighbors(); 00240 00241 (*_stream) << API_STATUS_OK << " NEIGHBOR LIST" << std::endl; 00242 for (std::set<dtn::core::Node>::const_iterator iter = nlist.begin(); iter != nlist.end(); iter++) 00243 { 00244 (*_stream) << (*iter).getEID().getString() << std::endl; 00245 } 00246 (*_stream) << std::endl; 00247 } 00248 else 00249 { 00250 ibrcommon::MutexLock l(_write_lock); 00251 (*_stream) << API_STATUS_BAD_REQUEST << " UNKNOWN COMMAND" << std::endl; 00252 } 00253 } 00254 else 00255 { 00256 ibrcommon::MutexLock l(_write_lock); 00257 (*_stream) << API_STATUS_BAD_REQUEST << " UNKNOWN COMMAND" << std::endl; 00258 } 00259 } catch (const std::exception&) { 00260 ibrcommon::MutexLock l(_write_lock); 00261 (*_stream) << API_STATUS_BAD_REQUEST << " ERROR" << std::endl; 00262 } 00263 } 00264 } 00265 }