[openrtm-commit:00138] r2152 - trunk/OpenRTM-aist/src/lib/rtm

openrtm @ openrtm.org openrtm @ openrtm.org
2011年 5月 31日 (火) 11:17:12 JST


Author: n-ando
Date: 2011-05-31 11:17:12 +0900 (Tue, 31 May 2011)
New Revision: 2152

Added:
   trunk/OpenRTM-aist/src/lib/rtm/SdoServiceProviderBase.h
Modified:
   trunk/OpenRTM-aist/src/lib/rtm/RTObject.cpp
   trunk/OpenRTM-aist/src/lib/rtm/RTObject.h
   trunk/OpenRTM-aist/src/lib/rtm/SdoConfiguration.cpp
   trunk/OpenRTM-aist/src/lib/rtm/SdoConfiguration.h
   trunk/OpenRTM-aist/src/lib/rtm/SdoServiceAdmin.cpp
   trunk/OpenRTM-aist/src/lib/rtm/SdoServiceAdmin.h
Log:
SDO service provider framework is implemented. Some SDO service
related interfaces are added/delete/updated.


Modified: trunk/OpenRTM-aist/src/lib/rtm/RTObject.cpp
===================================================================
--- trunk/OpenRTM-aist/src/lib/rtm/RTObject.cpp	2011-05-31 00:23:51 UTC (rev 2151)
+++ trunk/OpenRTM-aist/src/lib/rtm/RTObject.cpp	2011-05-31 02:17:12 UTC (rev 2152)
@@ -1188,7 +1188,10 @@
       }
     return new SDOPackage::DeviceProfile();
   }
-  
+
+  //------------------------------------------------------------
+  // SDO service
+  //------------------------------------------------------------
   /*!
    * @if jp
    * @brief [SDO interface] SDO ServiceProfile の取得 
@@ -1201,18 +1204,19 @@
 	   SDOPackage::NotAvailable, SDOPackage::InternalError)
   {
     RTC_TRACE(("get_service_profiles()"));
-    m_sdoSvcProfiles = m_pSdoConfigImpl->getServiceProfiles();
+
+    SDOPackage::ServiceProfileList_var sprofiles;
     try
       {
-	SDOPackage::ServiceProfileList_var sprofiles;
-	sprofiles = new SDOPackage::ServiceProfileList(m_sdoSvcProfiles);
-	return sprofiles._retn();
+	sprofiles = m_sdoservice.getServiceProviderProfiles();
+        RTC_DEBUG(("SDO ServiceProfiles[%d]", sprofiles->length()));
       }
     catch (...)
       {
+        RTC_ERROR(("Unknown exception cought in get_service_profiles()."));
 	throw SDOPackage::InternalError("get_service_profiles()");
       }
-    return new SDOPackage::ServiceProfileList();
+    return sprofiles._retn();
   }
   
   /*!
@@ -1228,29 +1232,29 @@
 	   SDOPackage::InvalidParameter, SDOPackage::NotAvailable,
 	   SDOPackage::InternalError)
   {
-    RTC_TRACE(("get_service_profile(%s))", id));
-    m_sdoSvcProfiles = m_pSdoConfigImpl->getServiceProfiles();
     if (!id)
-      throw SDOPackage::InvalidParameter("get_service_profile(): Empty name.");
+      {
+        throw SDOPackage::
+          InvalidParameter("get_service_profile(): Empty name.");
+      }
+    RTC_TRACE(("get_service_profile(%s))", id));
     
-    CORBA::Long index;
-    index = CORBA_SeqUtil::find(m_sdoSvcProfiles, svc_name(id));
-    if(index < 0)
-    {
-      throw SDOPackage::InvalidParameter("get_service_profile():"
-                                         "Name is not found.");
-    }
+    SDOPackage::ServiceProfile_var prof;
     try
       {
-	SDOPackage::ServiceProfile_var sprofile;
-	sprofile = new SDOPackage::ServiceProfile(m_sdoSvcProfiles[index]);
-	return sprofile._retn();
+	prof = m_sdoservice.getServiceProviderProfile(id);
       }
+    catch (SDOPackage::InvalidParameter &e)
+      {
+        RTC_ERROR(("InvalidParameter exception: name (%s) is not found", id));
+        throw e;
+      }
     catch (...)
       {
+        RTC_ERROR(("Unknown exception cought in get_service_profile(%s).", id));
 	throw SDOPackage::InternalError("get_service_profile()");
       }
-    return new SDOPackage::ServiceProfile();
+    return prof._retn();
   }
   
   /*!
@@ -1266,27 +1270,25 @@
 	   SDOPackage::InternalError)
   {
     RTC_TRACE(("get_sdo_service(%s))", id));
-    m_sdoSvcProfiles = m_pSdoConfigImpl->getServiceProfiles();
     if (!id)
-      throw SDOPackage::InvalidParameter("get_service(): Empty name.");
-    
-    CORBA::Long index;
-    index = CORBA_SeqUtil::find(m_sdoSvcProfiles, svc_name(id));
-    if (index <0)
-    {
-      throw SDOPackage::InvalidParameter("get_service(): Name is not found.");
-    }
+      {
+        throw SDOPackage::InvalidParameter("get_service(): Empty name.");
+      }
+
+    SDOPackage::SDOService_var sdo;
     try
       {
-	SDOPackage::SDOService_var service;
-	service = m_sdoSvcProfiles[index].service;
-	return service._retn();
+	sdo = m_sdoservice.getServiceProvider(id);
       }
+    catch (SDOPackage::InvalidParameter &e)
+      {
+        throw e;
+      }
     catch (...)
       {
 	throw SDOPackage::InternalError("get_service()");
       }
-    return SDOPackage::SDOService::_nil();
+    return sdo;
   }
   
   /*!
@@ -1909,90 +1911,7 @@
       }
     return ec->reset_component(::RTC::RTObject::_duplicate(getObjRef()));
   }
-   
-  /*!
-   * @if jp
-   *
-   * @brief [local interface] SDOサービスを追加する
-   * @else
-   * @brief [local interface] Add SDO service
-   * @endif
-   */
-  ReturnCode_t
-  RTObject_impl::addSdoService(const SDOPackage::ServiceProfile& profile)
-  {
-    CORBA::Boolean ret = m_pSdoConfigImpl->add_service_profile(profile);
-    if (ret) { return RTC::RTC_OK; }
-    return RTC::RTC_ERROR;
-    /*
-    std::string id(profile.id);
-    for (CORBA::ULong i(0), len(m_sdoSvcProfiles.length()); i < len; ++i)
-      {
-        if (id == m_sdoSvcProfiles[i].id)
-          {
-            return RTC::PRECONDITION_NOT_MET;
-          }
-      }
-    CORBA_SeqUtil::push_back(m_sdoSvcProfiles, profile);
-    return RTC::RTC_OK;
-    */
-  }
-  
-  /*!
-   * @if jp
-   * @brief [local interface] SDOサービスを削除する
-   * @else
-   * @brief [local interface] Remove SDO service
-   * @endif
-   */
-  SDOPackage::SDOService_var
-  RTObject_impl::removeSdoService(const char* service_id)
-  {
-    SDOPackage::SDOService_var service;
-    try
-      {
-        service = get_sdo_service(service_id);
-        m_pSdoConfigImpl->remove_service_profile(service_id);
-      }
-    catch (SDOPackage::InvalidParameter& e)
-      {
-      }
-    catch (SDOPackage::NotAvailable& e)
-      {
-      }
-    catch (SDOPackage::InternalError& e)
-      {
-      }
-    catch (...)
-      {
-      }
-    return service._retn();
-    /*
-    std::string id(service_id);
-    SDOPackage::ServiceProfile_var profile;
-    for (CORBA::ULong i(0), len(m_sdoSvcProfiles.length()); i < len; ++i)
-      {
-        if (id == m_sdoSvcProfiles[i].id)
-          {
-            profile = m_sdoSvcProfiles[i];
-            CORBA_SeqUtil::erase(m_sdoSvcProfile, id);
-          }
-      }
-    return profile._retn();
-    */
-  }
- 
-  bool RTObject_impl::
-  addSdoServiceConsumer(const SDOPackage::ServiceProfile& sProfile)
-  {
-    return m_sdoservice.addSdoServiceConsumer(sProfile);
-  }
 
