示例#1
0
        /// <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));
        }
示例#2
0
        /// <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);
                    }
                }
            });
        }
示例#4
0
 /// <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.");
            }
        }
示例#7
0
        /// <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);
            }
        }
示例#8
0
        /// <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));
        }
示例#9
0
        /// <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);
        }
示例#10
0
        /// <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);
            }
        }