00001
00019 #include <memory>
00020 #include <coil/UUID.h>
00021 #include <coil/Guard.h>
00022 #include <coil/stringutil.h>
00023 #include <rtm/RTObject.h>
00024 #include <rtm/CORBA_SeqUtil.h>
00025 #include <rtm/SdoServiceAdmin.h>
00026 #include <rtm/SdoServiceProviderBase.h>
00027 #include <rtm/SdoServiceConsumerBase.h>
00028
00029 namespace RTC
00030 {
00031 typedef coil::Guard<coil::Mutex> Guard;
00032
00040 struct service_id
00041 {
00042 service_id(const char* id) : m_id(id) {};
00043 bool operator()(const SDOPackage::ServiceProfile& s)
00044 {
00045 std::string id(s.id);
00046 return m_id == id;
00047 }
00048 const std::string m_id;
00049 };
00050
00051
00059 SdoServiceAdmin::SdoServiceAdmin(::RTC::RTObject_impl& rtobj)
00060 : m_rtobj(rtobj), m_allConsumerEnabled(true),
00061 rtclog("SdoServiceAdmin")
00062 {
00063 RTC_TRACE(("SdoServiceAdmin::SdoServiceAdmin(%s)",
00064 rtobj.getProperties()["instance_name"].c_str()));
00065
00066 ::coil::Properties& prop(m_rtobj.getProperties());
00067
00068
00069
00070 ::coil::vstring enabledProviderTypes
00071 = ::coil::split(prop["sdo.service.provider.enabled_services"], ",", true);
00072 RTC_DEBUG(("sdo.service.provider.enabled_services: %s",
00073 prop["sdo.service.provider.enabled_services"].c_str()));
00074
00075 ::coil::vstring availableProviderTypes
00076 = SdoServiceProviderFactory::instance().getIdentifiers();
00077 prop["sdo.service.provider.available_services"]
00078 = coil::flatten(availableProviderTypes);
00079 RTC_DEBUG(("sdo.service.provider.available_services: %s",
00080 prop["sdo.service.provider.available_services"].c_str()));
00081
00082
00083
00084 ::coil::vstring activeProviderTypes;
00085 for (size_t i(0); i < enabledProviderTypes.size(); ++i)
00086 {
00087 std::string tmp(enabledProviderTypes[i]);
00088 coil::toLower(tmp);
00089 if (tmp == "all")
00090 {
00091 activeProviderTypes = availableProviderTypes;
00092 RTC_DEBUG(("sdo.service.provider.enabled_services: ALL"));
00093 break;
00094 }
00095 for (size_t j(0); j < availableProviderTypes.size(); ++j)
00096 {
00097 if (availableProviderTypes[j] == enabledProviderTypes[i])
00098 {
00099 activeProviderTypes.push_back(availableProviderTypes[j]);
00100 }
00101 }
00102 }
00103
00104 SdoServiceProviderFactory& factory(SdoServiceProviderFactory::instance());
00105 for (size_t i(0); i < activeProviderTypes.size(); ++i)
00106 {
00107 SdoServiceProviderBase* svc
00108 = factory.createObject(activeProviderTypes[i]);
00109
00110 SDOPackage::ServiceProfile prof;
00111 prof.id = CORBA::string_dup(activeProviderTypes[i].c_str());
00112 prof.interface_type = CORBA::string_dup(activeProviderTypes[i].c_str());
00113 prof.service = svc->_this();
00114 std::string propkey = ifrToKey(activeProviderTypes[i]);
00115 NVUtil::copyFromProperties(prof.properties,
00116 prop.getNode(propkey.c_str()));
00117
00118 svc->init(rtobj, prof);
00119 m_providers.push_back(svc);
00120 }
00121
00122
00123
00124
00125
00126 ::std::string constypes = prop["sdo.service.consumer.enabled_services"];
00127 m_consumerTypes = ::coil::split(constypes, ",", true);
00128 RTC_DEBUG(("sdo.service.consumer.enabled_services: %s", constypes.c_str()));
00129
00130 prop["sdo.service.consumer.available_services"]
00131 = coil::flatten(SdoServiceConsumerFactory::instance().getIdentifiers());
00132 RTC_DEBUG(("sdo.service.consumer.available_services: %s",
00133 prop["sdo.service.consumer.available_services"].c_str()));
00134
00135
00136 for (size_t i(0); i < m_consumerTypes.size(); ++i)
00137 {
00138 std::string tmp(m_consumerTypes[i]);
00139 coil::toLower(tmp);
00140 if (tmp == "all")
00141 {
00142 m_allConsumerEnabled = true;
00143 RTC_DEBUG(("sdo.service.consumer.enabled_services: ALL"));
00144 }
00145 }
00146 }
00147
00155 SdoServiceAdmin::~SdoServiceAdmin()
00156 {
00157 for (size_t i(0); i < m_providers.size(); ++i)
00158 {
00159 m_providers[i]->finalize();
00160 delete m_providers[i];
00161 }
00162 m_providers.clear();
00163
00164 for (size_t i(0); i < m_consumers.size(); ++i)
00165 {
00166 m_consumers[i]->finalize();
00167 delete m_consumers[i];
00168 }
00169 m_consumers.clear();
00170 }
00171
00179 SDOPackage::ServiceProfileList* SdoServiceAdmin::getServiceProviderProfiles()
00180 {
00181 SDOPackage::ServiceProfileList_var prof
00182 = new SDOPackage::ServiceProfileList();
00183 SDOPackage::ServiceProfileList prof2;
00184 Guard guard(m_provider_mutex);
00185 for (size_t i(0); i < m_providers.size(); ++i)
00186 {
00187 CORBA_SeqUtil::push_back(prof2, m_providers[i]->getProfile());
00188 }
00189 return prof._retn();
00190 }
00191
00199 SDOPackage::ServiceProfile*
00200 SdoServiceAdmin::getServiceProviderProfile(const char* id)
00201 {
00202 std::string idstr(id);
00203 Guard guard(m_provider_mutex);
00204 for (size_t i(0); i < m_providers.size(); ++i)
00205 {
00206 if (idstr == static_cast<const char*>(m_providers[i]->getProfile().id))
00207 {
00208 return new SDOPackage::ServiceProfile(m_providers[i]->getProfile());
00209 }
00210 }
00211 throw new SDOPackage::InvalidParameter();
00212 return new SDOPackage::ServiceProfile();
00213 }
00214
00222 SDOPackage::SDOService_ptr SdoServiceAdmin::getServiceProvider(const char* id)
00223 {
00224 SDOPackage::ServiceProfile_var prof;
00225 prof = getServiceProviderProfile(id);
00226 SDOPackage::SDOService_var sdo
00227 = SDOPackage::SDOService::_duplicate(prof->service);
00228 return sdo._retn();
00229 }
00230
00238 bool SdoServiceAdmin::
00239 addSdoServiceProvider(const SDOPackage::ServiceProfile& prof,
00240 SdoServiceProviderBase* provider)
00241 {
00242 RTC_TRACE(("SdoServiceAdmin::addSdoServiceProvider(if=%s)",
00243 static_cast<const char*>(prof.interface_type)));
00244 Guard guard(m_provider_mutex);
00245
00246 std::string id(static_cast<const char*>(prof.id));
00247 for (size_t i(0); i < m_providers.size(); ++i)
00248 {
00249 if (id == static_cast<const char*>(m_providers[i]->getProfile().id))
00250 {
00251 RTC_ERROR(("SDO service(id=%s, ifr=%s) already exists",
00252 static_cast<const char*>(prof.id),
00253 static_cast<const char*>(prof.interface_type)));
00254 return false;
00255 }
00256 }
00257 m_providers.push_back(provider);
00258 return true;
00259 }
00260
00268 bool SdoServiceAdmin::removeSdoServiceProvider(const char* id)
00269 {
00270 RTC_TRACE(("removeSdoServiceProvider(%d)", id));
00271 Guard gurad(m_provider_mutex);
00272
00273 std::string strid(id);
00274 std::vector<SdoServiceProviderBase*>::iterator it = m_providers.begin();
00275 std::vector<SdoServiceProviderBase*>::iterator it_end = m_providers.end();
00276 while (it != it_end)
00277 {
00278 if (strid == static_cast<const char*>((*it)->getProfile().id))
00279 {
00280 (*it)->finalize();
00281 SdoServiceProviderFactory&
00282 factory(SdoServiceProviderFactory::instance());
00283 factory.deleteObject(*it);
00284 m_providers.erase(it);
00285 RTC_INFO(("SDO service provider has been deleted: %s", id));
00286 return true;
00287 }
00288 ++it;
00289 }
00290 RTC_WARN(("Specified SDO service provider not found: %s", id));
00291 return false;
00292 }
00293
00301 bool SdoServiceAdmin::
00302 addSdoServiceConsumer(const SDOPackage::ServiceProfile& sProfile)
00303 {
00304 Guard guard(m_consumer_mutex);
00305 RTC_TRACE(("addSdoServiceConsumer(IFR = %s)",
00306 static_cast<const char*>(sProfile.interface_type)));
00307
00308
00309 if (!isEnabledConsumerType(sProfile)) { return false; }
00310 if (!isExistingConsumerType(sProfile)) { return false; }
00311 RTC_DEBUG(("Valid SDO service required"));
00312 if (strncmp(sProfile.id, "", 1) == 0)
00313 {
00314 RTC_WARN(("No id specified. It should be given by clients."));
00315 return false;
00316 }
00317 RTC_DEBUG(("Valid ID specified"));
00318 {
00319 std::string id(sProfile.id);
00320 for (size_t i(0); i < m_consumers.size(); ++i)
00321 {
00322 if (id == static_cast<const char*>(m_consumers[i]->getProfile().id))
00323 {
00324 RTC_INFO(("Existing consumer is reinitilized."));
00325 RTC_DEBUG(("Propeteis are: %s",
00326 NVUtil::toString(sProfile.properties).c_str()));
00327 return m_consumers[i]->reinit(sProfile);
00328 }
00329 }
00330 }
00331 RTC_DEBUG(("SDO service properly initialized."));
00332
00333
00334 SdoServiceConsumerFactory&
00335 factory(SdoServiceConsumerFactory::instance());
00336 const char* ctype = static_cast<const char*>(sProfile.interface_type);
00337 if (ctype == NULL) { return false; }
00338 SdoServiceConsumerBase* consumer(factory.createObject(ctype));
00339 if (consumer == NULL)
00340 {
00341 RTC_ERROR(("Hmm... consumer must be created."));
00342 return false;
00343 }
00344 RTC_DEBUG(("An SDO service consumer created."));
00345
00346
00347 if (!consumer->init(m_rtobj, sProfile))
00348 {
00349 RTC_WARN(("SDO service initialization was failed."));
00350 RTC_DEBUG(("id: %s", static_cast<const char*>(sProfile.id)));
00351 RTC_DEBUG(("IFR: %s",
00352 static_cast<const char*>(sProfile.interface_type)));
00353 RTC_DEBUG(("properties: %s",
00354 NVUtil::toString(sProfile.properties).c_str()));
00355 factory.deleteObject(consumer);
00356 RTC_INFO(("SDO consumer was deleted by initialization failure"));
00357 return false;
00358 }
00359 RTC_DEBUG(("An SDO service consumer initialized."));
00360 RTC_DEBUG(("id: %s", static_cast<const char*>(sProfile.id)));
00361 RTC_DEBUG(("IFR: %s",
00362 static_cast<const char*>(sProfile.interface_type)));
00363 RTC_DEBUG(("properties: %s",
00364 NVUtil::toString(sProfile.properties).c_str()));
00365
00366
00367 m_consumers.push_back(consumer);
00368
00369 return true;
00370 }
00371
00379 bool SdoServiceAdmin::removeSdoServiceConsumer(const char* id)
00380 {
00381 Guard guard(m_consumer_mutex);
00382 if (id == NULL || id[0] == '\0')
00383 {
00384 RTC_ERROR(("removeSdoServiceConsumer(): id is invalid."));
00385 return false;
00386 }
00387 RTC_TRACE(("removeSdoServiceConsumer(id = %s)", id));
00388
00389 std::string strid(id);
00390 std::vector<SdoServiceConsumerBase*>::iterator it = m_consumers.begin();
00391 std::vector<SdoServiceConsumerBase*>::iterator it_end = m_consumers.end();
00392 while (it != it_end)
00393 {
00394 if (strid == static_cast<const char*>((*it)->getProfile().id))
00395 {
00396 (*it)->finalize();
00397 SdoServiceConsumerFactory&
00398 factory(SdoServiceConsumerFactory::instance());
00399 factory.deleteObject(*it);
00400 m_consumers.erase(it);
00401 RTC_INFO(("SDO service has been deleted: %s", id));
00402 return true;
00403 }
00404 ++it;
00405 }
00406 RTC_WARN(("Specified SDO consumer not found: %s", id));
00407 return false;
00408 }
00409
00410
00411
00412
00413
00421 bool SdoServiceAdmin::
00422 isEnabledConsumerType(const SDOPackage::ServiceProfile& sProfile)
00423 {
00424 if (m_allConsumerEnabled) { return true; }
00425
00426 for (size_t i(0); i < m_consumerTypes.size(); ++i)
00427 {
00428 if (m_consumerTypes[i] ==
00429 static_cast<const char*>(sProfile.interface_type))
00430 {
00431 RTC_DEBUG(("%s is supported SDO service.",
00432 static_cast<const char*>(sProfile.interface_type)));
00433 return true;
00434 }
00435 }
00436 RTC_WARN(("Consumer type is not supported: %s",
00437 static_cast<const char*>(sProfile.interface_type)));
00438 return false;
00439 }
00440
00448 bool SdoServiceAdmin::
00449 isExistingConsumerType(const SDOPackage::ServiceProfile& sProfile)
00450 {
00451 SdoServiceConsumerFactory& factory(SdoServiceConsumerFactory::instance());
00452 coil::vstring consumerTypes(factory.getIdentifiers());
00453
00454 for (size_t i(0); i < consumerTypes.size(); ++i)
00455 {
00456 if (consumerTypes[i] ==
00457 static_cast<const char*>(sProfile.interface_type))
00458 {
00459 RTC_DEBUG(("%s exists in the SDO service factory.",
00460 static_cast<const char*>(sProfile.interface_type)));
00461 RTC_PARANOID(("Available SDO serices in the factory: %s",
00462 coil::flatten(consumerTypes).c_str()));
00463 return true;
00464 }
00465 }
00466 RTC_WARN(("No available SDO service in the factory: %s",
00467 static_cast<const char*>(sProfile.interface_type)));
00468 return false;
00469 }
00470
00471 const std::string SdoServiceAdmin::getUUID() const
00472 {
00473 coil::UUID_Generator uugen;
00474 uugen.init();
00475 std::auto_ptr<coil::UUID> uuid(uugen.generateUUID(2,0x01));
00476
00477 return (const char*) uuid->to_string();
00478 }
00479
00480 std::string SdoServiceAdmin::ifrToKey(std::string& ifr)
00481 {
00482 ::coil::vstring ifrvstr = ::coil::split(ifr, ":");
00483 ::coil::toLower(ifrvstr[1]);
00484 ::coil::replaceString(ifrvstr[1], ".", "_");
00485 ::coil::replaceString(ifrvstr[1], "/", ".");
00486 return ifrvstr[1];
00487 }
00488
00489
00490 };