CorbaPort.cpp
Go to the documentation of this file.
00001 // -*- C++ -*-
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   // Local operations
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   // protected functions
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         // new version descriptor
00208         // <comp_iname>.port.<port_name>.provided.<type_name>.<instance_name>
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         // old version descriptor
00218         // port.<type_name>.<instance_name>
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); // default is "best_effort"
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         // never come here without error
00291         // if strict connection option is set, error is returned.
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     // new consumer interface descriptor
00349     std::string newdesc((const char*)m_profile.name);
00350     newdesc.insert(m_ownerInstanceName.size(), ".port");
00351     newdesc += ".required." + cons.descriptor();
00352 
00353     // find a NameValue of the consumer
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     // find a NameValue of the provider
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     // old consumer interface descriptor
00390     std::string olddesc("port."); olddesc += cons.descriptor();
00391 
00392     // find a NameValue of the provider same as olddesc
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     // if ior string is "null" or "nil", ignore it.
00417     if (std::string("null") == ior) { return true; }
00418     if (std::string("nil")  == ior) { return true; }
00419     // IOR should be started by "IOR:"
00420     if (std::string("IOR:").compare(0, 4, ior.c_str(), 4) != 0)
00421       {
00422         return false;
00423       }
00424 
00425     // set IOR to the consumer
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 };


openrtm_aist
Author(s): Noriaki Ando
autogenerated on Sat Jun 8 2019 18:49:03