-  bool RTObject_impl::removeSdoServiceConsumer(const char* id)
-  {
-    return m_sdoservice.removeSdoServiceConsumer(id);
-  }
-
   /*!
    * @if jp
    * @brief 全 InPort のデータを読み込む。

Modified: trunk/OpenRTM-aist/src/lib/rtm/RTObject.h
===================================================================
--- trunk/OpenRTM-aist/src/lib/rtm/RTObject.h	2011-05-31 00:23:51 UTC (rev 2151)
+++ trunk/OpenRTM-aist/src/lib/rtm/RTObject.h	2011-05-31 02:17:12 UTC (rev 2152)
@@ -3119,43 +3119,6 @@
     /*!
      * @if jp
      *
-     * @brief [local interface] SDOサービスを追加する
-     * 
-     * SDOサービスを追加する。
-     *
-     * @else
-     *
-     * @brief [local interface] Add SDO service
-     *
-     * This operation adds SDO service to this RT-Component.
-     *
-     * @endif
-     */
-    ReturnCode_t addSdoService(const SDOPackage::ServiceProfile& profile);
-
-    /*!
-     * @if jp
-     *
-     * @brief [local interface] SDOサービスを削除する
-     * 
-     * SDOサービスを削除する。
-     *
-     * @else
-     *
-     * @brief [local interface] Remove SDO service
-     *
-     * This operation removes SDO service to this RT-Component.
-     *
-     * @endif
-     */
-    SDOPackage::SDOService_var removeSdoService(const char* service_name);
-
-    bool addSdoServiceConsumer(const SDOPackage::ServiceProfile& sProfile);
-    bool removeSdoServiceConsumer(const char* id);
-
-    /*!
-     * @if jp
-     *
      * @brief 全 InPort のデータを読み込む。
      *
      * RTC が保持する全ての InPort のデータを読み込む。
@@ -4524,15 +4487,6 @@
     
     /*!
      * @if jp
-     * @brief SDOService のプロファイルリスト
-     * @else
-     * @brief SDOService Profile List
-     * @endif
-     */
-    SDOPackage::ServiceProfileList m_sdoSvcProfiles;
-    
-    /*!
-     * @if jp
      * @brief SDOService のプロファイルリストからidでサーチするためのファンクタ
      * @else
      * @brief Functor to find from SDOService Profile List by id

Modified: trunk/OpenRTM-aist/src/lib/rtm/SdoConfiguration.cpp
===================================================================
--- trunk/OpenRTM-aist/src/lib/rtm/SdoConfiguration.cpp	2011-05-31 00:23:51 UTC (rev 2151)
+++ trunk/OpenRTM-aist/src/lib/rtm/SdoConfiguration.cpp	2011-05-31 02:17:12 UTC (rev 2152)
@@ -702,32 +702,6 @@
   
   /*!
    * @if jp
-   * @brief SDO の ServiceProfile のリストを取得する
-   * @else
-   * @brief Get a list of ServiceProfile of SDO
-   * @endif
-   */
-  const ServiceProfileList Configuration_impl::getServiceProfiles()
-  {
-    return m_serviceProfiles;
-  }
-  /*!
-   * @if jp
-   * @brief SDO の ServiceProfile を取得する
-   * @else
-   * @brief Get Service Profile of SDO
-   * @endif
-   */
-  const ServiceProfile Configuration_impl::getServiceProfile(const char* id)
-  {
-    CORBA::Long index;
-    index =  CORBA_SeqUtil::find(m_serviceProfiles, service_id(id));
-    if (index < 0) return ServiceProfile();
-    return m_serviceProfiles[index];
-  }
-  
-  /*!
-   * @if jp
    * @brief SDO の Organization リストを取得する
    * @else
    * @brief Get a list of Organization of SDO

Modified: trunk/OpenRTM-aist/src/lib/rtm/SdoConfiguration.h
===================================================================
--- trunk/OpenRTM-aist/src/lib/rtm/SdoConfiguration.h	2011-05-31 00:23:51 UTC (rev 2151)
+++ trunk/OpenRTM-aist/src/lib/rtm/SdoConfiguration.h	2011-05-31 02:17:12 UTC (rev 2152)
@@ -964,56 +964,6 @@
     /*!
      * @if jp
      *
-     * @brief SDO の ServiceProfile のリストを取得する
-     * 
-     * SDO の ServiceProfile のリストを取得する
-     * 
-     * @return SDO ServiceProfileリスト
-     * 
-     * @else
-     *
-     * @brief Get a list of ServiceProfile of SDO
-     * 
-     * Get a list of ServiceProfile of SDO.
-     * 
-     * @return List of ServiceProfile of SDO
-     * 
-     * @endif
-     */
-    const ServiceProfileList getServiceProfiles();
-    
-    /*!
-     * @if jp
-     *
-     * @brief SDO の ServiceProfile を取得する
-     * 
-     * このオペレーションは引数 "id" で指定されたSDO の ServiceProfileを返す。
-     * "id" で指定された ServiceProfileが存在しない場合、
-     * ServiceProfileのインスタンスを生成し返す。
-     * 
-     * @param id ServiceProfile の識別子。
-     * 
-     * @return 指定された SDO ServiceProfile
-     * 
-     * @else
-     *
-     * @brief Get Service Profile of SDO
-     * 
-     * This operation returns ServiceProfile of SDO specified by argument "id".
-     * If ServiceProfile specified by "id" does not exist,
-     * the instance of ServiceProfile will be generated and returned.
-     * 
-     * @param id Identifier of ServiceProfile
-     * 
-     * @return The specified SDO ServiceProfile
-     * 
-     * @endif
-     */
-    const ServiceProfile getServiceProfile(const char* id);
-    
-    /*!
-     * @if jp
-     *
      * @brief SDO の Organization リストを取得する
      * 
      * SDO の Organization リストを取得する
@@ -1076,16 +1026,6 @@
     
     /*!
      * @if jp
-     * @brief Lock 付き SDO ServiceProfileList
-     * @else
-     * @brief SDO ServiceProfileList with mutex lock
-     * @endif
-     */
-    ServiceProfileList m_serviceProfiles;
-    Mutex m_sprofile_mutex;
-    
-    /*!
-     * @if jp
      * @brief SDO Parameter
      * 
      * 実装技術に非依存な変数(パラメータ)を定義するデータ構造。
@@ -1205,24 +1145,6 @@
     
     /*!
      * @if jp
-     * @brief  ServiceProfile用functor
-     * @else
-     * @brief  Functor for ServiceProfile
-     * @endif
-     */
-    struct service_id
-    {
-      service_id(const char* id) : m_id(id) {};
-      bool operator()(const ServiceProfile& s)
-      {
-	std::string id(s.id);
-	return m_id == id;
-      }
-      const std::string m_id;
-    };
-    
-    /*!
-     * @if jp
      * @brief  Organization用functor
      * @else
      * @brief  Functor for Organization

Modified: trunk/OpenRTM-aist/src/lib/rtm/SdoServiceAdmin.cpp
===================================================================
--- trunk/OpenRTM-aist/src/lib/rtm/SdoServiceAdmin.cpp	2011-05-31 00:23:51 UTC (rev 2151)
+++ trunk/OpenRTM-aist/src/lib/rtm/SdoServiceAdmin.cpp	2011-05-31 02:17:12 UTC (rev 2152)
@@ -23,6 +23,7 @@
 #include <rtm/RTObject.h>
 #include <rtm/CORBA_SeqUtil.h>
 #include <rtm/SdoServiceAdmin.h>
+#include <rtm/SdoServiceProviderBase.h>
 #include <rtm/SdoServiceConsumerBase.h>
 
 namespace RTC
@@ -62,16 +63,73 @@
     RTC_TRACE(("SdoServiceAdmin::SdoServiceAdmin(%s)",
                rtobj.getProperties()["instance_name"].c_str()));
 
+    ::coil::Properties& prop(m_rtobj.getProperties());
+
+    //------------------------------------------------------------
+    // SDO service provider
+   ::coil::vstring allowedProviderTypes 
+      = ::coil::split(prop["sdo.service.provider.allowed_services"], ",", true);
+    RTC_DEBUG(("sdo.service.provider.allowed_services: %s",
+               prop["sdo.service.provider.allowed_services"].c_str()));
+
+    ::coil::vstring availableProviderTypes 
+      = SdoServiceProviderFactory::instance().getIdentifiers();
+    prop["sdo.service.provider.available_services"]
+      = coil::flatten(availableProviderTypes);
+    RTC_DEBUG(("sdo.service.provider.available_services: %s",
+               prop["sdo.service.provider.available_services"].c_str()));
+
+    
+    // If types include '[Aa][Ll][Ll]', all types allowed in this RTC
+    ::coil::vstring activeProviderTypes;
+    for (size_t i(0); i < allowedProviderTypes.size(); ++i)
+      {
+        std::string tmp(allowedProviderTypes[i]);
+        coil::toLower(tmp);
+        if (tmp == "all")
+          {
+            activeProviderTypes = availableProviderTypes;
+            RTC_DEBUG(("sdo.service.provider.allowed_services: ALL"));
+            break;
+          }
+        for (size_t j(0); j < availableProviderTypes.size(); ++j)
+          {
+            if (availableProviderTypes[j] == allowedProviderTypes[i])
+              {
+                activeProviderTypes.push_back(availableProviderTypes[j]);
+              }
+          }
+      }
+
+    SdoServiceProviderFactory& factory(SdoServiceProviderFactory::instance());
+    for (size_t i(0); i < activeProviderTypes.size(); ++i)
+      {
+        SdoServiceProviderBase* svc
+          = factory.createObject(activeProviderTypes[i]);
+        
+        SDOPackage::ServiceProfile prof;
+        prof.id             = CORBA::string_dup(activeProviderTypes[i].c_str());
+        prof.interface_type = CORBA::string_dup(activeProviderTypes[i].c_str());
+        prof.service        = svc->_this();
+        std::string propkey = ifrToKey(activeProviderTypes[i]);
+        NVUtil::copyFromProperties(prof.properties,
+                                   prop.getNode(propkey.c_str()));
+
+        svc->init(rtobj, prof);
+        m_providers.push_back(svc);
+      }
+
+    //------------------------------------------------------------
+    // SDO service consumer
     // getting consumer types from RTC's properties
-    ::coil::Properties& prop(m_rtobj.getProperties());
+
     ::std::string constypes = prop["sdo.service.consumer.allowed_services"];
     m_consumerTypes = ::coil::split(constypes, ",", true);
-    RTC_DEBUG(("sdo.service.consumer.allowed_services: %s",
-               coil::flatten(m_consumerTypes).c_str()));
+    RTC_DEBUG(("sdo.service.consumer.allowed_services: %s", constypes.c_str()));
 
     prop["sdo.service.consumer.available_services"]
       = coil::flatten(SdoServiceConsumerFactory::instance().getIdentifiers());
-    RTC_DEBUG(("sdo.service.consumer.allowed_services: %s",
+    RTC_DEBUG(("sdo.service.consumer.available_services: %s",
                prop["sdo.service.consumer.available_services"].c_str()));
 
     // If types include '[Aa][Ll][Ll]', all types allowed in this RTC
@@ -96,35 +154,82 @@
    */
   SdoServiceAdmin::~SdoServiceAdmin()
   {
+    for (size_t i(0); i < m_providers.size(); ++i)
+      {
+        m_providers[i]->finalize();
+        delete m_providers[i];
+      }
+    m_providers.clear();
+
+    for (size_t i(0); i < m_consumers.size(); ++i)
+      {
+        m_consumers[i]->finalize();
+        delete m_consumers[i];
+      }
+    m_consumers.clear();
   }
   
   /*!
    * @if jp
-   * @brief Service Consumer Factory を登録する
+   * @brief SDO Service Provider の ServiceProfileList を取得する
    * @else
-   * @brief Add Service Consumer Factory
+   * @brief Get ServiceProfileList of SDO Service Provider
    * @endif
    */
