[ekiga] Opal: Fixed per account Outbound Proxy support.



commit 3a92728bb792aac398a42482c57e22b6b22b9caf
Author: Damien Sandras <dsandras seconix com>
Date:   Sat Apr 18 17:17:20 2015 +0200

    Opal: Fixed per account Outbound Proxy support.
    
    Also sanitized code.
    Get back to a mode where handle_registration_event is handled in the
    main thread. It does not seem to execute blocking operation, and it is
    always better to avoid deadlocks.

 lib/engine/components/opal/opal-account.cpp        |   35 +++++++------
 lib/engine/components/opal/opal-account.h          |   30 ++++++-----
 lib/engine/components/opal/opal-bank.cpp           |    2 +
 .../components/opal/process/h323-endpoint.cpp      |   13 +++--
 .../components/opal/process/sip-endpoint.cpp       |   57 ++++++++-----------
 5 files changed, 69 insertions(+), 68 deletions(-)
---
diff --git a/lib/engine/components/opal/opal-account.cpp b/lib/engine/components/opal/opal-account.cpp
index a0d4ef1..c7fd557 100644
--- a/lib/engine/components/opal/opal-account.cpp
+++ b/lib/engine/components/opal/opal-account.cpp
@@ -152,6 +152,7 @@ Opal::Account::Account (Opal::Bank & _bank,
                         boost::shared_ptr<Ekiga::NotificationCore> _notification_core,
                         boost::shared_ptr<Ekiga::PersonalDetails> _personal_details,
                         boost::shared_ptr<Ekiga::AudioOutputCore> _audiooutput_core,
+                        Opal::EndPoint& _endpoint,
 #ifdef HAVE_H323
                         Opal::H323::EndPoint* _h323_endpoint,
 #endif
@@ -165,6 +166,7 @@ Opal::Account::Account (Opal::Bank & _bank,
   notification_core(_notification_core),
   personal_details(_personal_details),
   audiooutput_core(_audiooutput_core),
+  endpoint(_endpoint),
 #ifdef HAVE_H323
   h323_endpoint(_h323_endpoint),
 #endif
@@ -578,7 +580,7 @@ Opal::Account::disable ()
       }
 
       if (type != Account::H323 && sip_endpoint) {
-        sip_endpoint->Unsubscribe (SIPSubscribe::MessageSummary, get_transaction_aor (get_aor ()));
+        sip_endpoint->Unsubscribe (SIPSubscribe::MessageSummary, get_full_uri (get_aor ()));
       }
 
       opal_presentity->Close ();
@@ -949,7 +951,7 @@ Opal::Account::fetch (const std::string uri)
   // Subscribe now
   if (state == Registered) {
     PTRACE(4, "Ekiga\tSubscribeToPresence for " << uri.c_str () << " (fetch)");
-    opal_presentity->SubscribeToPresence (get_transaction_aor (uri).c_str ());
+    opal_presentity->SubscribeToPresence (get_full_uri (uri));
   }
 }
 
@@ -958,7 +960,7 @@ void
 Opal::Account::unfetch (const std::string uri)
 {
   if (is_supported_uri (uri) && opal_presentity) {
-    opal_presentity->UnsubscribeFromPresence (get_transaction_aor (uri).c_str ());
+    opal_presentity->UnsubscribeFromPresence (get_full_uri (uri));
     Ekiga::Runtime::run_in_main (boost::bind (&Opal::Account::presence_status_in_main, this, uri, "unknown", 
""));
   }
 }
