Update to libjingle 0.5.5.

git-svn-id: http://libjingle.googlecode.com/svn/trunk@64 dd674b97-3498-5ee5-1854-bdd07cd0ff33
diff --git a/CHANGELOG b/CHANGELOG
index 77c8795..7dbfbe8 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -1,5 +1,11 @@
 Libjingle
 
+0.5.5 - May 26, 2011
+  - Refactor async sockets
+  - Improve MUC joining
+  - Add OSX video renderer
+  - Bug fixes
+
 0.5.4 - May 13, 2011
   - Support for MUC lookup by name
   - Bug fixes
diff --git a/talk/examples/call/callclient.cc b/talk/examples/call/callclient.cc
index 940f261..f18c123 100644
--- a/talk/examples/call/callclient.cc
+++ b/talk/examples/call/callclient.cc
@@ -684,14 +684,20 @@
     return;
   }
 
+  std::string room_nick = room_jid.resource();
+  if (room_nick.empty()) {
+    room_nick = (xmpp_client_->jid().node()
+                 + "_" + xmpp_client_->jid().resource());
+  }
+
   MucMap::iterator elem = mucs_.find(room_jid);
   if (elem != mucs_.end()) {
     console_->Printf("This MUC already exists.");
     return;
   }
 
-  buzz::Muc* muc = new buzz::Muc(room_jid, xmpp_client_->jid().node());
-  mucs_[room_jid] = muc;
+  buzz::Muc* muc = new buzz::Muc(room_jid.BareJid(), room_nick);
+  mucs_[muc->jid()] = muc;
   presence_out_->SendDirected(muc->local_jid(), my_status_);
 }
 
diff --git a/talk/p2p/base/session.cc b/talk/p2p/base/session.cc
index eb34e0a..a1ec304 100644
--- a/talk/p2p/base/session.cc
+++ b/talk/p2p/base/session.cc
@@ -130,6 +130,13 @@
   }
 }
 
+void TransportProxy::AddUnsentCandidates(const Candidates& candidates) {
+  for (Candidates::const_iterator cand = candidates.begin();
+       cand != candidates.end(); ++cand) {
+    unsent_candidates_.push_back(*cand);
+  }
+}
+
 
 TransportChannelProxy* TransportProxy::GetProxy(const std::string& name) {
   ChannelMap::iterator iter = channels_.find(name);
@@ -237,6 +244,7 @@
   error_ = ERROR_NONE;
   state_ = STATE_INIT;
   initiator_ = false;
+  initiate_acked_ = false;
   current_protocol_ = PROTOCOL_HYBRID;
 }
 
@@ -577,17 +585,22 @@
   ASSERT(signaling_thread_->IsCurrent());
   TransportProxy* transproxy = GetTransportProxy(transport);
   if (transproxy != NULL) {
-    if (!transproxy->negotiated()) {
-      transproxy->AddSentCandidates(candidates);
-    }
-    SessionError error;
-    if (!SendTransportInfoMessage(
-            TransportInfo(transproxy->content_name(), transproxy->type(),
-                          candidates),
-            &error)) {
-      LOG(LS_ERROR) << "Could not send transport info message: "
-                    << error.text;
-      return;
+    if (initiator_ && !initiate_acked_) {
+      // TODO: This is to work around server re-ordering
+      // messages.  We send the candidates once the session-initiate
+      // is acked.  Once we have fixed the server to guarantee message
+      // order, we can remove this case.
+      transproxy->AddUnsentCandidates(candidates);
+    } else {
+      if (!transproxy->negotiated()) {
+        transproxy->AddSentCandidates(candidates);
+      }
+      SessionError error;
+      if (!SendTransportInfoMessage(transproxy, candidates, &error)) {
+        LOG(LS_ERROR) << "Could not send transport info message: "
+                      << error.text;
+        return;
+      }
     }
   }
 }
@@ -661,6 +674,22 @@
   }
 }
 
+void Session::OnIncomingResponse(const buzz::XmlElement* orig_stanza,
+                                 const buzz::XmlElement* response_stanza,
+                                 const SessionMessage& msg) {
+  ASSERT(signaling_thread_->IsCurrent());
+
+  if (msg.type == ACTION_SESSION_INITIATE) {
+    initiate_acked_ = true;
+    // TODO: This is to work around server re-ordering
+    // messages.  We send the candidates once the session-initiate
+    // is acked.  Once we have fixed the server to guarantee message
+    // order, we can remove this case.
+    SessionError error;
+    SendAllUnsentTransportInfoMessages(&error);
+  }
+}
+
 void Session::OnFailedSend(const buzz::XmlElement* orig_stanza,
                            const buzz::XmlElement* error_stanza) {
   ASSERT(signaling_thread_->IsCurrent());
@@ -955,6 +984,15 @@
   return SendMessage(ACTION_TRANSPORT_INFO, tinfo, error);
 }
 