-  bool SdoServiceAdmin::addSdoServiceConsumerFactory()
+  SDOPackage::ServiceProfileList* SdoServiceAdmin::getServiceProviderProfiles()
   {
-    return false;
+    SDOPackage::ServiceProfileList_var prof
+      = new SDOPackage::ServiceProfileList();
+    SDOPackage::ServiceProfileList prof2;
+    Guard guard(m_provider_mutex);
+    for (size_t i(0); i < m_providers.size(); ++i)
+      {
+        CORBA_SeqUtil::push_back(prof2, m_providers[i]->getProfile());
+      }
+    return prof._retn();
   }
 
   /*!
    * @if jp
-   * @brief Service Consumer Factory を削除する
+   * @brief SDO Service Provider の ServiceProfile を取得する
    * @else
-   * @brief Remove Service Consumer Factory
+   * @brief Get ServiceProfile of an SDO Service Provider
    * @endif
    */
-  bool SdoServiceAdmin::removeSdoServiceConsumerFactory()
+  SDOPackage::ServiceProfile*
+  SdoServiceAdmin::getServiceProviderProfile(const char* id)
   {
-    return false;
+    std::string idstr(id);
+    Guard guard(m_provider_mutex);
+    for (size_t i(0); i < m_providers.size(); ++i)
+      {
+        if (idstr == static_cast<const char*>(m_providers[i]->getProfile().id))
+          {
+            return new SDOPackage::ServiceProfile(m_providers[i]->getProfile());
+          }
+      }
+    throw new SDOPackage::InvalidParameter();
+    return new SDOPackage::ServiceProfile();
   }