@@ -982,19 +984,18 @@ Opal::Account::is_supported_uri (const std::string & uri)
 void
 Opal::Account::handle_registration_event (Ekiga::Account::RegistrationState state_,
                                           const std::string info,
-                                          PSafePtr<OpalPresentity> _opal_presentity)
+                                          const std::string & aor)
 {
   if (state == state_)
     return; // The state did not change...
 
-  if (_opal_presentity)
-    opal_presentity = _opal_presentity;
-
   switch (state_) {
 
   case Registered:
 
     if (state != Registered) {
+      if (!aor.empty () && !opal_presentity)
+        opal_presentity = endpoint.AddPresentity (aor);
 
       // Translators: this is a state, not an action, i.e. it should be read as
       // "(you are) registered", and not as "(you have been) registered"
@@ -1021,7 +1022,7 @@ Opal::Account::handle_registration_event (Ekiga::Account::RegistrationState stat
 
         opal_presentity->SetLocalPresence (personal_state, presence_status);
         if (type != Account::H323 && sip_endpoint) {
-          sip_endpoint->Subscribe (SIPSubscribe::MessageSummary, 3600, get_transaction_aor (get_aor ()));
+          sip_endpoint->Subscribe (SIPSubscribe::MessageSummary, 3600, get_full_uri (get_aor ()));
         }
       }
       boost::shared_ptr<Ekiga::PersonalDetails> details = personal_details.lock ();
@@ -1041,7 +1042,7 @@ Opal::Account::handle_registration_event (Ekiga::Account::RegistrationState stat
     /* delay destruction of this account until the
        unsubscriber thread has called back */
     if (dead)
-      Ekiga::Runtime::run_in_main (boost::ref (removed));
+      removed ();
     break;
 
   case UnregistrationFailed:
@@ -1081,7 +1082,7 @@ Opal::Account::handle_registration_event (Ekiga::Account::RegistrationState stat
     break;
   }
 
-  Ekiga::Runtime::run_in_main (boost::ref (updated));
+  updated ();
 }
 
 
@@ -1402,11 +1403,13 @@ Opal::Account::decide_type ()
 }
 
 
-const std::string
-Opal::Account::get_transaction_aor (const std::string & aor) const
+const PString
+Opal::Account::get_full_uri (const PString & uri) const
 {
-  if (sip_endpoint && sip_endpoint->IsRegistered (get_aor () + ";transport=tcp"))
-    return aor + ";transport=tcp";
-  else
-    return aor;
+  PString parameters;
+  PINDEX j;
+  if (opal_presentity && (j = opal_presentity->GetAOR ().AsString ().Find (";")) != P_MAX_INDEX)
+    parameters = opal_presentity->GetAOR ().AsString ().Mid (j);
+
+  return uri + parameters;
 }
diff --git a/lib/engine/components/opal/opal-account.h b/lib/engine/components/opal/opal-account.h
index 2cac2d7..588bf9f 100644
--- a/lib/engine/components/opal/opal-account.h
+++ b/lib/engine/components/opal/opal-account.h
@@ -57,6 +57,7 @@ namespace Opal
   class Bank;
   class CallManager;
   class Presentity;
+  class EndPoint;
   namespace Sip { class EndPoint; };
   namespace H323 { class EndPoint; };
 
@@ -72,12 +73,12 @@ namespace Opal
     public Ekiga::PresencePublisher,
     public Ekiga::PresenceFetcher
   {
-    friend class Opal::Presentity;
+    friend class Presentity;
 public:
 
     typedef enum { SIP, Ekiga, DiamondCard, H323 } Type;
 
-    static xmlNodePtr build_node (Opal::Account::Type typus,
+    static xmlNodePtr build_node (Account::Type typus,
                                  std::string name,
                                  std::string host,
                                  std::string outbound_proxy,
@@ -104,15 +105,16 @@ public:
      * that Opal is taking care of deleting them. They are not deleted when
      * the last object having a reference to them is deleted.
      */
-    Account (Opal::Bank & bank,
+    Account (Bank & bank,
             boost::weak_ptr<Ekiga::PresenceCore> _presence_core,
             boost::shared_ptr<Ekiga::NotificationCore> _notification_core,
             boost::shared_ptr<Ekiga::PersonalDetails> _personal_details,
             boost::shared_ptr<Ekiga::AudioOutputCore> _audiooutput_core,
+             EndPoint& _endpoint,
 #ifdef HAVE_H323
-             Opal::H323::EndPoint* _h323_endpoint,
+             H323::EndPoint* _h323_endpoint,
 #endif
-             Opal::Sip::EndPoint* _sip_endpoint,
+             Sip::EndPoint* _sip_endpoint,
             boost::function0<std::list<std::string> > _existing_groups,
             xmlNodePtr node_);
 
@@ -198,7 +200,7 @@ public:
      */
     void handle_registration_event (RegistrationState state_,
                                    const std::string info,
-                                    PSafePtr<OpalPresentity> _opal_presentity = NULL);
+                                    const std::string & aor);
 
     /* This method is public to be called by an opal endpoint, which will push
      * this Opal::Account's message waiting information
@@ -208,6 +210,8 @@ public:
     /* This part of the api is the implementation of Ekiga::Heap */
     void visit_presentities (boost::function1<bool, Ekiga::PresentityPtr > visitor) const;
 
+    const PString get_full_uri (const PString & uri) const;
+
 protected:
     void on_rename_group (Opal::PresentityPtr pres);
 
@@ -218,9 +222,8 @@ private:
 
     void decide_type ();
 
-    const std::string get_transaction_aor (const std::string & aor) const;
-
     void add_contact ();
+
     bool on_add_contact_form_submitted (bool submitted,
                                        Ekiga::Form& result,
                                         std::string& error);
@@ -258,18 +261,19 @@ private:
     void presence_status_in_main (std::string uri,
                                  std::string presence,
                                  std::string status) const;
-    void when_presentity_removed (boost::shared_ptr<Opal::Presentity> pres);
-    void when_presentity_updated (boost::shared_ptr<Opal::Presentity> pres);
+    void when_presentity_removed (boost::shared_ptr<Presentity> pres);
+    void when_presentity_updated (boost::shared_ptr<Presentity> pres);
 
-    Opal::Bank & bank;
+    Bank & bank;
 
     boost::weak_ptr<Ekiga::PresenceCore> presence_core;
     boost::weak_ptr<Ekiga::NotificationCore> notification_core;
     boost::weak_ptr<Ekiga::PersonalDetails> personal_details;
     boost::weak_ptr<Ekiga::AudioOutputCore> audiooutput_core;
 
-    Opal::H323::EndPoint* h323_endpoint;
-    Opal::Sip::EndPoint* sip_endpoint;
+    EndPoint& endpoint;
+    H323::EndPoint* h323_endpoint;
+    Sip::EndPoint* sip_endpoint;
   };
 
   typedef boost::shared_ptr<Account> AccountPtr;
diff --git a/lib/engine/components/opal/opal-bank.cpp b/lib/engine/components/opal/opal-bank.cpp
index 1de5902..f61dcb0 100644
--- a/lib/engine/components/opal/opal-bank.cpp
+++ b/lib/engine/components/opal/opal-bank.cpp
@@ -95,6 +95,7 @@ Opal::Bank::Bank (Ekiga::ServiceCore& core,
                                                       notification_core,
                                                       personal_details,
                                                       audiooutput_core,
+                                                      endpoint,
 #ifdef HAVE_H323
                                                       _h323_endpoint,
 #endif
@@ -286,6 +287,7 @@ Opal::Bank::add (Account::Type acc_type,
                                    notification_core,
                                    personal_details,
                                    audiooutput_core,
+                                    endpoint,
 #ifdef HAVE_H323
                                     h323_endpoint,
 #endif
diff --git a/lib/engine/components/opal/process/h323-endpoint.cpp 
b/lib/engine/components/opal/process/h323-endpoint.cpp
index ec4ceac..b96af92 100644
--- a/lib/engine/components/opal/process/h323-endpoint.cpp
+++ b/lib/engine/components/opal/process/h323-endpoint.cpp
@@ -66,7 +66,8 @@ namespace Opal {
 
         if (!registering && ep.IsRegisteredWithGatekeeper (account.get_host ())) {
           ep.RemoveGatekeeper (account.get_host ());
-          account.handle_registration_event (Account::Unregistered, std::string ());
+          Ekiga::Runtime::run_in_main (boost::bind (&Opal::Account::handle_registration_event, &account,
+                                                    Account::Unregistered, std::string (), std::string ()));
           return;
         }
         else if (registering && !ep.IsRegisteredWithGatekeeper (account.get_host ())) {
@@ -119,12 +120,12 @@ namespace Opal {
               info = _("Failed");
 
             // Signal
-            account.handle_registration_event (Account::RegistrationFailed, info);
-          }
-          else {
-
-            account.handle_registration_event (Account::Registered, std::string ());
+            Ekiga::Runtime::run_in_main (boost::bind (&Opal::Account::handle_registration_event, &account,
+                                                      Account::RegistrationFailed, info, std::string ()));
           }
+          else
+            Ekiga::Runtime::run_in_main (boost::bind (&Opal::Account::handle_registration_event, &account,
+                                                      Account::Registered, std::string (), std::string ()));
         }
       }
 
diff --git a/lib/engine/components/opal/process/sip-endpoint.cpp 
b/lib/engine/components/opal/process/sip-endpoint.cpp
index 3786aa4..61ac0f7 100644
--- a/lib/engine/components/opal/process/sip-endpoint.cpp
+++ b/lib/engine/components/opal/process/sip-endpoint.cpp
@@ -76,16 +76,10 @@ namespace Opal {
           params.m_maxRetryTime = PMaxTimeInterval;  // use default value
 
           if (!account.get_outbound_proxy ().empty ())
-            params.m_addressOfRecord = params.m_addressOfRecord + ";OPAL-proxy=" + 
account.get_outbound_proxy ();
+            params.m_addressOfRecord = params.m_addressOfRecord + ";OPAL-proxy=" + 
account.get_outbound_proxy () + "%3Btransport=tcp";
 
           // Register the given aor to the given registrar
-          if (!ep.Register (params, _aor)) {
-            params.m_addressOfRecord = "sip:" + account.get_username () + "@" + account.get_host ();
-            if (!ep.Register (params, _aor)) {
-              account.handle_registration_event (Account::RegistrationFailed,
-                                                 _("Transport error"));
-            }
-          }
+          ep.Register (params, _aor);
         }
         else {
           PString aor = "sip:" + account.get_username () + "@" + account.get_host ();
@@ -160,28 +154,15 @@ Opal::Sip::EndPoint::send_message (const std::string & _uri,
 bool
 Opal::Sip::EndPoint::SetUpCall (const std::string & uri)
 {
-  std::stringstream ustr;
-
-  if (uri.find (":") == string::npos)
-    ustr << "sip:" << uri;
-  else
-    ustr << uri;
-
-  PStringList registrations = GetRegistrations ();
-  SIPURL remote_uri = ustr.str ().c_str ();
-  for (int i = 0 ; i < registrations.GetSize () ; i++) {
-    SIPURL registered_uri = registrations [i];
-    if (registered_uri.GetHostPort () == remote_uri.GetHostPort ()) {
-      PString transport = registered_uri.GetParamVars ()("transport");
-      if (!transport.IsEmpty ())
-        ustr << ";transport=" << (const char *) transport;
-    }
-  }
-
   PString token;
-  GetManager ().SetUpCall ("pc:*", ustr.str(), token, (void*) ustr.str().c_str());
+  boost::shared_ptr<Opal::Bank> bank = core.get<Opal::Bank> ("opal-account-store");
+  if (bank) {
+    Opal::AccountPtr account = bank->find_account (SIPURL (uri).GetHostPort ());
+    if (account)
+      return GetManager ().SetUpCall ("pc:*", account->get_full_uri (uri), token, (void*) uri.c_str ());
+  }
 
-  return true;
+  return GetManager ().SetUpCall ("pc:*", uri, token, (void*) uri.c_str ());
 }
 
 
@@ -289,17 +270,26 @@ Opal::Sip::EndPoint::OnRegistrationStatus (const RegistrationStatus & status)
 
   /* Successful registration or unregistration */
   if (status.m_reason == SIP_PDU::Successful_OK) {
-    account->handle_registration_event (status.m_wasRegistering?Account::Registered:Account::Unregistered,
-                                        std::string (),
-                                        GetManager ().AddPresentity (PURL (status.m_addressofRecord)));
+    Ekiga::Runtime::run_in_main (boost::bind (&Opal::Account::handle_registration_event, account,
+                                              
status.m_wasRegistering?Account::Registered:Account::Unregistered,
+                                              std::string (),
+                                              status.m_addressofRecord));
   }
   /* Registration or unregistration failure */
   else {
     SIPURL m_addressOfRecord = SIPURL (status.m_addressofRecord);
+    /* Try again in UDP mode */
     if (m_addressOfRecord.GetTransportProto () == "TCP") {
       SIPRegister::Params params;
       PString _aor;
       m_addressOfRecord.SetParamVar ("transport", "udp");
+      if (m_addressOfRecord.GetParamVars ().Contains ("OPAL-proxy")) {
+        PString proxy = m_addressOfRecord.GetParamVars().Get ("OPAL-proxy");
+        PINDEX p = proxy.Find (";");
+        if (p != P_MAX_INDEX)
+          proxy = proxy.Left (p);
+        m_addressOfRecord.SetParamVar ("OPAL-proxy", proxy);
+      }
       params.m_addressOfRecord = m_addressOfRecord;
       params.m_compatibility = SIPRegister::e_RFC5626;
       params.m_authID = status.m_handler->GetAuthID ();
@@ -547,8 +537,9 @@ Opal::Sip::EndPoint::OnRegistrationStatus (const RegistrationStatus & status)
      * as a sip code has already been scheduled to be shown
      */
     if (status.m_reason != SIP_PDU::Failure_RequestTerminated) {
-      account->handle_registration_event 
(status.m_wasRegistering?Account::RegistrationFailed:Account::UnregistrationFailed,
-                                          info);
+      Ekiga::Runtime::run_in_main (boost::bind (&Opal::Account::handle_registration_event, account,
+                                                
status.m_wasRegistering?Account::RegistrationFailed:Account::UnregistrationFailed,
+                                                info, std::string ()));
     }
   }
 }


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]