ekiga r6852 - in trunk: . src/endpoints



Author: jpuydt
Date: Sun Sep  7 06:09:18 2008
New Revision: 6852
URL: http://svn.gnome.org/viewvc/ekiga?rev=6852&view=rev

Log:
Fixed #551111

Modified:
   trunk/ChangeLog
   trunk/src/endpoints/manager.cpp
   trunk/src/endpoints/manager.h

Modified: trunk/src/endpoints/manager.cpp
==============================================================================
--- trunk/src/endpoints/manager.cpp	(original)
+++ trunk/src/endpoints/manager.cpp	Sun Sep  7 06:09:18 2008
@@ -51,12 +51,6 @@
 #include "call-manager.h"
 #include "form-request-simple.h"
 
-static void
-manager_ready_in_main (Ekiga::CallManager* manager)
-{
-  manager->ready.emit ();
-}
-
 static  bool same_codec_desc (Ekiga::CodecDescription a, Ekiga::CodecDescription b)
 { 
   return (a.name == b.name && a.rate == b.rate); 
@@ -69,60 +63,37 @@
 
 public:
 
-  StunDetector (const std::string & _server, 
-                Ekiga::CallCore & _core,
-                Opal::CallManager & _manager,
-                Ekiga::Runtime & _runtime) 
+  StunDetector (const std::string & _server,
+		Opal::CallManager& _manager,
+                GAsyncQueue* _queue) 
     : PThread (1000, AutoDeleteThread), 
       server (_server),
-      core (_core),
       manager (_manager),
-      runtime (_runtime)
+      queue (_queue)
   {
+    g_async_queue_ref (queue);
     this->Resume ();
   };
 
   ~StunDetector ()
   {
-    if (!nat_error.empty ()) {
-      while (!core.errors.handle_request (nat_error)) {
-        PThread::Current ()->Sleep (100);
-      }
-    }
+    g_async_queue_unref (queue);
   }
   
   void Main () 
   {
-    PSTUNClient::NatTypes type = manager.SetSTUNServer (server);
-    if (type == PSTUNClient::SymmetricNat 
-        || type == PSTUNClient::BlockedNat 
-        || type == PSTUNClient::PartialBlockedNat) {
-
-      nat_error =  _("Ekiga did not manage to configure your network settings automatically. You can"
-                     " still use it, but you need to configure your network settings manually.\n\n"
-                     "Please see http://wiki.ekiga.org/index.php/Enable_port_forwarding_manually for"
-                     " instructions");
-
-
-    }
-    else {
+    PSTUNClient::NatTypes* result = NULL;
 
-      for (Ekiga::CallManager::iterator iter = manager.begin ();
-           iter != manager.end ();
-           iter++) 
-        (*iter)->set_listen_port ((*iter)->get_listen_interface ().port);
-    }
+    result = (PSTUNClient::NatTypes*)g_malloc0 (sizeof (PSTUNClient::NatTypes));
+    *result = manager.SetSTUNServer (server);
 
-    runtime.run_in_main (sigc::bind (sigc::ptr_fun (manager_ready_in_main),
-				     &manager));
+    g_async_queue_push (queue, result);
   };
 
 private:
   const std::string server;
-  Ekiga::CallCore & core;
   Opal::CallManager & manager;
-  Ekiga::Runtime & runtime;
-  std::string nat_error;
+  GAsyncQueue* queue;
 };
 
 
@@ -171,19 +142,28 @@
 
   //
   call_core = dynamic_cast<Ekiga::CallCore *> (core.get ("call-core"));
+
+
+  // used to communicate with the StunDetector
+  queue = g_async_queue_new_full (g_free);
 }
 
 
 CallManager::~CallManager ()
 {
   ClearAllCalls (OpalConnection::EndedByLocalUser, false);
+
+  g_async_queue_unref (queue);
 }
 
 
 void CallManager::start ()
 {
   // Ready
-  new StunDetector ("stun.voxgratia.org", *call_core, *this, runtime);
+  new StunDetector ("stun.voxgratia.org", *this, queue);
+
+  patience = 3;
+  runtime.run_in_main (sigc::mem_fun (this, &CallManager::HandleSTUNResult), 3);
 }
 
 
@@ -710,3 +690,65 @@
   }
 }
 
+void
+CallManager::HandleSTUNResult ()
+{
+  PSTUNClient::NatTypes* result = NULL;
+
+  result = (PSTUNClient::NatTypes*)g_async_queue_try_pop (queue);
+
+  if (result != NULL || patience == 0) {
+
+    if (patience == 0
+	|| *result == PSTUNClient::SymmetricNat
+	|| *result == PSTUNClient::BlockedNat
+	|| *result == PSTUNClient::PartialBlockedNat) {
+
+      ReportSTUNError (_("Ekiga did not manage to configure your network settings automatically. You can"
+			 " still use it, but you need to configure your network settings manually.\n\n"
+			 "Please see http://wiki.ekiga.org/index.php/Enable_port_forwarding_manually for"
+			 " instructions"));
+    } else {
+
+    for (Ekiga::CallManager::iterator iter = begin ();
+	 iter != end ();
+	 ++iter) 
+      (*iter)->set_listen_port ((*iter)->get_listen_interface ().port);
+    }
+
+    ready.emit ();
+
+  } else {
+
+    if (patience == 3) {
+
+      patience--;
+      runtime.run_in_main (sigc::mem_fun (this,
+					  &CallManager::HandleSTUNResult),
+			   12);
+    } else if (patience == 2) {
+
+      patience--;
+      runtime.run_in_main (sigc::mem_fun (this,
+					  &CallManager::HandleSTUNResult),
+			   21);
+    } else if (patience == 1) {
+
+      patience--;
+      runtime.run_in_main (sigc::mem_fun (this,
+					  &CallManager::HandleSTUNResult),
+			   30);
+    }
+  }
+}
+
+void
+CallManager::ReportSTUNError (const std::string error)
+{
+  // notice we're in for an infinite loop if nobody ever reports to the user!
+  if ( !call_core->errors.handle_request (error))
+    runtime.run_in_main (sigc::bind (sigc::mem_fun (this,
+						    &CallManager::ReportSTUNError),
+				     error),
+			 10);
+}

Modified: trunk/src/endpoints/manager.h
==============================================================================
--- trunk/src/endpoints/manager.h	(original)
+++ trunk/src/endpoints/manager.h	Sun Sep  7 06:09:18 2008
@@ -160,6 +160,10 @@
 
     void GetAllowedFormats (OpalMediaFormatList & full_list);
 
+    void HandleSTUNResult ();
+
+    void ReportSTUNError (const std::string error);
+
     /* The various related endpoints */
     GMPCSSEndpoint *pcssEP;
 
@@ -172,6 +176,10 @@
     Ekiga::CodecList codecs; 
     Ekiga::CallCore *call_core;
 
+    /* used to get the STUNDetector results */
+    GAsyncQueue* queue;
+    uint patience;
+
     std::string display_name;
     unsigned reject_delay;
     bool forward_on_busy;



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