-    
 
   /*!
    * @if jp
+   * @brief SDO Service Provider の Service を取得する
+   * @else
+   * @brief Get ServiceProfile of an SDO Service
+   * @endif
+   */   
+  SDOPackage::SDOService_ptr SdoServiceAdmin::getServiceProvider(const char* id)
+  {
+    SDOPackage::ServiceProfile_var prof;
+    prof = getServiceProviderProfile(id);
+    SDOPackage::SDOService_var sdo 
+      = SDOPackage::SDOService::_duplicate(prof->service);
+    return sdo._retn();
+  }
+
+  /*!
+   * @if jp
    * @brief Service Consumer を追加する
    * @else
    * @brief Add Service Consumer
@@ -309,5 +414,14 @@
     return (const char*) uuid->to_string();
   }
 
+  std::string SdoServiceAdmin::ifrToKey(std::string& ifr)
+  {
+    ::coil::vstring ifrvstr = ::coil::split(ifr, ":");
+    ::coil::toLower(ifrvstr[1]);
+    ::coil::replaceString(ifrvstr[1], ".", "_");
+    ::coil::replaceString(ifrvstr[1], "/", ".");
+    return ifrvstr[1];
+  }
 
+
 }; // end of namepsace RTC

Modified: trunk/OpenRTM-aist/src/lib/rtm/SdoServiceAdmin.h
===================================================================
--- trunk/OpenRTM-aist/src/lib/rtm/SdoServiceAdmin.h	2011-05-31 00:23:51 UTC (rev 2151)
+++ trunk/OpenRTM-aist/src/lib/rtm/SdoServiceAdmin.h	2011-05-31 02:17:12 UTC (rev 2152)
@@ -28,6 +28,7 @@
 namespace RTC
 {
   class RTObject_impl;
+  class SdoServiceProviderBase;
   class SdoServiceConsumerBase;
 
   /*!
@@ -84,10 +85,7 @@
    * するServiceProfileを探索するため、サービス提供側では削除時までIDを
    * 保持しておかなければならない。
    *
-   * 
    *
-   *
-   *
    * @since 1.1.0
    *
    * @else
@@ -95,7 +93,54 @@
    * @class SDO service administration class
    * @brief SDO service administration class
    *
+   * This class is the administration class for SDO Services. The SDO
+   * Service, which is defined in the OMG SDO Specification, is a kind
+   * of service for certain functionalities which is provided and/or
+   * consumed by SDO. The specification does not define details.
+   * However, in this implementation, the following behaviors of SDO
+   * services are assumed and this class manages these SDO services.
    *
+   * In this context, the SDO Services that are owned by SDO/RTC is
+   * called SDO Service Provider, and the SDO Services that receive
+   * references to provided services by other SDOs/RTCs or
+   * applications is called SDO Serivce Consumer.
+   *
+   * SDO Service Provider is called from other applications, and it is
+   * used to access to internal functionality of an SDO/RTC.  Other
+   * SDO/RTC or applications would get a ServiceProfiles or a
+   * reference to the SDO serivce through the following operations,
+   * and then they call operations of the service.
+   *
+   * - SDO::get_service_profiles ()
+   * - SDO::get_service_profile (in UniqueIdentifier id)
+   * - SDO::get_sdo_service (in UniqueIdentifier id) 
+   *
+   * Since references of services in other SDOs/RTCs or applications
+   * could be released anytime, service providers cannot know where
+   * and how many consumers refer them. On the other hand, since
+   * SDO/RTC which provides services can stop and delete them anytime,
+   * consumers have to call operations by assuming that the reference
+   * cannot be accessed always.
+   *
+   * SDO Service Consumer, which is a reference to the service entity
+   * in the other SDOs/RTCs or other applications, is given with
+   * ServiceProfile, and SDO/RTC would call operation to access some
+   * functionality to the service object. And giving certain observer
+   * object, it will work as callback from SDO/RTC. SDO service
+   * consumer, which is defferent from SDO service provider, is added
+   * and deleted through SDO Configuration interface shown as follows.
+   *
+   * - Configuration::add_service_profile (in ServiceProfile sProfile)
+   * - Configuration::remove_service_profile (in UniqueIdentifier id)
+   *
+   * To set a SDO service to the target SDO/RTC, other SDOs/RTCs and
+   * applications have to give their service references with
+   * ServiceProfile including ID, interface type and properties to the
+   * add_service_profile() operation.  The ID has to be unique such as
+   * UUID.  Since ID is used when the service is removed from the
+   * target SDO/RTC, SDOs/RTCs and applications of service provider
+   * side have to keep the ID until removing the service.
+   *
    * @since 1.1.0
    *
    * @endif
@@ -144,32 +189,77 @@
     /*!
      * @if jp
      *
-     * @brief Service Consumer Factory を登録する
+     * @brief SDO Service Provider の ServiceProfileList を取得する
      * 
      * @else
      *
-     * @brief Add Service Consumer Factory
+     * @brief Get ServiceProfileList of SDO Service Provider
      *
      * @endif
      */
