00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024 #include <plugin/manager.h>
00025 #include <plugin/net/handler.h>
00026 #include <plugin/net/messages.h>
00027 #include <plugin/net/list_message.h>
00028
00029 #include <utils/logging/liblogger.h>
00030
00031 #include <netcomm/fawkes/component_ids.h>
00032 #include <netcomm/fawkes/hub.h>
00033
00034 #include <algorithm>
00035 #include <cstring>
00036 #include <cstdlib>
00037 #include <cerrno>
00038
00039 namespace fawkes {
00040 #if 0
00041 }
00042 #endif
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066 PluginNetworkHandler::PluginNetworkHandler(PluginManager *manager, FawkesNetworkHub *hub)
00067 : Thread("PluginNetworkHandler", Thread::OPMODE_WAITFORWAKEUP),
00068 FawkesNetworkHandler(FAWKES_CID_PLUGINMANAGER)
00069 {
00070 __manager = manager;
00071 __hub = hub;
00072
00073 __manager->add_listener(this);
00074 __hub->add_handler(this);
00075 }
00076
00077
00078
00079 PluginNetworkHandler::~PluginNetworkHandler()
00080 {
00081 __hub->remove_handler(this);
00082 __manager->remove_listener(this);
00083 }
00084
00085
00086
00087
00088
00089
00090
00091
00092
00093
00094 PluginListMessage *
00095 PluginNetworkHandler::list_avail()
00096 {
00097 PluginListMessage *m = new PluginListMessage();
00098
00099 std::list<std::pair<std::string, std::string> > available_plugins;
00100 available_plugins = __manager->get_available_plugins();
00101
00102 std::list<std::pair<std::string, std::string> >::iterator i;
00103 for (i = available_plugins.begin(); i != available_plugins.end(); ++i) {
00104 m->append(i->first.c_str(), i->first.length());
00105 m->append(i->second.c_str(), i->second.length());
00106 }
00107 return m;
00108 }
00109
00110 PluginListMessage *
00111 PluginNetworkHandler::list_loaded()
00112 {
00113 PluginListMessage *m = new PluginListMessage();
00114
00115 std::list<std::string> loaded_plugins;
00116 loaded_plugins = __manager->get_loaded_plugins();
00117
00118 std::list<std::string>::iterator i;
00119 for (i = loaded_plugins.begin(); i != loaded_plugins.end(); ++i) {
00120 m->append(i->c_str(), i->length());
00121 }
00122
00123 return m;
00124 }
00125
00126
00127 void
00128 PluginNetworkHandler::send_load_failure(const char *plugin_name,
00129 unsigned int client_id)
00130 {
00131 try {
00132 plugin_load_failed_msg_t *r = (plugin_load_failed_msg_t *)calloc(1, sizeof(plugin_load_failed_msg_t));
00133 strncpy(r->name, plugin_name, PLUGIN_MSG_NAME_LENGTH);
00134 __hub->send(client_id, FAWKES_CID_PLUGINMANAGER, MSG_PLUGIN_LOAD_FAILED,
00135 r, sizeof(plugin_load_failed_msg_t));
00136 } catch (Exception &e) {
00137 LibLogger::log_warn("PluginNetworkHandler", "Failed to send load failure, exception follows");
00138 LibLogger::log_warn("PluginNetworkHandler", e);
00139 }
00140 }
00141
00142
00143 void
00144 PluginNetworkHandler::send_load_success(const char *plugin_name, unsigned int client_id)
00145 {
00146 try {
00147 plugin_loaded_msg_t *r = (plugin_loaded_msg_t *)calloc(1, sizeof(plugin_loaded_msg_t));
00148 strncpy(r->name, plugin_name, PLUGIN_MSG_NAME_LENGTH);
00149 __hub->send(client_id, FAWKES_CID_PLUGINMANAGER, MSG_PLUGIN_LOADED,
00150 r, sizeof(plugin_loaded_msg_t));
00151 } catch (Exception &e) {
00152 LibLogger::log_warn("PluginNetworkHandler", "Failed to send load success, exception follows");
00153 LibLogger::log_warn("PluginNetworkHandler", e);
00154 }
00155 }
00156
00157
00158 void
00159 PluginNetworkHandler::send_unloaded(const char *plugin_name)
00160 {
00161 __subscribers.lock();
00162 try {
00163 for (__ssit = __subscribers.begin(); __ssit != __subscribers.end(); ++__ssit) {
00164 send_unload_success(plugin_name, *__ssit);
00165 }
00166 } catch (Exception &e) {
00167 LibLogger::log_warn("PluginNetworkHandler", "Failed to send unloaded, exception follows");
00168 LibLogger::log_warn("PluginNetworkHandler", e);
00169 }
00170 __subscribers.unlock();
00171 }
00172
00173
00174 void
00175 PluginNetworkHandler::send_loaded(const char *plugin_name)
00176 {
00177 __subscribers.lock();
00178 try {
00179 for (__ssit = __subscribers.begin(); __ssit != __subscribers.end(); ++__ssit) {
00180 send_load_success(plugin_name, *__ssit);
00181 }
00182 } catch (Exception &e) {
00183 LibLogger::log_warn("PluginNetworkHandler", "Failed to send loaded, exception follows");
00184 LibLogger::log_warn("PluginNetworkHandler", e);
00185 }
00186 __subscribers.unlock();
00187 }
00188
00189
00190 void
00191 PluginNetworkHandler::send_unload_failure(const char *plugin_name,
00192 unsigned int client_id)
00193 {
00194 try {
00195 plugin_unload_failed_msg_t *r = (plugin_unload_failed_msg_t *)calloc(1, sizeof(plugin_unload_failed_msg_t));
00196 strncpy(r->name, plugin_name, PLUGIN_MSG_NAME_LENGTH);
00197 __hub->send(client_id, FAWKES_CID_PLUGINMANAGER, MSG_PLUGIN_UNLOAD_FAILED,
00198 r, sizeof(plugin_unload_failed_msg_t));
00199 } catch (Exception &e) {
00200 LibLogger::log_warn("PluginNetworkHandler", "Failed to send unload failure, exception follows");
00201 LibLogger::log_warn("PluginNetworkHandler", e);
00202 }
00203 }
00204
00205
00206 void
00207 PluginNetworkHandler::send_unload_success(const char *plugin_name, unsigned int client_id)
00208 {
00209 try {
00210 plugin_unloaded_msg_t *r = (plugin_unloaded_msg_t *)calloc(1, sizeof(plugin_unloaded_msg_t));
00211 strncpy(r->name, plugin_name, PLUGIN_MSG_NAME_LENGTH);
00212 __hub->send(client_id, FAWKES_CID_PLUGINMANAGER, MSG_PLUGIN_UNLOADED,
00213 r, sizeof(plugin_unloaded_msg_t));
00214 } catch (Exception &e) {
00215 LibLogger::log_warn("PluginNetworkHandler", "Failed to send unload success, exception follows");
00216 LibLogger::log_warn("PluginNetworkHandler", e);
00217 }
00218 }
00219
00220
00221
00222
00223
00224
00225
00226
00227
00228
00229
00230 void
00231 PluginNetworkHandler::load(const char *plugin_list, unsigned int clid)
00232 {
00233 try {
00234 __manager->load(plugin_list);
00235 send_load_success(plugin_list, clid);
00236 } catch (Exception &e) {
00237 LibLogger::log_error("PluginNetworkHandler", "Failed to load plugin %s", plugin_list);
00238 LibLogger::log_error("PluginNetworkHandler", e);
00239 send_load_failure(plugin_list, clid);
00240 }
00241 }
00242
00243
00244
00245
00246
00247
00248
00249
00250
00251 void
00252 PluginNetworkHandler::unload(const char *plugin_name, unsigned int clid)
00253 {
00254 try {
00255 __manager->unload(plugin_name);
00256 send_unload_success(plugin_name, clid);
00257 } catch (Exception &e) {
00258 LibLogger::log_error("PluginNetworkHandler", "Failed to unload plugin %s", plugin_name);
00259 LibLogger::log_error("PluginNetworkHandler", e);
00260 send_unload_failure(plugin_name, clid);
00261 }
00262 }
00263
00264
00265
00266
00267 void
00268 PluginNetworkHandler::loop()
00269 {
00270 while ( ! __inbound_queue.empty() ) {
00271 FawkesNetworkMessage *msg = __inbound_queue.front();
00272
00273 switch (msg->msgid()) {
00274 case MSG_PLUGIN_LOAD:
00275 if ( msg->payload_size() != sizeof(plugin_load_msg_t) ) {
00276 LibLogger::log_error("PluginNetworkHandler", "Invalid load message size");
00277 } else {
00278 plugin_load_msg_t *m = (plugin_load_msg_t *)msg->payload();
00279 char name[PLUGIN_MSG_NAME_LENGTH + 1];
00280 name[PLUGIN_MSG_NAME_LENGTH] = 0;
00281 strncpy(name, m->name, PLUGIN_MSG_NAME_LENGTH);
00282
00283 if ( __manager->is_loaded(name) ) {
00284 LibLogger::log_info("PluginNetworkHandler", "Client requested loading of %s which is already loaded", name);
00285 send_load_success(name, msg->clid());
00286 } else {
00287 LibLogger::log_info("PluginNetworkHandler", "Loading plugin %s", name);
00288 load(name, msg->clid());
00289 }
00290 }
00291 break;
00292
00293 case MSG_PLUGIN_UNLOAD:
00294 if ( msg->payload_size() != sizeof(plugin_unload_msg_t) ) {
00295 LibLogger::log_error("PluginNetworkHandler", "Invalid unload message size.");
00296 } else {
00297 plugin_unload_msg_t *m = (plugin_unload_msg_t *)msg->payload();
00298 char name[PLUGIN_MSG_NAME_LENGTH + 1];
00299 name[PLUGIN_MSG_NAME_LENGTH] = 0;
00300 strncpy(name, m->name, PLUGIN_MSG_NAME_LENGTH);
00301
00302 if ( !__manager->is_loaded(name) ) {
00303 LibLogger::log_info("PluginNetworkHandler", "Client requested unloading of %s which is not loaded", name);
00304 send_unload_success(name, msg->clid());
00305 } else {
00306 LibLogger::log_info("PluginNetworkHandler", "UNloading plugin %s", name);
00307 unload(name, msg->clid());
00308 }
00309 }
00310 break;
00311
00312 case MSG_PLUGIN_LIST_AVAIL:
00313 try {
00314 LibLogger::log_debug("PluginNetworkHandler", "Sending list of all available plugins");
00315 PluginListMessage *plm = list_avail();
00316 __hub->send(msg->clid(), FAWKES_CID_PLUGINMANAGER, MSG_PLUGIN_AVAIL_LIST, plm);
00317 } catch (Exception &e) {
00318 __hub->send(msg->clid(), FAWKES_CID_PLUGINMANAGER, MSG_PLUGIN_AVAIL_LIST_FAILED);
00319 }
00320 break;
00321
00322 case MSG_PLUGIN_LIST_LOADED:
00323 try {
00324 LibLogger::log_debug("PluginNetworkHandler", "Sending list of all loaded plugins");
00325 PluginListMessage *plm = list_loaded();
00326 __hub->send(msg->clid(), FAWKES_CID_PLUGINMANAGER, MSG_PLUGIN_LOADED_LIST, plm);
00327 } catch (Exception &e) {
00328 __hub->send(msg->clid(), FAWKES_CID_PLUGINMANAGER, MSG_PLUGIN_LOADED_LIST_FAILED);
00329 }
00330 break;
00331
00332 case MSG_PLUGIN_SUBSCRIBE_WATCH:
00333 __subscribers.lock();
00334 __subscribers.push_back(msg->clid());
00335 __subscribers.sort();
00336 __subscribers.unique();
00337 __subscribers.unlock();
00338 break;
00339
00340 case MSG_PLUGIN_UNSUBSCRIBE_WATCH:
00341 __subscribers.remove_locked(msg->clid());
00342 break;
00343
00344 default:
00345
00346 break;
00347 }
00348
00349 msg->unref();
00350 __inbound_queue.pop_locked();
00351 }
00352 }
00353
00354
00355 void
00356 PluginNetworkHandler::handle_network_message(FawkesNetworkMessage *msg)
00357 {
00358 msg->ref();
00359 __inbound_queue.push_locked(msg);
00360 wakeup();
00361 }
00362
00363
00364 void
00365 PluginNetworkHandler::client_connected(unsigned int clid)
00366 {
00367 }
00368
00369
00370 void
00371 PluginNetworkHandler::client_disconnected(unsigned int clid)
00372 {
00373 __subscribers.remove_locked(clid);
00374 }
00375
00376 void
00377 PluginNetworkHandler::plugin_loaded(const char *plugin_name)
00378 {
00379 send_loaded(plugin_name);
00380 }
00381
00382 void
00383 PluginNetworkHandler::plugin_unloaded(const char *plugin_name)
00384 {
00385 send_unloaded(plugin_name);
00386 }
00387
00388 }