00001
00020 #include <rtm/SystemLogger.h>
00021 #include <rtm/CorbaPort.h>
00022 #include <rtm/CORBA_SeqUtil.h>
00023 #include <rtm/NVUtil.h>
00024 #include <rtm/Manager.h>
00025 #include <string>
00026
00027 namespace RTC
00028 {
00036 CorbaPort::CorbaPort(const char* name)
00037 : PortBase(name)
00038 {
00039 addProperty("port.port_type", "CorbaPort");
00040 }
00041
00049 CorbaPort::~CorbaPort()
00050 {
00051 }
00052
00060 void CorbaPort::init(coil::Properties& prop)
00061 {
00062 RTC_TRACE(("init()"));
00063 RTC_PARANOID(("given properties:"));
00064 RTC_DEBUG_STR((prop));
00065
00066 m_properties << prop;
00067
00068 RTC_PARANOID(("updated properties:"));
00069 RTC_DEBUG_STR((m_properties));
00070
00071 int num(-1);
00072 if (!coil::stringTo(num, m_properties.getProperty("connection_limit",
00073 "-1").c_str()))
00074 {
00075 RTC_ERROR(("invalid connection_limit value: %s",
00076 m_properties.getProperty("connection_limit").c_str()));
00077 }
00078
00079 setConnectionLimit(num);
00080 }
00081
00089 bool
00090 CorbaPort::registerProvider(const char* instance_name,
00091 const char* type_name,
00092 PortableServer::RefCountServantBase& provider)
00093 {
00094 RTC_TRACE(("registerProvider(instance=%s, type_name=%s)",
00095 instance_name, type_name));
00096
00097 try
00098 {
00099 CorbaProviderHolder providerholder(type_name, instance_name, &provider);
00100 m_providers.push_back(providerholder);
00101 }
00102 catch (...)
00103 {
00104 RTC_ERROR(("appending provider interface failed"));
00105 return false;
00106 }
00107
00108 if (!appendInterface(instance_name, type_name, RTC::PROVIDED))
00109 {
00110 RTC_ERROR(("appending provider interface failed"));
00111 return false;
00112 }
00113
00114 return true;
00115 };
00116
00124 bool
00125 CorbaPort::registerConsumer(const char* instance_name,
00126 const char* type_name,
00127 CorbaConsumerBase& consumer)
00128 {
00129 RTC_TRACE(("registerConsumer()"));
00130
00131 if (!appendInterface(instance_name, type_name, RTC::REQUIRED))
00132 {
00133 return false;
00134 }
00135
00136 m_consumers.push_back(CorbaConsumerHolder(type_name,
00137 instance_name,
00138 &consumer));
00139
00140 return true;
00141 }
00142
00143
00144
00145
00146
00154 void CorbaPort::activateInterfaces()
00155 {
00156 CorbaProviderList::iterator it(m_providers.begin());
00157 while(it != m_providers.end())
00158 {
00159 it->activate();
00160 ++it;
00161 }
00162 }
00163
00171 void CorbaPort::deactivateInterfaces()
00172 {
00173 CorbaProviderList::iterator it(m_providers.begin());
00174 while(it != m_providers.end())
00175 {
00176 it->deactivate();
00177 ++it;
00178 }
00179 }
00180
00181
00182
00183
00191 ReturnCode_t
00192 CorbaPort::publishInterfaces(ConnectorProfile& connector_profile)
00193 {
00194 RTC_TRACE(("publishInterfaces()"));
00195
00196 ReturnCode_t returnvalue = _publishInterfaces();
00197 if(returnvalue != RTC::RTC_OK)
00198 {
00199 return returnvalue;
00200 }
00201
00202 NVList properties;
00203 CorbaProviderList::iterator it(m_providers.begin());
00204 while (it != m_providers.end())
00205 {
00206
00207
00208
00209 std::string newdesc((const char*)m_profile.name);
00210 newdesc.insert(m_ownerInstanceName.size(), ".port");
00211 newdesc += ".provided." + it->descriptor();
00212 CORBA_SeqUtil::
00213 push_back(properties,
00214 NVUtil::newNV(newdesc.c_str(), it->ior().c_str()));
00215
00216
00217
00218
00219 std::string olddesc;
00220 olddesc += "port." + it->descriptor();
00221 CORBA_SeqUtil::
00222 push_back(properties,
00223 NVUtil::newNV(olddesc.c_str(), it->ior().c_str()));
00224 ++it;
00225 }
00226
00227 #ifdef ORB_IS_RTORB
00228 {
00229 CORBA::ULong len1(connector_profile.properties.length());
00230 CORBA::ULong len2(properties.length());
00231 CORBA::ULong len(len1 + len2);
00232 connector_profile.properties.length(len);
00233
00234 for (CORBA::ULong i = 0; i < len2; ++i)
00235 {
00236 connector_profile.properties[len1 + i] = properties[i];
00237 }
00238 }
00239 #else // ORB_IS_RTORB
00240 CORBA_SeqUtil::push_back_list(connector_profile.properties, properties);
00241 #endif
00242
00243 RTC_DEBUG_STR((NVUtil::toString(properties)));
00244
00245 return RTC::RTC_OK;
00246 }
00247
00255 ReturnCode_t
00256 CorbaPort::subscribeInterfaces(const ConnectorProfile& connector_profile)
00257 {
00258 RTC_TRACE(("subscribeInterfaces()"));
00259
00260 const NVList& nv(connector_profile.properties);
00261 RTC_DEBUG_STR((NVUtil::toString(nv)));
00262
00263 bool strict(false);
00264 CORBA::Long index(NVUtil::find_index(nv, "port.connection.strictness"));
00265 if (index >= 0)
00266 {
00267 const char* strictness;
00268 nv[index].value >>= strictness;
00269 if (std::string("best_effort") == strictness) { strict = false; }
00270 else if (std::string("strict") == strictness) { strict = true; }
00271 RTC_DEBUG(("Connetion strictness is: %s",
00272 strict ? "strict" : "best_effort"))
00273 }
00274
00275 for (CorbaConsumerList::iterator it(m_consumers.begin());
00276 it != m_consumers.end(); ++it)
00277 {
00278 std::string ior;
00279 if (findProvider(nv, *it, ior))
00280 {
00281 setObject(ior, *it);
00282 continue;
00283 }
00284 if (findProviderOld(nv, *it, ior))
00285 {
00286 setObject(ior, *it);
00287 continue;
00288 }
00289
00290
00291
00292 if (strict)
00293 {
00294 RTC_ERROR(("subscribeInterfaces() failed."));
00295 return RTC::RTC_ERROR;
00296 }
00297 }
00298
00299 RTC_TRACE(("subscribeInterfaces() successfully finished."));
00300
00301 return RTC::RTC_OK;
00302 }
00303
00311 void
00312 CorbaPort::unsubscribeInterfaces(const ConnectorProfile& connector_profile)
00313 {
00314 RTC_TRACE(("unsubscribeInterfaces()"));
00315
00316 const NVList& nv(connector_profile.properties);
00317 RTC_DEBUG_STR((NVUtil::toString(nv)));
00318
00319 for (CorbaConsumerList::iterator it(m_consumers.begin());
00320 it != m_consumers.end(); ++it)
00321 {
00322 std::string ior;
00323 if (findProvider(nv, *it, ior))
00324 {
00325 RTC_DEBUG(("Correspoinding consumer found."));
00326 releaseObject(ior, *it);
00327 continue;
00328 }
00329 if (findProviderOld(nv, *it, ior))
00330 {
00331 RTC_DEBUG(("Correspoinding consumer found."));
00332 releaseObject(ior, *it);
00333 continue;
00334 }
00335 }
00336 }
00337
00345 bool CorbaPort::findProvider(const NVList& nv, CorbaConsumerHolder& cons,
00346 std::string& iorstr)
00347 {
00348
00349 std::string newdesc((const char*)m_profile.name);
00350 newdesc.insert(m_ownerInstanceName.size(), ".port");
00351 newdesc += ".required." + cons.descriptor();
00352
00353
00354 CORBA::Long cons_index(NVUtil::find_index(nv, newdesc.c_str()));
00355 if (cons_index < 0) { return false; }
00356
00357 const char* provider;
00358 if (!(nv[cons_index].value >>= provider))
00359 {
00360 RTC_WARN(("Cannot extract Provider interface descriptor"));
00361 return false;
00362 }
00363
00364
00365 CORBA::Long prov_index(NVUtil::find_index(nv, provider));
00366 if (prov_index < 0) { return false; }
00367
00368 const char* ior;
00369 if (!(nv[prov_index].value >>= ior))
00370 {
00371 RTC_WARN(("Cannot extract Provider IOR string"));
00372 return false;
00373 }
00374 iorstr = ior;
00375 RTC_DEBUG(("interface matched with new descriptor: %s", newdesc.c_str()));
00376 return true;
00377 }
00378
00386 bool CorbaPort::findProviderOld(const NVList&nv, CorbaConsumerHolder& cons,
00387 std::string& iorstr)
00388 {
00389
00390 std::string olddesc("port."); olddesc += cons.descriptor();
00391
00392
00393 CORBA::Long index(NVUtil::find_index(nv, olddesc.c_str()));
00394 if (index < 0) { return false; }
00395
00396 const char* ior;
00397 if (!(nv[index].value >>= ior))
00398 {
00399 RTC_WARN(("Cannot extract Provider IOR string"));
00400 return false;
00401 }
00402 iorstr = ior;
00403 RTC_INFO(("interface matched with old descriptor: %s", olddesc.c_str()));
00404 return true;
00405 }
00406
00414 bool CorbaPort::setObject(const std::string& ior, CorbaConsumerHolder& cons)
00415 {
00416
00417 if (std::string("null") == ior) { return true; }
00418 if (std::string("nil") == ior) { return true; }
00419
00420 if (std::string("IOR:").compare(0, 4, ior.c_str(), 4) != 0)
00421 {
00422 return false;
00423 }
00424
00425
00426 if (!cons.setObject(ior.c_str()))
00427 {
00428 RTC_ERROR(("Cannot narrow reference"));
00429 return false;
00430 }
00431 RTC_TRACE(("setObject() done"));
00432 return true;
00433 }
00434
00442 bool CorbaPort::releaseObject(const std::string& ior,
00443 CorbaConsumerHolder& cons)
00444 {
00445 if (ior == cons.getIor())
00446 {
00447 cons.releaseObject();
00448 RTC_DEBUG(("Consumer %s released.", cons.descriptor().c_str()));
00449 return true;
00450 }
00451 RTC_WARN(("IORs between Consumer and Connector are different."));
00452 return false;
00453 }
00454
00455 };