-    bool addSdoServiceConsumerFactory();
+    SDOPackage::ServiceProfileList* getServiceProviderProfiles();
 
     /*!
      * @if jp
      *
-     * @brief Service Consumer Factory を削除する
+     * @brief SDO Service Provider の ServiceProfile を取得する
+     *
+     * id で指定されたIFR IDを持つSDO Service Provider の
+     * ServiceProfile を取得する。id が NULL ポインタの場合、指定された
+     * id に該当するServiceProfile が存在しない場合、InvalidParameter
+     * 例外が送出される。
+     *
+     * @param id SDO Service provider の IFR ID
+     * @return 指定された id を持つ ServiceProfile
      * 
      * @else
      *
-     * @brief Remove Service Consumer Factory
+     * @brief Get ServiceProfile of an SDO Service Provider
      *
+     * This operation returnes ServiceProfile of an SDO Service
+     * Provider which has the specified id. If the specified id is
+     * NULL pointer or the specified id does not exist in the
+     * ServiceProfile list, InvalidParameter exception will be thrown.
+     *
+     * @param id IFR ID of an SDO Service provider
+     * @return ServiceProfile which has the specified id
+     *
      * @endif
      */
-    bool removeSdoServiceConsumerFactory();
-    
+    SDOPackage::ServiceProfile* getServiceProviderProfile(const char* id);
+
     /*!
      * @if jp
      *
+     * @brief SDO Service Provider の Service を取得する
+     *
+     * id で指定されたIFR IDを持つSDO Service のオブジェクトリファレン
+     * ス を取得する。id が NULL ポインタの場合、指定された id に該当す
+     * るServiceProfile が存在しない場合、InvalidParameter 例外が送出さ
+     * れる。
+     *
+     * @param id SDO Service provider の IFR ID
+     * @return 指定された id を持つ SDO Service のオブジェクトリファレンス
+     * 
+     * @else
+     *
+     * @brief Get ServiceProfile of an SDO Service
+     *
+     * This operation returnes an object reference of an SDO Service
+     * Provider which has the specified id. If the specified id is
+     * NULL pointer or the specified id does not exist in the
+     * ServiceProfile list, InvalidParameter exception will be thrown.
+     *
+     * @param id IFR ID of an SDO Service provider
+     * @return an SDO Service reference which has the specified id
+     *
+     * @endif
+     */
+    SDOPackage::SDOService_ptr getServiceProvider(const char* id);
+
+    /*!
+     * @if jp
+     *
      * @brief Service Consumer を追加する
      * 
      * @else
@@ -222,7 +312,9 @@
 
     const std::string getUUID() const;
     
+    std::string ifrToKey(std::string& ifr);
 
+
   private:
     RTC::RTObject_impl& m_rtobj;
     coil::vstring m_consumerTypes;
@@ -235,7 +327,7 @@
      * @brief SDO ServiceProfileList with mutex lock
      * @endif
      */
