/// <summary> /// Queries the XMPP entity with the specified JID for its software /// version. /// </summary> /// <param name="jid">The JID of the XMPP entity to query.</param> /// <returns>An instance of the VersionInformation class containing the /// entity's software version.</returns> /// <exception cref="ArgumentNullException">The jid parameter is /// null.</exception> /// <exception cref="NotSupportedException">The XMPP entity with /// the specified JID does not support the 'Software Version' XMPP /// extension.</exception> /// <exception cref="XmppErrorException">The server returned an XMPP error code. /// Use the Error property of the XmppErrorException to obtain the specific /// error condition.</exception> /// <exception cref="XmppException">The server returned invalid data or another /// unspecified XMPP error occurred.</exception> public VersionInformation GetVersion(Jid jid) { jid.ThrowIfNull("jid"); if (!ecapa.Supports(jid, Extension.SoftwareVersion)) { throw new NotSupportedException("The XMPP entity does not support the " + "'Software Version' extension."); } Iq response = im.IqRequest(IqType.Get, jid, im.Jid, Xml.Element("query", "jabber:iq:version")); if (response.Type == IqType.Error) { throw Util.ExceptionFromError(response, "The version could not be retrieved."); } // Parse the response. var query = response.Data.Element("query"); if (query == null || query.GetDefaultNamespace().NamespaceName != "jabber:iq:version") { throw new XmppException("Erroneous server response: " + response); } if (query.Element("name") == null || query.Element("version") == null) { throw new XmppException("Missing name or version element: " + response); } string os = query.Element("os") != null?query.Element("os").Value : null; return(new VersionInformation(query.Element("name").Value, query.Element("version").Value, os)); }
/// <summary> /// Attempts to initiate a data stream with the XMPP entity with the specified /// JID. /// </summary> /// <param name="to">The JID of the XMPP entity to initiate a data-stream /// with.</param> /// <param name="mimeType">The MIME type of the data to be transferred across /// the stream.</param> /// <param name="profile">The 'Stream Initiation' profile to use.</param> /// <param name="streamOptions">An enumerable collection of supported /// stream methods which are advertised to the receiving XMPP /// entity.</param> /// <param name="data">An XML element containing any additional data the /// specified 'Stream Initiation' profile may require.</param> /// <returns>An initialized instance of the InitiationResult class containing /// the negotiated stream-method and session identifier.</returns> /// <exception cref="ArgumentNullException">The to parameter or the mimeType /// parameter or the profile parameter or the streamOptions parameter /// is null.</exception> /// <exception cref="ArgumentException">The streamOptions enumerable contains /// no elements, or the stream-initiation response received contained no /// selection for the stream-method.</exception> /// <exception cref="NotSupportedException">The XMPP entity with /// the specified JID does not support the 'Stream Initiation' XMPP /// extension.</exception> /// <exception cref="XmppErrorException">The server or the receiving XMPP /// entity returned an XMPP error code. Use the Error property of the /// XmppErrorException to obtain the specific error condition.</exception> /// <exception cref="XmppException">The server returned invalid data or another /// unspecified XMPP error occurred.</exception> public InitiationResult InitiateStream(Jid to, string mimeType, string profile, IEnumerable <string> streamOptions, XElement data = null) { to.ThrowIfNull("to"); mimeType.ThrowIfNull("mimeType"); profile.ThrowIfNull("profile"); streamOptions.ThrowIfNull("streamOptions"); if (streamOptions.Count() == 0) { throw new ArgumentException("The streamOptions enumerable must " + "include one or more stream-options."); } if (!ecapa.Supports(to, Extension.StreamInitiation)) { throw new NotSupportedException("The XMPP entity does not support " + "the 'Stream Initiation' extension."); } string sid = GenerateSessionId(); var si = CreateSiElement(sid, mimeType, profile, streamOptions, data); // Perform the actual request. Iq iq = im.IqRequest(IqType.Set, to, im.Jid, si); if (iq.Type == IqType.Error) { throw Util.ExceptionFromError(iq, "Stream initiation failed."); } // Result must contain a 'feature' element. var feat = iq.Data.Element("si").Element("feature"); string selected = ParseStreamMethod(feat); // Construct and return the initiation result. return(new InitiationResult(sid, selected, iq.Data.Element("si"))); }
//public void CopyNodes(XDocument targetDocument, XNode targetNode, XNode source) //{ // XNode targetChildNode = targetDocument.CreateNode(source.NodeType, source.Name, ""); // if (!source.HasChildNodes) // targetChildNode.InnerText = source.InnerText; // targetNode.AppendChild(targetChildNode); // foreach (XNode childNode in source.ChildNodes) // { // CopyNodes(targetDocument, targetChildNode, childNode); // } //} /// <summary> /// Requests the XMPP entity with the specified JID a GET command. /// When the Result is received and it not not an error /// if fires the callback function /// </summary> /// <param name="jid">The JID of the XMPP entity to get.</param> /// <exception cref="ArgumentNullException">The jid parameter /// is null.</exception> /// <exception cref="NotSupportedException">The XMPP entity with /// the specified JID does not support the 'Ping' XMPP extension.</exception> /// <exception cref="XmppErrorException">The server returned an XMPP error code. /// Use the Error property of the XmppErrorException to obtain the specific /// error condition.</exception> /// <exception cref="XmppException">The server returned invalid data or another /// unspecified XMPP error occurred.</exception> public void RequestCustomIqAsync(Jid jid, string request, Action callback) { jid.ThrowIfNull("jid"); request.ThrowIfNull("str"); //First check if the Jid entity supports the namespace if (!ecapa.Supports(jid, Extension.CustomIqExtension)) { throw new NotSupportedException("The XMPP entity does not support the " + "'CustomIqExtension' extension."); } var xml = Xml.Element("customiq", "urn:sharp.xmpp:customiq").Text(request); //The Request is Async im.IqRequestAsync(IqType.Get, jid, im.Jid, xml, null, (id, iq) => { //For any reply we execute the callback if (iq.Type == IqType.Error) { throw Util.ExceptionFromError(iq, "Could not Send Object to XMPP entity."); } if (iq.Type == IqType.Result) { try { //An empty response means the Message was received if (callback != null) { callback.Invoke(); } } catch (Exception e) { System.Diagnostics.Debug.WriteLine("Not correctly formated response to RequestCustomIqAsync" + e.StackTrace + e.ToString()); throw Util.ExceptionFromError(iq, "Not correctly formated response to RequestCustomIqAsync, " + e.Message); } } }); }
/// <summary> /// Gets the attention of the XMPP user with the specified JID. /// </summary> /// <param name="jid">The JID of the user to grab the attention of.</param> /// <param name="message">A Message to sent along.</param> /// <exception cref="ArgumentNullException">The jid parameter /// is null.</exception> /// <exception cref="NotSupportedException">The XMPP entity with /// the specified JID does not support the 'Attention' XMPP /// extension.</exception> public void GetAttention(Jid jid, string message = null) { jid.ThrowIfNull("jid"); if (!ecapa.Supports(jid, Extension.Attention)) { throw new NotSupportedException("The XMPP entity does not support the " + "'Attention' extension."); } Im.Message m = new Im.Message(jid, message); // Add the 'attention' element to the Message. m.Data.Child(Xml.Element("attention", "urn:xmpp:attention:0")); im.SendMessage(m); }
/// <summary> /// Returns an enumerable collection of blocked contacts. /// </summary> /// <returns>An enumerable collection of JIDs which are on the client's /// blocklist.</returns> /// <exception cref="NotSupportedException">The XMPP entity with /// the specified JID does not support the 'Blocking Command' XMPP /// extension.</exception> /// <exception cref="XmppErrorException">The server returned an XMPP error code. /// Use the Error property of the XmppErrorException to obtain the specific /// error condition.</exception> /// <exception cref="XmppException">The server returned invalid data or another /// unspecified XMPP error occurred.</exception> public IEnumerable <Jid> GetBlocklist() { // Probe for server support. if (!ecapa.Supports(im.Jid.Domain, Extension.BlockingCommand)) { throw new NotSupportedException("The server does not support " + "the 'Blocking Command' extension."); } Iq iq = im.IqRequest(IqType.Get, null, im.Jid, Xml.Element("blocklist", "urn:xmpp:blocking")); if (iq.Type == IqType.Error) { throw Util.ExceptionFromError(iq, "The blocklist could not be retrieved."); } ISet <Jid> set = new HashSet <Jid>(); var list = iq.Data.Element("blocklist"); if (list == null || list.GetDefaultNamespace().NamespaceName != "urn:xmpp:blocking") { throw new XmppException("Erroneous server response."); } foreach (XElement item in list.Descendants("item")) { try { string jid = item.GetAttribute("jid"); set.Add(jid); } catch (FormatException e) { throw new XmppException("Encountered an invalid JID.", e); } } return(set); }
public void EnableCarbons(bool enable = true) { if (!ecapa.Supports(im.Jid.Domain, Extension.MessageCarbons)) { throw new NotSupportedException("The XMPP server does not support " + "the 'Message Carbons' extension."); } var iq = im.IqRequest(IqType.Set, null, im.Jid, Xml.Element(enable ? "enable" : "disable", _namespaces[0])); if (iq.Type == IqType.Error) { throw Util.ExceptionFromError(iq, "Message Carbons could not " + "be enabled."); } }
/// <summary> /// Retrieves the data-item with the specified CID from the XMPP entity /// with the specified JID. /// </summary> /// <param name="cid">The CID of the binary data to retrieve.</param> /// <param name="from">The JID of the XMPP entity to request the data /// from.</param> /// <param name="cache">true to store the requested item in the local /// cache for future references.</param> /// <returns>The data-item with the specified CID.</returns> /// <exception cref="ArgumentNullException">The cid parameter or the from /// parameter is null.</exception> /// <exception cref="NotSupportedException">The XMPP entity with /// the specified JID does not support the 'Bits of Binary' XMPP /// extension.</exception> /// <exception cref="XmppErrorException">The server returned an XMPP error code. /// Use the Error property of the XmppErrorException to obtain the specific /// error condition.</exception> /// <exception cref="XmppException">The server returned invalid data or another /// unspecified XMPP error occurred.</exception> public BobData Get(string cid, Jid from, bool cache = true) { cid.ThrowIfNull("cid"); from.ThrowIfNull("from"); // If the data is already in the cache, return it. if (this.cache.ContainsKey(cid)) { return(this.cache[cid]); } if (!ecapa.Supports(from, Extension.BitsOfBinary)) { throw new NotSupportedException("The XMPP entity does not support " + "the 'Bits of Binary' extension."); } // Request the data. Iq iq = im.IqRequest(IqType.Get, from, im.Jid, Xml.Element("data", "urn:xmpp:bob").SetAttribute("cid", cid)); if (iq.Type == IqType.Error) { throw Util.ExceptionFromError(iq, "The data-item with the specified " + "CID could not be retrieved."); } var data = iq.Data.Element("data"); if (data == null || data.GetDefaultNamespace().NamespaceName != "urn:xmpp:bob") { throw new XmppException("Erroneous response."); } try { // Parse the response 'data' element. BobData b = BobData.Parse(data); if (cache) { this.cache[cid] = b; } return(b); } catch (ArgumentException e) { throw new XmppException("The retrieved data-item could not be " + "processed.", e); } }
/// <summary> /// Pings the XMPP entity with the specified JID. /// </summary> /// <param name="jid">The JID of the XMPP entity to ping.</param> /// <returns>The time it took to ping the XMPP entity with the specified /// JID.</returns> /// <exception cref="ArgumentNullException">The jid parameter /// is null.</exception> /// <exception cref="NotSupportedException">The XMPP entity with /// the specified JID does not support the 'Ping' XMPP extension.</exception> /// <exception cref="XmppErrorException">The server returned an XMPP error code. /// Use the Error property of the XmppErrorException to obtain the specific /// error condition.</exception> /// <exception cref="XmppException">The server returned invalid data or another /// unspecified XMPP error occurred.</exception> public TimeSpan PingEntity(Jid jid) { jid.ThrowIfNull("jid"); if (!ecapa.Supports(jid, Extension.Ping)) { throw new NotSupportedException("The XMPP entity does not support the " + "'Ping' extension."); } DateTime start = DateTime.Now; Iq iq = im.IqRequest(IqType.Get, jid, im.Jid, Xml.Element("ping", "urn:xmpp:ping")); if (iq.Type == IqType.Error) { throw Util.ExceptionFromError(iq, "Could not ping XMPP entity."); } return(DateTime.Now.Subtract(start)); }
/// <summary> /// Retrieves the client's external IP address. /// </summary> /// <returns>The XMPP client's external IP address.</returns> /// <exception cref="NotSupportedException">The XMPP server does not /// support the 'Server IP Check' XMPP extension.</exception> /// <exception cref="XmppErrorException">The server returned an XMPP error code. /// Use the Error property of the XmppErrorException to obtain the specific /// error condition.</exception> /// <exception cref="XmppException">The server returned invalid data or another /// unspecified XMPP error occurred.</exception> public string GetExternalAddress() { if (!ecapa.Supports(im.Jid.Domain, Extension.ServerIpCheck)) { throw new NotSupportedException("The XMPP server does not support " + "the 'Server IP Check' extension."); } Iq iq = im.IqRequest(IqType.Get, null, im.Jid, Xml.Element("address", "urn:xmpp:sic:1")); if (iq.Type == IqType.Error) { throw Util.ExceptionFromError(iq, "The external IP address could not " + "be retrieved."); } var address = iq.Data.Element("address"); if (address == null || address.Element("ip") == null) { throw new XmppException("Erroneous IQ response."); } return(address.Element("ip").Value); }
/// <summary> /// Retrieves the time of the XMPP entity with the specified JID. /// </summary> /// <param name="jid">The JID of the XMPP entity to retrieve the time /// for.</param> /// <returns>The time of the XMPP entity with the specified JID.</returns> /// <exception cref="ArgumentNullException">The jid parameter /// is null.</exception> /// <exception cref="NotSupportedException">The XMPP entity with /// the specified JID does not support the 'Entity Time' XMPP extension.</exception> /// <exception cref="XmppErrorException">The server returned an XMPP error code. /// Use the Error property of the XmppErrorException to obtain the specific /// error condition.</exception> /// <exception cref="XmppException">The server returned invalid data or another /// unspecified XMPP error occurred.</exception> public DateTime GetTime(Jid jid) { jid.ThrowIfNull("jid"); if (!ecapa.Supports(jid, Extension.EntityTime)) { throw new NotSupportedException("The XMPP entity does not support " + "the 'Entity Time' extension."); } Iq iq = im.IqRequest(IqType.Get, jid, im.Jid, Xml.Element("time", "urn:xmpp:time")); if (iq.Type == IqType.Error) { throw Util.ExceptionFromError(iq, "The time could not be retrieved."); } var time = iq.Data.Element("time"); if (time == null || time.Element("tzo") == null || time.Element("utc") == null) { throw new XmppException("Erroneous IQ response."); } string tzo = time.Element("tzo").Value; string utc = time.Element("utc").Value; // Try to parse utc into datetime, tzo into timespan. try { DateTime dt = DateTime.Parse(utc).ToUniversalTime(); TimeSpan sp = TimeSpan.Parse(tzo.TrimStart('+')); return(dt.Add(sp)); } catch (FormatException e) { throw new XmppException("Invalid tzo or utc value.", e); } }