| < Previous by Date | Date Index | Next by Date > |
| Thread Index |
|
Hi everybody, I am using resprocate library to develop a SIP client. I had problems when parsing presence information from the other users. I've also tried limpc and found out that limpc has the same problem. The problem was one way: from the other client to limpc. The other clients had no problem with limpc's status recognition. I've investigated the sources and I've found out that Pidf::parse() fails to parse the body of the NOTIFY request. The other SIP client uses XML namespace associated with a namespace prefix to scope the Pidf element names. Example: <pr:presence xmlns:pr="urn:ietf:params:xml:ns:pidf"> <pr:tuple> <pr:status> <pr:basic>open</pr:basic> <pr:status> </pr:tuple> </pr:presence> But the Pidf parser works only when the global namespace is used. In this case we have no namespace prefix. Example: <presence xmlns="urn:ietf:params:xml:ns:pidf"> <tuple> <status> <basic>open</basic> </status> <tuple> </presence> I made some corrections to be able to parse presence elements that are prefixed by a namespace prefix. I am attaching the patch. Maybe someone is interested. The patch was made against the main trunk of the repository, revision 6387 Best Regards, Orlin Jechev |
Index: resip/stack/Pidf.cxx
===================================================================
--- resip/stack/Pidf.cxx (revision 6387)
+++ resip/stack/Pidf.cxx (working copy)
@@ -146,18 +146,38 @@
str << " </tuple>" << Symbols::CRLF;
}
str << "</presence>" << Symbols::CRLF;
-
+
return str;
}
-void
+void
Pidf::parse(ParseBuffer& pb)
{
DebugLog(<< "Pidf::parse(" << Data(pb.start(), int(pb.end()-pb.start())) << ") ");
+ std::string pidf_namespace;
+
XMLCursor xml(pb);
- if (xml.getTag() == "presence")
+ XMLCursor::AttributeMap attr = xml.getAttributes();
+ XMLCursor::AttributeMap::const_iterator it =
+ std::find_if(attr.begin(), attr.end(), XMLCursor::AttributeValueEqual("urn:ietf:params:xml:ns:pidf"));
+
+ if ( it != attr.end() ) {
+
+ std::string key(it->first.data(), it->first.size());
+
+ size_t pos = key.find(':');
+
+ if ( pos != string::npos) {
+ pidf_namespace.assign(key, pos+1, key.size()-pos-1);
+ pidf_namespace.append(1, ':');
+ }
+ }
+
+ const std::string presence = pidf_namespace + "presence";
+
+ if (xml.getTag() == presence.c_str())
{
XMLCursor::AttributeMap::const_iterator i = xml.getAttributes().find("entity");
if (i != xml.getAttributes().end())
@@ -168,12 +188,13 @@
{
DebugLog(<< "no entity!");
}
-
+
if (xml.firstChild())
{
do
{
- if (xml.getTag() == "tuple")
+ const std::string tuple = pidf_namespace + "tuple";
+ if (xml.getTag() == tuple.c_str())
{
Tuple t;
t.attributes = xml.getAttributes();
@@ -183,20 +204,25 @@
t.id = i->second;
t.attributes.erase("id");
}
-
+
// look for status, contacts, notes -- take last of each for now
if (xml.firstChild())
{
do
{
- if (xml.getTag() == "status")
+ const std::string status = pidf_namespace + "status";
+ const std::string contact = pidf_namespace + "contact";
+ const std::string note = pidf_namespace + "note";
+ const std::string timestamp = pidf_namespace + "timestamp";
+ if (xml.getTag() == status.c_str())
{
// look for basic
if (xml.firstChild())
{
do
{
- if (xml.getTag() == "basic")
+ std::string basic = pidf_namespace + "basic";
+ if (xml.getTag() == basic.c_str())
{
if (xml.firstChild())
{
@@ -208,7 +234,7 @@
xml.parent();
}
}
- else if (xml.getTag() == "contact")
+ else if (xml.getTag() == contact.c_str())
{
XMLCursor::AttributeMap::const_iterator i = xml.getAttributes().find("priority");
if (i != xml.getAttributes().end())
@@ -221,7 +247,7 @@
xml.parent();
}
}
- else if (xml.getTag() == "note")
+ else if (xml.getTag() == note.c_str())
{
if (xml.firstChild())
{
@@ -229,7 +255,7 @@
xml.parent();
}
}
- else if (xml.getTag() == "timestamp")
+ else if (xml.getTag() == timestamp.c_str())
{
if (xml.firstChild())
{
Index: resip/stack/XMLCursor.hxx
===================================================================
--- resip/stack/XMLCursor.hxx (revision 6387)
+++ resip/stack/XMLCursor.hxx (working copy)
@@ -119,6 +119,13 @@
static std::ostream& encode(std::ostream& strm, const AttributeMap& attrs);
class Node;
+ class AttributeValueEqual {
+ Data data_;
+ public:
+ AttributeValueEqual(const Data& data) : data_(data) {};
+ bool operator()(const std::pair<Data, Data>& data) { return data.second == data_; }
+ };
+
private:
static void skipProlog(ParseBuffer& pb);
static void decode(Data&);