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