-    SDOPackage::ServiceProfileList m_providerProfiles;
+    std::vector<SdoServiceProviderBase*> m_providers;
     coil::Mutex m_provider_mutex;
     
     /*!

Added: trunk/OpenRTM-aist/src/lib/rtm/SdoServiceProviderBase.h
===================================================================
--- trunk/OpenRTM-aist/src/lib/rtm/SdoServiceProviderBase.h	                        (rev 0)
+++ trunk/OpenRTM-aist/src/lib/rtm/SdoServiceProviderBase.h	2011-05-31 02:17:12 UTC (rev 2152)
@@ -0,0 +1,253 @@
+// -*- C++ -*-
+/*!
+ * @file SdoServiceProviderBase.h
+ * @brief SDO service provider base class and its factory
+ * @date $Date$
+ * @author Noriaki Ando <n-ando at aist.go.jp>
+ *
+ * Copyright (C) 2011
+ *     Noriaki Ando
+ *     Intelligent Systems Research Institute,
+ *     National Institute of
+ *         Advanced Industrial Science and Technology (AIST), Japan
+ *     All rights reserved.
+ *
+ * $Id$
+ *
+ */
+
+
+#ifndef RTC_SDOSERVICEPROVIDERBASE_H
+#define RTC_SDOSERVICEPROVIDERBASE_H
+
+#include <coil/Mutex.h>
+#include <coil/Factory.h>
+#include <coil/Timer.h>
+#include <rtm/RTC.h>
+#include <rtm/RTObject.h>
+#include <rtm/idl/SDOPackageStub.h>
+
+namespace RTC
+{
+  /*!
+   * @if jp
+   *
+   * @brief SdoServiceProvider 基底クラス
+   *
+   * SDOで定義されているSDOサービスのプロバイダを実装するための基底クラ
+   * ス。SDOサービスには、外部から提供サービスをRTC(SDO)側で利用する
+   * SDOサービスコンシューマと、RTC(SDO)自身がSDOサービスを提供するSDO
+   * サービスプロバイダがある。すべてのSDOサービスプロバイダはこの基底
+   * クラスを継承して実装される。
+   *
+   * このオブジェクトのライフサイクルは以下の通り。
+   *
+   * -# オブジェクトは通常、共有オブジェクト (so, DLL) としてコンパイル・
+   *    リンクされる。
+   * -# マネージャに対してロードされるとモジュール初期化関数によりオブ
+   *    ジェクトファクトリが、SdoServiceProviderFactory に対して登録さ
+   *    れる。登録のキーにはサービスインターフェースの IFR (interface
+   *    repository) ID が利用され、これによりサービスが区別される。
+   * -# rtc.conf等のコンフィギュレーション指定により、有効化することが
+   *    指定されているサービスインプロバイダは、RTCの起動と同時にインス
+   *    タンス化される。
+   * -# インスタンス化後、初期化関数 init() が呼ばれる。引数には当該サー
+   *    ビスのためのコンフィギュレーションオプションが coil::Propertyに
+   *    より渡される。
+   * -# インスタンス化されたSDOサービスプロバイダは
+   *    SDO::get_get_sdo_service() により外部からアクセスされる。このと
+   *    き、サービスを指定するIDはIFR IDと同じである。このときのアタッ
+   *    チシーケンスは以下の通り。
+   * -# RTCがfinalizeされ解体されると同時にSDOサービスプロバイダも解体
+   *    されるが、その際にはSdoServiceProviderBase::finalize()がコール
+   *    されるので、ここでリソースの解放など終了処理を行う。
+   *
+   * <pre>
+   * 
+   *   [RTC]      [SDO service]               [Other]
+   *     |              :                        |
+   *     | instantiate  :                        |
+   *     |------------->:                        |
+   *     |    init()    |                        |
+   *     |------------->|                        |
+   *     |              | get_service_profiles() |
+   *     |<--------------------------------------|
+   *     |              |    get_sdo_service()   |
+   *     |<--------------------------------------|
+   *     |              |        use service     |
+   *     |              |<-----------------------|
+   *     |              |                        |
+   *     |  finalize()  |                        |
+   *     |------------->x                        |
+   *     x              x                        |
+   *
+   * </pre>
+   *
+   * このクラスの実装に当たっては、少なくとも以下の純粋仮想関数を実装す
+   * る必要がある。
+   *
+   * - init(): 初期化関数。与えられた RTObject および ServiceProfile か
+   *   ら、当該オブジェクトを初期化する。
+   * - reinit(): 再初期化関数。ServiceProfile は設定情報更新のため同一
+   *   IDで呼び出されることが有るが、その際にこの関数が新たな
+   *   ServiceProfile とともに呼び出される。関数内では、設定の変更など
+   *   再初期化処理を実装する。
+   * - getProfile(): 設定されたプロファイルを返す関数。
+   * - finalize(): 終了処理。コンシューマがデタッチされる際に呼び出され
+   *   る関数。関数内では終了処理を実装する。
+   *
+   * SdoServiceProvider は通常共有オブジェクトとしてコンパイル・リンク
+   * される。共有オブジェクトのエントリポイントは通常コンパイルされたファ
+   * イル名の basename + "Init" にしておく。以下に、クラス名、ファイル
+   * 名、エントリポイント関数名の推奨例を示す。
+   *
+   * - 実装クラス名: MySdoServiceConusmer 
+   * - ファイル名: MySdoServiceProvider.h. MySdoServiceProvider.cpp
+   * - 共有オブジェクト名: MySdoServiceProvider.so (or DLL)
+   * - エントリポイント関数名: MySdoServiceProviderInit()
+   *
+   * エントリポイント関数は通常以下のように、SdoServiceProviderFactory
+   * に当該コンシューマのファクトリ (と解体ファンクタ) を登録する以下の
+   * ような関数になる。
+   *
+   * <pre>
+   * extern "C"
+   * {
+   *   void MySdoServiceProviderInit()
+   *   {
+   *     RTC::SdoServiceProviderFactory& factory
+   *       = RTC::SdoServiceProviderFactory::instance();
+   *     factory.addFactory(CORBA_Util::toRepositoryId<OpenRTM::MySdoService>(),
+   *                        ::coil::Creator< ::RTC::SdoServiceProviderBase,
+   *                        ::RTC::MySdoServiceProvider>,
+   *                        ::coil::Destructor< ::RTC::SdoServiceProviderBase,
+   *                        ::RTC::MySdoServiceProvider>);
+   *   }
+   * };
+   * </pre>
+   * 
+   * @else
+   *
+   * @endif
+   *
+   */
+  class SdoServiceProviderBase
+    : public virtual POA_SDOPackage::SDOService,
+      public virtual PortableServer::RefCountServantBase
+  {
+  public:
+    /*!
+     * @if jp
+     * @brief 仮想デストラクタ
+     * @else
+     * @brief virtual destructor
+     * @endif
+     */
+    virtual ~SdoServiceProviderBase() {};
+
+    /*!
+     * @if jp
+     * @brief コンシューマクラスの初期化関数
+     *
+     * このオブジェクトの初期化を行う。外部からSDOサービスが
+     * ServiceProfile とともにアタッチされると、SDOコンシューマがインス
+     * タンス化され、その直後に SDO サービスがアタッチされた RTC と与え
+     * られた ServiceProfile を引数としてこの関数が呼ばれる。
+     *
+     * 関数内では、ServiceProfile 内の SDO サービスリファレンスを
+     * CorbaProvider クラス等を利用しオブジェクト内に保持するとともに、
+     * properties から設定内容を読み込みサービス固有の設定等を行う。与
+     * えられたサービスのオブジェクトリファレンスが不正、あるいは
+     * properties の内容が不正、等の場合は戻り値に false を返す。
+     *
+     * @param rtobj このオブジェクトがインスタンス化された RTC
+     * @param profile 外部から与えられた SDO ServiceProfile
+     * @return 与えられた SDO Service や ServiceProfile が不正の場合 false
+     *
+     * @else
+     * @brief Initialization function of the consumer class
+     *
+     * @endif
+     */
+    virtual bool init(RTObject_impl& rtobj,
+                      const SDOPackage::ServiceProfile& profile) = 0;
+    /*!
+     * @if jp
+     * @brief コンシューマクラスの再初期化関数
+     *
+     * このオブジェクトの再初期化を行う。ServiceProfile には id フィー
+     * ルドにセッション固有の UUID がセットされているが、同一の id の場
+     * 合、properties に設定された設定情報の変更や、service フィールド
+     * のサービスの参照の変更が行われる。その際に呼ばれるのがこの
+     * reinit() 関数である。実装では、service フィールドのオブジェクト
+     * リファレンスの同一性を確認し、異なっている場合保持しているリファ
+     * レンスを更新する必要がある。また properties には新たな設定が与え
+     * られている可能性があるので、内容を読み込み設定を更新する。
+     *
+     * @param profile 新たに与えられた SDO ServiceProfile
+     * @return 不正な ServiceProfile が与えられた場合は false
+     *
+     * @else
+     * @brief Reinitialization function of the consumer class
+     *
+     * @endif
+     */
+    virtual bool reinit(const SDOPackage::ServiceProfile& profile) = 0;
+
+    /*!
+     * @if jp
+     * @brief ServiceProfile を返す
+     *
+     * init()/reinit()で与えられた ServiceProfile は通常オブジェクト内
+     * で保持される。SDO Service 管理フレームワークは管理上このオブジェ
+     * クトに対応する ServiceProfile を必要とするので、この関数では保持
+     * されている ServiceProfile を返す。
+     * 
+     * @return このオブジェクトが保持している ServiceProfile
+     *
+     * @else
+     * @brief Getting ServiceProfile
+     * @endif
+     */
+    virtual const SDOPackage::ServiceProfile& getProfile() const = 0;
+
+    /*!
+     * @if jp
+     * @brief 終了処理
+     *
+     * SDOサービスがでタッチされる際に呼び出される終了処理用関数。サー
+     * ビスのでタッチに際して、当該オブジェクトが保持するリソースを解放
+     * するなどの処理を行う。
+     *
+     * @else
+     * @brief Finalization
+     *
+     * @endif
+     */
+    virtual void finalize() = 0;
+  };
+
+    /*!
+     * @if jp
+     * @brief SdoServiceProviderFactory の typedef
+     * @else
+     * @brief typedef of sdoServiceProviderFactory
+     * @endif
+     */
+  typedef ::coil::GlobalFactory<
+    ::RTC::SdoServiceProviderBase > SdoServiceProviderFactory;
+
+#if defined(WIN32) || defined(_WIN32) || defined(__WIN32__) || defined(__NT__)
+    /*!
+     * @if jp
+     * @brief クラステンプレートの明示的インスタンス化
+     * @else
+     * @brief Explicit instantiation of class template
+     * @endif
+     */
+  EXTERN template class DLL_PLUGIN 
+                     ::coil::GlobalFactory< ::RTC::SdoServiceProviderBase >;
+#endif  
+}; // namespace RTC
+
+#endif // RTC_SDOSERVICEPROVIDERBASE_H



openrtm-commit メーリングリストの案内