Added file share namespaces and tags to known list. Add utility methods used to build file share and result set management elements.
git-svn-id: http://yate.null.ro/svn/yate/trunk@5475 acf43c95-373e-0410-b603-e72c3f656dc1
This commit is contained in:
parent
a345ff2216
commit
d2be7683e8
|
@ -2562,7 +2562,7 @@ bool JBEntityCapsList::processCaps(String& capsId, XmlElement* xml, JBStream* st
|
|||
void JBEntityCapsList::addCaps(NamedList& list, JBEntityCaps& caps)
|
||||
{
|
||||
#define CHECK_NS(ns,param) \
|
||||
if (caps.m_features.get(ns)) { \
|
||||
if (caps.hasFeature(ns)) { \
|
||||
params->append(param,","); \
|
||||
list.addParam(param,String::boolText(true)); \
|
||||
}
|
||||
|
@ -2590,6 +2590,8 @@ void JBEntityCapsList::addCaps(NamedList& list, JBEntityCaps& caps)
|
|||
case 0:
|
||||
break;
|
||||
}
|
||||
CHECK_NS(XMPPNamespace::FileInfoShare,"caps.fileinfoshare");
|
||||
CHECK_NS(XMPPNamespace::ResultSetMngt,"caps.resultsetmngt");
|
||||
}
|
||||
CHECK_NS(XMPPNamespace::Muc,"caps.muc");
|
||||
#undef CHECK_NS
|
||||
|
|
|
@ -107,6 +107,9 @@ const String XMPPNamespace::s_array[Count] = {
|
|||
"http://jabber.org/protocol/chatstates", // ChatStates
|
||||
"http://yate.null.ro/yate/cluster", // YateCluster
|
||||
"http://www.google.com/transport/raw-udp", // JingleTransportGoogleRawUdp
|
||||
"urn:xmpp:hashes:1", // Hash
|
||||
"http://jabber.org/protocol/rsm", // ResultSetMngt
|
||||
"urn:xmpp.mam", // FileInfoShare
|
||||
};
|
||||
|
||||
const String XMPPError::s_array[Count] = {
|
||||
|
@ -249,6 +252,23 @@ const String XmlTag::s_array[Count] = {
|
|||
"compressed", // Compressed
|
||||
"compression", // Compression
|
||||
"x", // X
|
||||
"hash", // Hash
|
||||
"algo", // Algo
|
||||
"size", // Size
|
||||
"date", // Date
|
||||
"desc", // Desc
|
||||
"set", // Set
|
||||
"after", // After
|
||||
"before", // Before
|
||||
"count", // CountTag
|
||||
"first", // First
|
||||
"index", // Index
|
||||
"last", // Last
|
||||
"max", // Max
|
||||
"match", // Match
|
||||
"directory", // Directory
|
||||
"name", // Name
|
||||
"changed", // Changed
|
||||
};
|
||||
|
||||
XMPPNamespace XMPPUtils::s_ns;
|
||||
|
@ -342,13 +362,7 @@ void JabberID::set(const char* node, const char* domain, const char* resource)
|
|||
m_node = node;
|
||||
m_domain = domain;
|
||||
m_resource = resource;
|
||||
String::clear();
|
||||
if (m_node)
|
||||
*this << m_node << "@";
|
||||
*this << m_domain;
|
||||
m_bare = *this;
|
||||
if (m_node && m_resource)
|
||||
*this << "/" << m_resource;
|
||||
normalize();
|
||||
}
|
||||
|
||||
bool JabberID::valid(const String& value)
|
||||
|
@ -383,11 +397,20 @@ void JabberID::parse()
|
|||
m_domain = tmp.substr(0,i);
|
||||
m_resource = tmp.substr(i+1,tmp.length()-i-1);
|
||||
}
|
||||
// Set bare JID
|
||||
m_bare = "";
|
||||
normalize();
|
||||
}
|
||||
|
||||
void JabberID::normalize()
|
||||
{
|
||||
m_node.toLower();
|
||||
m_domain.toLower();
|
||||
m_bare.clear();
|
||||
if (m_node)
|
||||
m_bare << m_node << "@";
|
||||
m_bare << m_domain;
|
||||
assign(m_bare);
|
||||
if (m_resource)
|
||||
*this << "/" << m_resource;
|
||||
}
|
||||
|
||||
// Get an empty JabberID
|
||||
|
@ -730,6 +753,17 @@ void XMPPFeatureList::updateEntityCaps()
|
|||
/*
|
||||
* XMPPUtils
|
||||
*/
|
||||
// Find an xml tag in an array terminated with XmlTag::Count
|
||||
int XMPPUtils::findTag(const String& tag, int* tags)
|
||||
{
|
||||
if (!(tag && tags))
|
||||
return XmlTag::Count;
|
||||
for (; *tags != XmlTag::Count; tags++)
|
||||
if (tag == s_tag[*tags])
|
||||
return *tags;
|
||||
return XmlTag::Count;
|
||||
}
|
||||
|
||||
// Partially build an XML element from another one.
|
||||
XmlElement* XMPPUtils::createElement(const XmlElement& src, bool response, bool result)
|
||||
{
|
||||
|
@ -1037,6 +1071,76 @@ XmlElement* XMPPUtils::createDelay(unsigned int timeSec, const char* from,
|
|||
return x;
|
||||
}
|
||||
|
||||
// Create a 'file' element in file transfer namespace, add the name child if not empty
|
||||
XmlElement* XMPPUtils::createFileNsTransfer(const char* name)
|
||||
{
|
||||
XmlElement* x = createElement(XmlTag::File,XMPPNamespace::JingleAppsFileTransfer);
|
||||
if (!TelEngine::null(name))
|
||||
x->addChildSafe(createElement(XmlTag::Name,name));
|
||||
return x;
|
||||
}
|
||||
|
||||
// Create a 'hash' element as defined in XEP-0300
|
||||
XmlElement* XMPPUtils::createHash(const char* name, const char* value)
|
||||
{
|
||||
XmlElement* x = createElement(XmlTag::Hash,XMPPNamespace::Hash,value);
|
||||
x->setAttribute(s_tag[XmlTag::Algo],name);
|
||||
return x;
|
||||
}
|
||||
|
||||
// Decode a 'hash' element as defined in XEP-0300
|
||||
void XMPPUtils::decodeHash(XmlElement& xml, const char*& name, const char*& value)
|
||||
{
|
||||
name = xml.attribute(s_tag[XmlTag::Algo]);
|
||||
value = xml.getText();
|
||||
}
|
||||
|
||||
// Build a Result Set Management (XEP-0059) set element from a parameter list
|
||||
XmlElement* XMPPUtils::createRSM(const NamedList& params, const String& prefix)
|
||||
{
|
||||
static int s_rsmTags[] = {XmlTag::After,XmlTag::Before,XmlTag::CountTag,XmlTag::First,
|
||||
XmlTag::Index,XmlTag::Last,XmlTag::Max,XmlTag::Count};
|
||||
XmlElement* rsm = 0;
|
||||
NamedIterator iter(params);
|
||||
for (const NamedString* ns = 0; 0 != (ns = iter.get());) {
|
||||
if (!ns->name().startsWith(prefix))
|
||||
continue;
|
||||
String tmp = ns->name().substr(prefix.length());
|
||||
int tag = findTag(tmp,s_rsmTags);
|
||||
if (tag == XmlTag::Count)
|
||||
continue;
|
||||
XmlElement* x = createElement(tmp,*ns);
|
||||
if (tag == XmlTag::First) {
|
||||
String* index = params.getParam(ns->name() + ".index");
|
||||
if (!TelEngine::null(index))
|
||||
x->setAttribute(s_tag[XmlTag::Index],*index);
|
||||
}
|
||||
if (!rsm)
|
||||
rsm = createElement(XmlTag::Set,XMPPNamespace::ResultSetMngt);
|
||||
rsm->addChildSafe(x);
|
||||
}
|
||||
return rsm;
|
||||
}
|
||||
|
||||
// Add Result Set Management (XEP-0059) set element child data to a parameter list
|
||||
void XMPPUtils::addRSM(XmlElement* rsm, NamedList& params, const String& prefix)
|
||||
{
|
||||
if (!rsm)
|
||||
return;
|
||||
for (XmlElement* c = 0; 0 != (c = rsm->findNextChild(c));) {
|
||||
int tag = XmlTag::Count;
|
||||
int ns = XMPPNamespace::Count;
|
||||
getTag(*c,tag,ns);
|
||||
String p = prefix + c->unprefixedTag();
|
||||
params.addParam(p,c->getText());
|
||||
if (tag == XmlTag::First && ns == XMPPNamespace::ResultSetMngt) {
|
||||
const char* index = c->attribute(s_ns[XmlTag::Index]);
|
||||
if (index)
|
||||
params.addParam(p + ".index",index);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Check if an element has a child with 'priority' tag
|
||||
int XMPPUtils::priority(XmlElement& xml, int defVal)
|
||||
{
|
||||
|
@ -1524,13 +1628,13 @@ const String& XMPPUtils::body(XmlElement& xml, int ns)
|
|||
}
|
||||
|
||||
// Retrieve an xml element from a NamedPointer. Release its ownership
|
||||
XmlElement* XMPPUtils::getXml(GenObject* gen)
|
||||
XmlElement* XMPPUtils::getXml(GenObject* gen, bool takeOwnerShip)
|
||||
{
|
||||
if (!gen)
|
||||
return 0;
|
||||
NamedPointer* np = static_cast<NamedPointer*>(gen->getObject(YATOM("NamedPointer")));
|
||||
XmlElement* xml = np ? static_cast<XmlElement*>(np->userObject(YATOM("XmlElement"))) : 0;
|
||||
if (xml)
|
||||
if (xml && takeOwnerShip)
|
||||
np->takeData();
|
||||
return xml;
|
||||
}
|
||||
|
|
|
@ -191,6 +191,9 @@ public:
|
|||
ChatStates, // http://jabber.org/protocol/chatstates
|
||||
YateCluster, // http://yate.null.ro/yate/cluster
|
||||
JingleTransportGoogleRawUdp, // http://www.google.com/transport/raw-udp
|
||||
Hash, // urn:xmpp:hashes:1
|
||||
ResultSetMngt, // http://jabber.org/protocol/rsm
|
||||
FileInfoShare, // urn:xmpp:mam
|
||||
// This value MUST be the last one: it's used as array bound
|
||||
Count,
|
||||
};
|
||||
|
@ -388,6 +391,23 @@ public:
|
|||
Compressed, // compressed
|
||||
Compression, // compression
|
||||
X, // x
|
||||
Hash, // hash
|
||||
Algo, // algo
|
||||
Size, // size
|
||||
Date, // date
|
||||
Desc, // desc
|
||||
Set, // set
|
||||
After, // after
|
||||
Before, // before
|
||||
CountTag, // count
|
||||
First, // first
|
||||
Index, // index
|
||||
Last, // last
|
||||
Max, // max
|
||||
Match, // match
|
||||
Directory, // directory
|
||||
Name, // name
|
||||
Changed, // changed
|
||||
// This value MUST be the last one: it's used as array bound
|
||||
Count
|
||||
};
|
||||
|
@ -620,6 +640,7 @@ public:
|
|||
|
||||
private:
|
||||
void parse(); // Parse the string. Set the data
|
||||
void normalize(); // Lowercase node and domain. Set bare jid and jid
|
||||
|
||||
String m_node; // The node part
|
||||
String m_domain; // The domain part
|
||||
|
@ -1108,6 +1129,14 @@ public:
|
|||
AuthDialback = 0x08, // Dialback authentication
|
||||
};
|
||||
|
||||
/**
|
||||
* Find an xml tag in an array terminated with XmlTag::Count
|
||||
* @param tag Tag to find
|
||||
* @param tags Tags list
|
||||
* @return XmlTag value, XmlTag::Count if not found
|
||||
*/
|
||||
static int findTag(const String& tag, int* tags);
|
||||
|
||||
/**
|
||||
* Check if an xml element has type 'result' or 'error'
|
||||
* @param xml The element to check
|
||||
|
@ -1118,6 +1147,28 @@ public:
|
|||
return tmp && (*tmp == "result" || *tmp == "error");
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve a JID from 'to' and 'to_instance' parameters
|
||||
* @param params Parameter list
|
||||
* @param jid Destination to be set
|
||||
*/
|
||||
static inline void getJIDTo(const NamedList& params, JabberID& jid) {
|
||||
jid = params[YSTRING("to")];
|
||||
if (jid && !jid.resource())
|
||||
jid.resource(params[YSTRING("to_instance")]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve a JID from 'from' and 'from_instance' parameters
|
||||
* @param params Parameter list
|
||||
* @param jid Destination to be set
|
||||
*/
|
||||
static inline void getJIDFrom(const NamedList& params, JabberID& jid) {
|
||||
jid = params[YSTRING("from")];
|
||||
if (jid && !jid.resource())
|
||||
jid.resource(params[YSTRING("from_instance")]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create an XML element
|
||||
* @param name Element's name
|
||||
|
@ -1178,6 +1229,21 @@ public:
|
|||
*/
|
||||
static XmlElement* createElement(const XmlElement& src, bool response, bool result);
|
||||
|
||||
/**
|
||||
* Create an element with an attribute
|
||||
* @param tag Element tag
|
||||
* @param attrName Attribute name
|
||||
* @param attrValue Attribute value
|
||||
* @param ns Optional 'xmlns' attribute as enumeration
|
||||
* @return A valid XmlElement pointer
|
||||
*/
|
||||
static inline XmlElement* createElementAttr(int tag, const String& attrName,
|
||||
const char* attrValue, int ns = XMPPNamespace::Count) {
|
||||
XmlElement* x = createElement(tag,ns);
|
||||
x->setAttributeValid(attrName,attrValue);
|
||||
return x;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create an 'iq' element
|
||||
* @param type Iq type as enumeration
|
||||
|
@ -1410,6 +1476,57 @@ public:
|
|||
static XmlElement* createDelay(unsigned int timeSec, const char* from = 0,
|
||||
unsigned int fractions = 0, const char* text = 0);
|
||||
|
||||
/**
|
||||
* Create a 'file' element in file transfer namespace, add the name child if not empty
|
||||
* @param name Optional file name
|
||||
* @return XmlElement pointer
|
||||
*/
|
||||
static XmlElement* createFileNsTransfer(const char* name = 0);
|
||||
|
||||
/**
|
||||
* Create a 'hash' element as defined in XEP-0300
|
||||
* @param name Hash name
|
||||
* @param value Hash value
|
||||
* @return XmlElement pointer
|
||||
*/
|
||||
static XmlElement* createHash(const char* name, const char* value);
|
||||
|
||||
/**
|
||||
* Decode a 'hash' element as defined in XEP-0300
|
||||
* @param xml XML element to handle
|
||||
* @param name Hash name
|
||||
* @param value Hash value
|
||||
*/
|
||||
static void decodeHash(XmlElement& xml, const char*& name, const char*& value);
|
||||
|
||||
/**
|
||||
* Create a 'match' element in FileInfoShare namespace
|
||||
* @param child Optional child
|
||||
* @return XmlElement pointer
|
||||
*/
|
||||
static inline XmlElement* createFileInfoShareMatch(XmlElement* child = 0) {
|
||||
XmlElement* m = createElement(XmlTag::Match,XMPPNamespace::FileInfoShare);
|
||||
if (child)
|
||||
m->addChildSafe(child);
|
||||
return m;
|
||||
}
|
||||
|
||||
/**
|
||||
* Build a Result Set Management (XEP-0059) set element from a parameter list
|
||||
* @param params List of parameters containing the RSM
|
||||
* @param prefix Prefix for RSM parameters
|
||||
* @return XmlElement pointer or 0
|
||||
*/
|
||||
static XmlElement* createRSM(const NamedList& params, const String& prefix = "rsm_");
|
||||
|
||||
/**
|
||||
* Add Result Set Management (XEP-0059) set element child data to a parameter list
|
||||
* @param rsn The element in RSM namespace
|
||||
* @param params List of parameters to add the RSM data
|
||||
* @param prefix Prefix for RSM parameters
|
||||
*/
|
||||
static void addRSM(XmlElement* rsm, NamedList& params, const String& prefix = "rsm_");
|
||||
|
||||
/**
|
||||
* Check if an element has a child with 'remove' tag
|
||||
* @param xml The element to check
|
||||
|
@ -1525,6 +1642,38 @@ public:
|
|||
static XmlElement* findNextChild(const XmlElement& xml, XmlElement* start,
|
||||
int t = XmlTag::Count, int ns = XMPPNamespace::Count);
|
||||
|
||||
/**
|
||||
* Retrieve a child's text
|
||||
* @param xml The xml
|
||||
* @param tag Child tag
|
||||
* @param ns Optional child namespace
|
||||
* @return Pointer to child's text, 0 if the child was not found
|
||||
*/
|
||||
static inline const String* childText(XmlElement& xml, int tag, int ns = XMPPNamespace::Count) {
|
||||
XmlElement* c = findFirstChild(xml,tag,ns);
|
||||
return c ? &(c->getText()) : 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve a child's text converted to integer
|
||||
* @param xml The xml
|
||||
* @param tag Child tag
|
||||
* @param ns Optional child namespace
|
||||
* @param defVal Default to return if not found or the string is not a number
|
||||
* @param base Numeration base, 0 to autodetect
|
||||
* @param minvalue Minimum value allowed
|
||||
* @param maxvalue Maximum value allowed
|
||||
* @param clamp Control the out of bound values: true to adjust to the nearest
|
||||
* bound, false to return the default value
|
||||
* @return Integer value
|
||||
*/
|
||||
static inline int childTextInt(XmlElement& xml, int tag, int ns = XMPPNamespace::Count,
|
||||
int defVal = 0, int base = 0, int minvalue = INT_MIN, int maxvalue = INT_MAX,
|
||||
bool clamp = true) {
|
||||
const String* tmp = childText(xml,tag,ns);
|
||||
return tmp ? tmp->toInteger(defVal,base,minvalue,maxvalue,clamp) : defVal;
|
||||
}
|
||||
|
||||
/**
|
||||
* Find an error child of a given element and decode it
|
||||
* @param xml The element
|
||||
|
@ -1856,11 +2005,12 @@ public:
|
|||
|
||||
/**
|
||||
* Retrieve an xml element from a NamedPointer.
|
||||
* Release NamedPointer ownership if found
|
||||
* Release NamedPointer ownership if found and requested
|
||||
* @param gen The object to be processed
|
||||
* @param takeOwnerShip Take ownership (defaults to true)
|
||||
* @return XmlElement pointer or 0
|
||||
*/
|
||||
static XmlElement* getXml(GenObject* gen);
|
||||
static XmlElement* getXml(GenObject* gen, bool takeOwnerShip = true);
|
||||
|
||||
/**
|
||||
* Parse a string to an XmlElement
|
||||
|
@ -2052,6 +2202,14 @@ public:
|
|||
: m_value(0)
|
||||
{ replace(flags); }
|
||||
|
||||
/**
|
||||
* Copy constructor
|
||||
* @param other Source to copy
|
||||
*/
|
||||
inline XMPPDirVal(const XMPPDirVal& other)
|
||||
: m_value(other.m_value)
|
||||
{}
|
||||
|
||||
/**
|
||||
* Replace all flags
|
||||
* @param flag The new value of the flags
|
||||
|
|
|
@ -2791,14 +2791,22 @@ public:
|
|||
m_version(version), m_node(node), m_data(data)
|
||||
{}
|
||||
|
||||
/**
|
||||
* Check if a given feature is found in the list
|
||||
* @param ns The feature to check
|
||||
* @return True if the feature was found in the list
|
||||
*/
|
||||
inline bool hasFeature(int ns)
|
||||
{ return 0 != m_features.get(ns); }
|
||||
|
||||
/**
|
||||
* Check if an audio capability is present
|
||||
* @return True if an audio capability is present
|
||||
*/
|
||||
inline bool hasAudio() {
|
||||
return m_features.get(XMPPNamespace::JingleAppsRtpAudio) ||
|
||||
m_features.get(XMPPNamespace::JingleAudio) ||
|
||||
m_features.get(XMPPNamespace::JingleVoiceV1);
|
||||
return hasFeature(XMPPNamespace::JingleAppsRtpAudio) ||
|
||||
hasFeature(XMPPNamespace::JingleAudio) ||
|
||||
hasFeature(XMPPNamespace::JingleVoiceV1);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
Loading…
Reference in New Issue