+bool Session::SendTransportInfoMessage(const TransportProxy* transproxy,
+                                       const Candidates& candidates,
+                                       SessionError* error) {
+  return SendTransportInfoMessage(TransportInfo(transproxy->content_name(),
+                                                transproxy->type(),
+                                                candidates),
+                                  error);
+}
+
 bool Session::WriteSessionAction(SignalingProtocol protocol,
                                  const TransportInfo& tinfo,
                                  XmlElements* elems, WriteError* error) {
@@ -972,11 +1010,9 @@
     TransportProxy* transproxy = iter->second;
     if (transproxy->sent_candidates().size() > 0) {
       if (!SendTransportInfoMessage(
-              TransportInfo(
-                  transproxy->content_name(),
-                  transproxy->type(),
-                  transproxy->sent_candidates()),
-              error)) {
+              transproxy, transproxy->sent_candidates(), error)) {
+        LOG(LS_ERROR) << "Could not resend transport info messages: "
+                      << error->text;
         return false;
       }
       transproxy->ClearSentCandidates();
@@ -985,6 +1021,23 @@
   return true;
 }
 
+bool Session::SendAllUnsentTransportInfoMessages(SessionError* error) {
+  for (TransportMap::iterator iter = transports_.begin();
+       iter != transports_.end(); ++iter) {
+    TransportProxy* transproxy = iter->second;
+    if (transproxy->unsent_candidates().size() > 0) {
+      if (!SendTransportInfoMessage(
+              transproxy, transproxy->unsent_candidates(), error)) {
+        LOG(LS_ERROR) << "Could not send unsent transport info messages: "
+                      << error->text;
+        return false;
+      }
+      transproxy->ClearUnsentCandidates();
+    }
+  }
+  return true;
+}
+
 bool Session::SendMessage(ActionType type, const XmlElements& action_elems,
                           SessionError* error) {
   talk_base::scoped_ptr<buzz::XmlElement> stanza(
diff --git a/talk/p2p/base/session.h b/talk/p2p/base/session.h
index 6a8750c..ba254ad 100644
--- a/talk/p2p/base/session.h
+++ b/talk/p2p/base/session.h
@@ -90,13 +90,16 @@
   std::string type() const;
   bool negotiated() const { return state_ == STATE_NEGOTIATED; }
   const Candidates& sent_candidates() const { return sent_candidates_; }
+  const Candidates& unsent_candidates() const { return unsent_candidates_; }
 
   TransportChannel* GetChannel(const std::string& name);
   TransportChannel* CreateChannel(const std::string& name,
                                   const std::string& content_type);
   void DestroyChannel(const std::string& name);
   void AddSentCandidates(const Candidates& candidates);
+  void AddUnsentCandidates(const Candidates& candidates);
   void ClearSentCandidates() { sent_candidates_.clear(); }
+  void ClearUnsentCandidates() { unsent_candidates_.clear(); }
   void SpeculativelyConnectChannels();
   void CompleteNegotiation();
 
@@ -119,6 +122,7 @@
   TransportState state_;
   ChannelMap channels_;
   Candidates sent_candidates_;
+  Candidates unsent_candidates_;
 };
 
 typedef std::map<std::string, TransportProxy*> TransportMap;
@@ -442,7 +446,12 @@
   bool SendTerminateMessage(const std::string& reason, SessionError* error);
   bool SendTransportInfoMessage(const TransportInfo& tinfo,
                                 SessionError* error);
+  bool SendTransportInfoMessage(const TransportProxy* transproxy,
+                                const Candidates& candidates,
+                                SessionError* error);
+
   bool ResendAllTransportInfoMessages(SessionError* error);
+  bool SendAllUnsentTransportInfoMessages(SessionError* error);
 
   // Both versions of SendMessage send a message of the given type to
   // the other client.  Can pass either a set of elements or an
@@ -492,6 +501,9 @@
   sigslot::signal2<Session *, const buzz::XmlElement*> SignalOutgoingMessage;
   void OnIncomingMessage(const SessionMessage& msg);
 
+  void OnIncomingResponse(const buzz::XmlElement* orig_stanza,
+                          const buzz::XmlElement* response_stanza,
+                          const SessionMessage& msg);
   void OnFailedSend(const buzz::XmlElement* orig_stanza,
                     const buzz::XmlElement* error_stanza);
 
@@ -521,6 +533,7 @@
 
   SessionManager *session_manager_;
   bool initiator_;
+  bool initiate_acked_;
   std::string initiator_name_;
   std::string content_type_;
   SessionClient* client_;
diff --git a/talk/p2p/base/sessionmanager.cc b/talk/p2p/base/sessionmanager.cc
index 1a7d186..ba05bc7 100644
--- a/talk/p2p/base/sessionmanager.cc
+++ b/talk/p2p/base/sessionmanager.cc
@@ -29,6 +29,7 @@
 
 #include "talk/base/common.h"
 #include "talk/base/helpers.h"
+#include "talk/base/logging.h"
 #include "talk/base/scoped_ptr.h"
 #include "talk/base/stringencode.h"
 #include "talk/p2p/base/constants.h"
@@ -188,9 +189,18 @@
 
 void SessionManager::OnIncomingResponse(const buzz::XmlElement* orig_stanza,
     const buzz::XmlElement* response_stanza) {
-  // We don't do anything with the response now.  If we need to we can forward
-  // it to the session.
-  return;
+  SessionMessage msg;
+  ParseError error;
+  if (!ParseSessionMessage(orig_stanza, &msg, &error)) {
+    LOG(LS_WARNING) << "Error parsing incoming response: " << error.text
+                    << ":" << orig_stanza;
+    return;
+  }
+
+  Session* session = FindSession(msg.sid, msg.to);
+  if (session) {
+    session->OnIncomingResponse(orig_stanza, response_stanza, msg);
+  }
 }
 
 void SessionManager::OnFailedSend(const buzz::XmlElement* orig_stanza,