[ekiga] Made presence mostly work again in ekiga



commit abc0cce3c74ace9c22cd8d63ace294aca7e07b57
Author: Julien Puydt <jpuydt gnome org>
Date:   Sat Sep 25 11:51:21 2010 +0200

    Made presence mostly work again in ekiga
    
    This code is wrong, and will have to change, but it's a stopgap for better days.

 lib/engine/components/opal/sip-endpoint.cpp |  207 +++++++++++++++++++++++----
 lib/engine/components/opal/sip-endpoint.h   |    4 +-
 2 files changed, 181 insertions(+), 30 deletions(-)
---
diff --git a/lib/engine/components/opal/sip-endpoint.cpp b/lib/engine/components/opal/sip-endpoint.cpp
index b40d916..dc962e1 100644
--- a/lib/engine/components/opal/sip-endpoint.cpp
+++ b/lib/engine/components/opal/sip-endpoint.cpp
@@ -53,6 +53,8 @@
 #include "personal-details.h"
 #include "opal-account.h"
 
+#include <ptclib/pxml.h>
+
 namespace Opal {
 
   namespace Sip {
@@ -325,7 +327,7 @@ Opal::Sip::EndPoint::publish (const Ekiga::PersonalDetails & details)
       data += "</status>\r\n";
 
       data += "<contact priority=\"1\">";
-      data += to; 
+      data += to;
       data += "</contact>\r\n";
 
       data += "</tuple>\r\n";
@@ -910,11 +912,11 @@ Opal::Sip::EndPoint::OnIncomingConnection (OpalConnection &connection,
 }
 
 
-PBoolean 
-Opal::Sip::EndPoint::OnReceivedINVITE (OpalTransport& transport, 
+PBoolean
+Opal::Sip::EndPoint::OnReceivedINVITE (OpalTransport& transport,
                                        SIP_PDU* pdu)
 {
-  if (pdu == NULL) 
+  if (pdu == NULL)
     return SIPEndPoint::OnReceivedINVITE (transport, pdu);
 
   PString str;
@@ -998,45 +1000,79 @@ Opal::Sip::EndPoint::GetRegisteredPartyName (const SIPURL & aor,
 
 
 void
-Opal::Sip::EndPoint::OnPresenceInfoReceived (const PString & user,
-                                             const PString & basic,
-                                             const PString & note)
+Opal::Sip::EndPoint::OnPresenceInfoReceived (const SIPPresenceInfo& info)
 {
-  PINDEX j;
-  PCaselessString b = basic;
-  PCaselessString s = note;
-
   std::string presence = "unknown";
   std::string status;
 
-  if (!basic.IsEmpty ()) {
+  /* we could do something precise */
+  switch (info.m_state) {
 
-    if (b.Find ("Open") != P_MAX_INDEX)
-      presence = "online";
-    else
-      presence = "offline";
+  case OpalPresenceInfo::InternalError:
+  case OpalPresenceInfo::Forbidden:
+  case OpalPresenceInfo::NoPresence:
+  case OpalPresenceInfo::Unchanged:
+  case OpalPresenceInfo::Unavailable:
+    presence = "offline";
+    break;
+
+  case OpalPresenceInfo::Available:
+  case OpalPresenceInfo::UnknownExtended:
+  case OpalPresenceInfo::Appointment:
+  case OpalPresenceInfo::Away:
+  case OpalPresenceInfo::Breakfast:
+  case OpalPresenceInfo::Busy:
+  case OpalPresenceInfo::Dinner:
+  case OpalPresenceInfo::Holiday:
+  case OpalPresenceInfo::InTransit:
+  case OpalPresenceInfo::LookingForWork:
+  case OpalPresenceInfo::Lunch:
+  case OpalPresenceInfo::Meal:
+  case OpalPresenceInfo::Meeting:
+  case OpalPresenceInfo::OnThePhone:
+  case OpalPresenceInfo::Other:
+  case OpalPresenceInfo::Performance:
+  case OpalPresenceInfo::PermanentAbsence:
+  case OpalPresenceInfo::Playing:
+  case OpalPresenceInfo::Presentation:
+  case OpalPresenceInfo:: Shopping:
+  case OpalPresenceInfo::Sleeping:
+  case OpalPresenceInfo::Spectator:
+  case OpalPresenceInfo::Steering:
+  case OpalPresenceInfo::Travel:
+  case OpalPresenceInfo::TV:
+  case OpalPresenceInfo::Vacation:
+  case OpalPresenceInfo::Working:
+  case OpalPresenceInfo:: Worship:
+    presence = "online";
+    break;
+  default:
+    presence = "offline";
+    break;
   }
 
-  if (!note.IsEmpty ()) {
+  if (!info.m_note.IsEmpty ()) {
 
-    if (s.Find ("Away") != P_MAX_INDEX)
+    PINDEX j;
+    PCaselessString note = info.m_note;
+    if (note.Find ("Away") != P_MAX_INDEX)
       presence = "away";
-    else if (s.Find ("On the phone") != P_MAX_INDEX)
+    else if (note.Find ("On the phone") != P_MAX_INDEX)
       presence = "inacall";
-    else if (s.Find ("Ringing") != P_MAX_INDEX)
+    else if (note.Find ("Ringing") != P_MAX_INDEX)
       presence = "ringing";
-    else if (s.Find ("dnd") != P_MAX_INDEX
-             || s.Find ("Do Not Disturb") != P_MAX_INDEX)
+    else if (note.Find ("dnd") != P_MAX_INDEX
+             || note.Find ("Do Not Disturb") != P_MAX_INDEX)
       presence = "dnd";
 
-    else if (s.Find ("Free For Chat") != P_MAX_INDEX)
+    else if (note.Find ("Free For Chat") != P_MAX_INDEX)
       presence = "freeforchat";
 
-    if ((j = s.Find (" - ")) != P_MAX_INDEX)
-      status = (const char *) note.Mid (j + 3);
+    if ((j = note.Find (" - ")) != P_MAX_INDEX)
+      status = (const char *) info.m_note.Mid (j + 3);
   }
 
-  SIPURL sip_uri = SIPURL (user);
+  SIPURL sip_uri = SIPURL (info.m_entity);
   sip_uri.Sanitise (SIPURL::ExternalURI);
   std::string _uri = sip_uri.AsString ();
   std::string old_presence = presence_infos[_uri].presence;
@@ -1157,7 +1193,7 @@ Opal::Sip::EndPoint::registration_event_in_main (const std::string aor,
   boost::shared_ptr<Opal::Bank> bank = core.get<Opal::Bank> ("opal-account-store");
   AccountPtr account = bank->find_account (aor);
 
-  if (account) 
+  if (account)
     account->handle_registration_event (state, msg);
 }
 
@@ -1199,3 +1235,120 @@ Opal::Sip::EndPoint::mwi_received_in_main (const std::string aor,
     account->handle_message_waiting_information (info);
   }
 }
+
+
+// FIXME -- REMOVE
+//
+// The code below is just a hack to get presence going again in ekiga
+// it's based on code in the lalande branch, and just provides a bridge
+// between opal's old old api and opal's new api.
+//
+// It has been written around 2010-09-25 and isn't supposed to last long
+
+class SIPPresenceEventPackageHandler : public SIPEventPackageHandler
+{
+  virtual PCaselessString GetContentType () const
+  {
+    return "application/pidf+xml";
+  }
+
+  virtual bool OnReceivedNOTIFY(SIPHandler& handler,
+				SIP_PDU& request)
+  {
+    bool result;
+    SIPPresenceInfo info;
+
+    SIPURL from = request.GetMIME ().GetFrom ();
+    SIPURL to = request.GetMIME ().GetTo ();
+
+    from.Sanitise (SIPURL::ExternalURI);
+    info.m_entity = from.AsString ();
+
+    to.Sanitise (SIPURL::ExternalURI);
+    info.m_target = to.AsString ();
+
+    // if we have an empty body, it's just a ping
+    if (request.GetEntityBody ().IsEmpty ()) {
+
+      handler.GetEndPoint ().OnPresenceInfoReceived (info);
+      return false;
+    }
+
+    PXML xml;
+    if (xml.Load (request.GetEntityBody ())) {
+
+      /* now if we get a valid XML fragment, then it look like :
+       * <presence>
+       *   <tuple>
+       *      <status>
+       *         <basic>something</basic>
+       *         <note>something</note>
+       *      </status>
+       *      <contact>something</contact>
+       *   </tuple>
+       * </presence>
+       *
+       * well, it mostly looks like this, because the note element could end
+       * up just under tuple or presence...
+       */
+
+      PXMLElement* presence = NULL;
+      PXMLElement* tuple = NULL;
+      PXMLElement* status = NULL;
+      PXMLElement* basic = NULL;
+      PXMLElement* contact = NULL;
+      PXMLElement* note = NULL;
+
+      presence = xml.GetRootElement ();
+      if (presence && presence->GetName () == "presence") {
+
+	// ok, it looks legit
+	tuple = presence->GetElement ("tuple");
+	if (tuple) {
+
+	  status = tuple->GetElement ("status");
+	  contact = tuple->GetElement ("contact");
+
+	  if (status) {
+
+	    basic = status->GetElement ("basic");
+	    note = status->GetElement ("note");
+	  }
+	}
+
+	// let's deal with the moving note element
+	if (!note)
+	  note = presence->GetElement ("note");
+	if (!note && tuple)
+	  note = tuple->GetElement ("note");
+
+	// we know where everything is : just get the data from there
+	if (basic) {
+
+	  PCaselessString val = basic->GetData ();
+	  if (val == "open")
+	    info.m_state = SIPPresenceInfo::Available;
+	  else if (val == "closed")
+	    info.m_state = SIPPresenceInfo::Unavailable;
+	}
+	if (note) {
+
+	  info.m_note = note->GetData ();
+	}
+	if (contact) {
+
+	  info.m_contact = contact->GetData ();
+	}
+
+	result = true;
+      }
+      
+      if (result)
+	handler.GetEndPoint().OnPresenceInfoReceived(info);
+    }
+
+    return result;
+  }
+};
+
+static SIPEventPackageFactory::Worker<SIPPresenceEventPackageHandler> presenceEventPackageHandler(SIPSubscribe::Presence);
diff --git a/lib/engine/components/opal/sip-endpoint.h b/lib/engine/components/opal/sip-endpoint.h
index 0262d6d..aeb8c12 100644
--- a/lib/engine/components/opal/sip-endpoint.h
+++ b/lib/engine/components/opal/sip-endpoint.h
@@ -179,9 +179,7 @@ namespace Opal {
                                  unsigned options,
                                  OpalConnection::StringOptions * stroptions);
 
-      void OnPresenceInfoReceived (const PString & user,
-                                   const PString & basic,
-                                   const PString & note);
+      void OnPresenceInfoReceived (const SIPPresenceInfo& info);
 
       void OnDialogInfoReceived (const SIPDialogNotification & info);
 



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