diff --git a/Client/Examples.xml b/Client/Examples.xml
index 48b0203e..4498f543 100644
--- a/Client/Examples.xml
+++ b/Client/Examples.xml
@@ -1,171 +1,169 @@
-
-
-
-
-
- This example shows how to use the GetFeatures method to print out a
- list of features supported by the XMPP client of a chat contact.
-
- string hostname = "jabber.se",
- username = "myUsername",
- password = "myPassword";
- Jid juliet = "juliet@capulet.com/balcony";
-
- using (var cl = new XmppClient(hostname, username, password)) {
- cl.Connect();
-
- Console.WriteLine("Juliet's XMPP client supports: ");
- foreach (var feat in cl.GetFeatures(juliet))
- Console.WriteLine(" - " + feat);
- }
-
-
-
-
-
- This example demonstrates how to use the SendMessage method in order
- to send a chat-message to a contact.
-
- string hostname = "jabber.se",
- username = "myUsername",
- password = "myPassword";
- Jid juliet = "juliet@capulet.com/balcony";
-
- using (var cl = new XmppClient(hostname, username, password)) {
- cl.Connect();
-
- while(true) {
- Console.Write("Type a message or type 'quit' to exit: ");
- string s = Console.ReadLine();
- if(s == "quit")
- return;
- // Send the message to Juliet.
- cl.SendMessage(juliet, s);
- }
- }
-
-
-
-
-
- This example demonstrates how to use the SendMessage method in order
- to send a multi-language chat-message to a contact.
-
- string hostname = "jabber.se",
- username = "myUsername",
- password = "myPassword";
- Jid juliet = "juliet@capulet.com/balcony";
-
- using (var cl = new XmppClient(hostname, username, password)) {
- cl.Connect();
-
- cl.SendMessage(juliet, new Dictionary<string, string>() {
- { "en", "Hi, how are you?" },
- { "dk", "Hej, hvordan har du det?" },
- { "de", "Hallo, wie geht es dir?" },
- { "jp", "お元気ですか?" }
- });
- }
-
-
-
-
-
- This example demonstrates how to use the GetRoster method in order
- to retrieve a list of all of the user's contacts.
-
- string hostname = "jabber.se",
- username = "myUsername",
- password = "myPassword";
-
- using (var cl = new XmppClient(hostname, username, password)) {
- cl.Connect();
-
- Console.WriteLine("Contacts on " + cl.Jid.Node + "'s contact-list:");
- foreach (var item in cl.GetRoster())
- Console.WriteLine(" - " + item.Jid);
- }
-
-
-
-
-
- This example demonstrates how to use the SetTune method in order
- to publish tune information to other contacts.
-
- string hostname = "jabber.se",
- username = "myUsername",
- password = "myPassword";
-
- using (var cl = new XmppClient(hostname, username, password)) {
- cl.Connect();
-
- // Let your contacts know what you are currently listening to.
- cl.SetTune(new TuneInformation("Every Breath You Take", "The Police"));
-
- Console.WriteLine("Type 'quit' to exit.");
- while(Console.ReadLine() != "quit");
- }
-
-
-
-
-
- This example demonstrates how to use the SetActivity method in order
- to publish the user's current activity.
-
- string hostname = "jabber.se",
- username = "myUsername",
- password = "myPassword";
-
- using (var cl = new XmppClient(hostname, username, password)) {
- cl.Connect();
-
- // Let your contacts know what you are currently doing.
- cl.SetActivity(GeneralActivity.Eating, SpecificActivity.HavingBreakfast);
-
- Console.WriteLine("Type 'quit' to exit.");
- while(Console.ReadLine() != "quit");
- }
-
-
-
-
-
- This example demonstrates how to set up the SubscriptionRequest delegate in
- order to process incoming subscription requests.
-
- static void Main(string[] args) {
- string hostname = "jabber.se",
- username = "myUsername",
- password = "myPassword";
-
- using (var cl = new XmppClient(hostname, username, password)) {
- cl.SubscriptionRequest = OnSubscriptionRequest;
- cl.Connect();
-
- // Put the thread to sleep and wait for subscription requests.
- Thread.Sleep(Timeout.Infinite);
- }
- }
-
- /// <summary>
- /// A callback method that is invoked whenever a subscription request from
- /// another XMPP user is received.
- /// </summary>
- /// <param name="from">The JID of the XMPP user who wishes to subscribe to our
- /// presence.</param>
- /// <returns>true to approve the request; Otherwise false.</returns>
- static bool OnSubscriptionRequest(Jid from) {
- Console.WriteLine(from + " wants to subscribe to your presence.");
- Console.Write("Type Y to approve the request, or any other key to refuse it: ");
-
- // Return true to approve the request, or false to refuse it.
- return Console.ReadLine().ToLowerInvariant() == "y";
- }
-
-
-
-
-
-
\ No newline at end of file
+
+
+
+
+ This example shows how to use the GetFeatures method to print out a
+ list of features supported by the XMPP client of a chat contact.
+
+ string hostname = "jabber.se",
+ username = "myUsername",
+ password = "myPassword";
+ Jid juliet = "juliet@capulet.com/balcony";
+
+ using (var cl = new XmppClient(hostname, username, password)) {
+ cl.Connect();
+
+ Console.WriteLine("Juliet's XMPP client supports: ");
+ foreach (var feat in cl.GetFeatures(juliet))
+ Console.WriteLine(" - " + feat);
+ }
+
+
+
+
+
+ This example demonstrates how to use the SendMessage method in order
+ to send a chat-message to a contact.
+
+ string hostname = "jabber.se",
+ username = "myUsername",
+ password = "myPassword";
+ Jid juliet = "juliet@capulet.com/balcony";
+
+ using (var cl = new XmppClient(hostname, username, password)) {
+ cl.Connect();
+
+ while(true) {
+ Console.Write("Type a message or type 'quit' to exit: ");
+ string s = Console.ReadLine();
+ if(s == "quit")
+ return;
+ // Send the message to Juliet.
+ cl.SendMessage(juliet, s);
+ }
+ }
+
+
+
+
+
+ This example demonstrates how to use the SendMessage method in order
+ to send a multi-language chat-message to a contact.
+
+ string hostname = "jabber.se",
+ username = "myUsername",
+ password = "myPassword";
+ Jid juliet = "juliet@capulet.com/balcony";
+
+ using (var cl = new XmppClient(hostname, username, password)) {
+ cl.Connect();
+
+ cl.SendMessage(juliet, new Dictionary<string, string>() {
+ { "en", "Hi, how are you?" },
+ { "dk", "Hej, hvordan har du det?" },
+ { "de", "Hallo, wie geht es dir?" },
+ { "jp", "お元気ですか?" }
+ });
+ }
+
+
+
+
+
+ This example demonstrates how to use the GetRoster method in order
+ to retrieve a list of all of the user's contacts.
+
+ string hostname = "jabber.se",
+ username = "myUsername",
+ password = "myPassword";
+
+ using (var cl = new XmppClient(hostname, username, password)) {
+ cl.Connect();
+
+ Console.WriteLine("Contacts on " + cl.Jid.Node + "'s contact-list:");
+ foreach (var item in cl.GetRoster())
+ Console.WriteLine(" - " + item.Jid);
+ }
+
+
+
+
+
+ This example demonstrates how to use the SetTune method in order
+ to publish tune information to other contacts.
+
+ string hostname = "jabber.se",
+ username = "myUsername",
+ password = "myPassword";
+
+ using (var cl = new XmppClient(hostname, username, password)) {
+ cl.Connect();
+
+ // Let your contacts know what you are currently listening to.
+ cl.SetTune(new TuneInformation("Every Breath You Take", "The Police"));
+
+ Console.WriteLine("Type 'quit' to exit.");
+ while(Console.ReadLine() != "quit");
+ }
+
+
+
+
+
+ This example demonstrates how to use the SetActivity method in order
+ to publish the user's current activity.
+
+ string hostname = "jabber.se",
+ username = "myUsername",
+ password = "myPassword";
+
+ using (var cl = new XmppClient(hostname, username, password)) {
+ cl.Connect();
+
+ // Let your contacts know what you are currently doing.
+ cl.SetActivity(GeneralActivity.Eating, SpecificActivity.HavingBreakfast);
+
+ Console.WriteLine("Type 'quit' to exit.");
+ while(Console.ReadLine() != "quit");
+ }
+
+
+
+
+
+ This example demonstrates how to set up the SubscriptionRequest delegate in
+ order to process incoming subscription requests.
+
+ static void Main(string[] args) {
+ string hostname = "jabber.se",
+ username = "myUsername",
+ password = "myPassword";
+
+ using (var cl = new XmppClient(hostname, username, password)) {
+ cl.SubscriptionRequest = OnSubscriptionRequest;
+ cl.Connect();
+
+ // Put the thread to sleep and wait for subscription requests.
+ Thread.Sleep(Timeout.Infinite);
+ }
+ }
+
+ /// <summary>
+ /// A callback method that is invoked whenever a subscription request from
+ /// another XMPP user is received.
+ /// </summary>
+ /// <param name="from">The JID of the XMPP user who wishes to subscribe to our
+ /// presence.</param>
+ /// <returns>true to approve the request; Otherwise false.</returns>
+ static bool OnSubscriptionRequest(Jid from) {
+ Console.WriteLine(from + " wants to subscribe to your presence.");
+ Console.Write("Type Y to approve the request, or any other key to refuse it: ");
+
+ // Return true to approve the request, or false to refuse it.
+ return Console.ReadLine().ToLowerInvariant() == "y";
+ }
+
+
+
+
+
\ No newline at end of file
diff --git a/Client/FileTransferSettings.cs b/Client/FileTransferSettings.cs
index 71a0c76c..79578b6a 100644
--- a/Client/FileTransferSettings.cs
+++ b/Client/FileTransferSettings.cs
@@ -1,9 +1,9 @@
-using Sharp.Xmpp.Extensions;
+using XMPPEngineer.Extensions;
using System;
using System.Collections.Generic;
using System.Net;
-namespace Sharp.Xmpp.Client
+namespace XMPPEngineer.Client
{
///
/// Contains settings for configuring various file-transfer options.
diff --git a/Client/XmppClient.cs b/Client/XmppClient.cs
index b2f5ec23..56a8630e 100644
--- a/Client/XmppClient.cs
+++ b/Client/XmppClient.cs
@@ -1,12 +1,12 @@
-using Sharp.Xmpp.Extensions;
-using Sharp.Xmpp.Im;
+using XMPPEngineer.Extensions;
+using XMPPEngineer.Im;
using System;
using System.Collections.Generic;
using System.Globalization;
using System.IO;
using System.Net.Security;
-namespace Sharp.Xmpp.Client
+namespace XMPPEngineer.Client
{
///
/// Implements an XMPP client providing basic instant messaging (IM) and
@@ -162,6 +162,53 @@ public class XmppClient : IDisposable
///
private MessageCarbons messageCarbons;
+ ///
+ /// What extensions to load? Defaults to all.
+ ///
+ private AvailableExtensions loadExtensions = AvailableExtensions.All;
+
+ ///
+ /// The extensions available on the client. Use with the loadExtensions property.
+ ///
+ [Flags]
+ public enum AvailableExtensions : Int64
+ {
+ // 64 maximum values
+ None = 0,
+ SoftwareVersion = 1,
+ ServiceDiscovery = 2,
+ EntityCapabilities = 4,
+ Ping = 8,
+ Attention = 16,
+ EntityTime = 32,
+ BlockingCommand = 64,
+ Pep = 128,
+ UserTune = 256,
+ UserAvatar = 512,
+ UserMood = 1024,
+ DataForms = 2048,
+ FeatureNegotiation = 4096,
+ StreamInitiation = 8192,
+ SIFileTransfer = 16384,
+ InBandBytestreams = 32768,
+ UserActivity = 65536,
+ Socks5Bytestreams = 131072,
+ FileTransfer = 262144,
+ ServerIpCheck = 524288,
+ MessageCarbons = 1048576,
+ InBandRegistration = 2097152,
+ ChatStateNotifications = 4194304,
+ BitsOfBinary = 8388608,
+ VCardAvatars = 16777216,
+ CustomIqExtension = 33554432,
+ MultiUserChat = 67108864,
+ Default = SoftwareVersion | ServiceDiscovery | EntityCapabilities,
+ All = SoftwareVersion | ServiceDiscovery | EntityCapabilities | Ping | Attention | EntityTime | BlockingCommand | Pep | UserTune | UserAvatar |
+ UserMood | DataForms | FeatureNegotiation | StreamInitiation | SIFileTransfer | InBandBytestreams | UserActivity | Socks5Bytestreams
+ | FileTransfer | ServerIpCheck | MessageCarbons | InBandRegistration | ChatStateNotifications | BitsOfBinary | VCardAvatars | CustomIqExtension
+ | MultiUserChat
+ //134217728, 268435456, 536870912, 1073741824 ... up to 32.
+ }
///
/// The hostname of the XMPP server to connect to.
///
@@ -260,6 +307,15 @@ public RemoteCertificateValidationCallback Validate
}
}
+ ///
+ /// If false the connection will not try to retrieve the rooster automatically
+ ///
+ public bool RetrieveRoster
+ {
+ get { return im.RetrieveRoster; }
+ set { im.RetrieveRoster = value; }
+ }
+
///
/// Determines whether the session with the server is TLS/SSL encrypted.
///
@@ -458,6 +514,36 @@ public event EventHandler Tune
}
}
+ ///
+ /// The event that is raised when stream management is enabled.
+ ///
+ public event EventHandler StreamManagementEnabled
+ {
+ add
+ {
+ im.StreamManagementEnabled += value;
+ }
+ remove
+ {
+ im.StreamManagementEnabled -= value;
+ }
+ }
+
+ ///
+ /// The event that is raised when a stream is resumed.
+ ///
+ public event EventHandler StreamResumed
+ {
+ add
+ {
+ im.StreamResumed += value;
+ }
+ remove
+ {
+ im.StreamResumed -= value;
+ }
+ }
+
///
/// The event that is raised when a chat message is received.
///
@@ -697,12 +783,41 @@ public event EventHandler Error
/// Use this constructor if you wish to connect to an XMPP server using
/// an existing set of user credentials.
public XmppClient(string hostname, string username, string password,
- int port = 5222, bool tls = true, RemoteCertificateValidationCallback validate = null)
- {
- im = new XmppIm(hostname, username, password, port, tls, validate);
- // Initialize the various extension modules.
- LoadExtensions();
- }
+ AvailableExtensions extensions = AvailableExtensions.All,
+ int port = 5222, bool tls = true, RemoteCertificateValidationCallback validate = null) :
+ this(hostname, username, password, null, extensions, port, tls, validate) { }
+
+ ///
+ /// Initializes a new instance of the XmppClient class.
+ ///
+ /// The hostname of the XMPP server to connect to.
+ /// The username with which to authenticate. In XMPP jargon
+ /// this is known as the 'node' part of the JID.
+ /// The password with which to authenticate.
+ /// The IP address or domain of the XMPP server, if different from the hostname. eg. xmpp.server.com
+ /// The port number of the XMPP service of the server.
+ /// If true the session will be TLS/SSL-encrypted if the server
+ /// supports TLS/SSL-encryption.
+ /// A delegate used for verifying the remote Secure Sockets
+ /// Layer (SSL) certificate which is used for authentication. Can be null if not
+ /// needed.
+ /// The hostname parameter or the
+ /// username parameter or the password parameter is null.
+ /// The hostname parameter or the username
+ /// parameter is the empty string.
+ /// The value of the port parameter
+ /// is not a valid port number.
+ /// Use this constructor if you wish to connect to an XMPP server using
+ /// an existing set of user credentials.
+ public XmppClient(string hostname, string username, string password, string server,
+ AvailableExtensions extensions = AvailableExtensions.All,
+ int port = 5222, bool tls = true, RemoteCertificateValidationCallback validate = null)
+ {
+ im = new XmppIm(hostname, username, password, server, port, tls, validate);
+ loadExtensions = extensions;
+ // Initialize the various extension modules.
+ LoadExtensions();
+ }
///
/// Initializes a new instance of the XmppClient class.
@@ -722,12 +837,37 @@ public XmppClient(string hostname, string username, string password,
/// is not a valid port number.
/// Use this constructor if you wish to register an XMPP account using
/// the in-band account registration process supported by some servers.
- public XmppClient(string hostname, int port = 5222, bool tls = true,
- RemoteCertificateValidationCallback validate = null)
- {
- im = new XmppIm(hostname, port, tls, validate);
- LoadExtensions();
- }
+ public XmppClient(string hostname, AvailableExtensions extensions = AvailableExtensions.All, int port = 5222, bool tls = true,
+ RemoteCertificateValidationCallback validate = null) :
+ this(hostname, null, extensions, port, tls, validate) { }
+
+ ///
+ /// Initializes a new instance of the XmppClient class.
+ ///
+ /// The hostname of the XMPP server to connect to.
+ /// The IP address or domain of the XMPP server, if different from the hostname eg. xmpp.server.com
+ /// The port number of the XMPP service of the server.
+ /// If true the session will be TLS/SSL-encrypted if the server
+ /// supports TLS/SSL-encryption.
+ /// A delegate used for verifying the remote Secure Sockets
+ /// Layer (SSL) certificate which is used for authentication. Can be null if not
+ /// needed.
+ /// The hostname parameter is
+ /// null.
+ /// The hostname parameter is the empty
+ /// string.
+ /// The value of the port parameter
+ /// is not a valid port number.
+ /// Use this constructor if you wish to register an XMPP account using
+ /// the in-band account registration process supported by some servers.
+ public XmppClient(string hostname, string server, AvailableExtensions extensions = AvailableExtensions.All,
+ int port = 5222, bool tls = true,
+ RemoteCertificateValidationCallback validate = null)
+ {
+ im = new XmppIm(hostname, server, port, tls, validate);
+ loadExtensions = extensions;
+ LoadExtensions();
+ }
///
/// Establishes a connection to the XMPP server.
@@ -774,40 +914,55 @@ public void Connect(string resource = null)
/// of an XMPP extension failed.
public void Authenticate(string username, string password)
{
- im.Autenticate(username, password);
+ im.Authenticate(username, password);
}
- ///
- /// Sends a chat message with the specified content to the specified JID.
- ///
- /// The JID of the intended recipient.
- /// The content of the message.
- /// The subject of the message.
- /// The conversation thread the message belongs to.
- /// The type of the message. Can be one of the values from
- /// the MessagType enumeration.
- /// The language of the XML character data of
- /// the stanza.
- /// The to parameter or the body parameter
- /// is null.
- /// The body parameter is the empty
- /// string.
- /// There was a failure while writing to or reading
- /// from the network.
- /// The XmppClient instance is not
- /// connected to a remote host, or the XmppClient instance has not authenticated with
- /// the XMPP server.
- /// The XmppClient object has been
- /// disposed.
- ///
- public void SendMessage(Jid to, string body, string subject = null,
- string thread = null, MessageType type = MessageType.Normal,
+ ///
+ /// Enables stream management. You should listen for the StreamManagementEnabled event
+ /// to know when it is ready.
+ /// Whether we should enabled resumption on the stream.
+ /// The max timeout client request - the server can override this.
+ ///
+ public void EnableStreamManagement(bool withresumption = true, int maxTimeout = 60)
+ {
+ AssertValid();
+
+ // enable sm
+ im.EnableStreamManagement(withresumption, maxTimeout);
+ }
+
+ ///
+ /// Sends a chat message with the specified content to the specified JID.
+ ///
+ /// The JID of the intended recipient.
+ /// The content of the message.
+ /// The subject of the message.
+ /// Any additional address to send to XEP-0033.
+ /// The conversation thread the message belongs to.
+ /// The type of the message. Can be one of the values from
+ /// the MessagType enumeration.
+ /// The language of the XML character data of
+ /// the stanza.
+ /// The to parameter or the body parameter
+ /// is null.
+ /// The body parameter is the empty
+ /// string.
+ /// There was a failure while writing to or reading
+ /// from the network.
+ /// The XmppClient instance is not
+ /// connected to a remote host, or the XmppClient instance has not authenticated with
+ /// the XMPP server.
+ /// The XmppClient object has been
+ /// disposed.
+ ///
+ public void SendMessage(Jid to, string body, string subject = null,
+ List additionalAddresses = null, string thread = null, MessageType type = MessageType.Normal,
CultureInfo language = null)
{
AssertValid();
to.ThrowIfNull("to");
body.ThrowIfNullOrEmpty("body");
- im.SendMessage(to, body, subject, thread, type, language);
+ im.SendMessage(to, body, subject, additionalAddresses, thread, type, language);
}
///
@@ -847,7 +1002,7 @@ public void SendMessage(Jid to, IDictionary bodies,
AssertValid();
to.ThrowIfNull("to");
bodies.ThrowIfNull("bodies");
- im.SendMessage(to, bodies, subjects, thread, type, language);
+ im.SendMessage(to, bodies, subjects, thread, null, type, language);
}
///
@@ -1997,41 +2152,44 @@ private void AssertValid()
throw new InvalidOperationException("Not authenticated with XMPP server.");
}
+
///
/// Initializes the various XMPP extension modules.
///
private void LoadExtensions()
{
- version = im.LoadExtension();
- sdisco = im.LoadExtension();
- ecapa = im.LoadExtension();
- ping = im.LoadExtension();
- attention = im.LoadExtension();
- time = im.LoadExtension();
- block = im.LoadExtension();
- pep = im.LoadExtension();
- userTune = im.LoadExtension();
+ if ((loadExtensions & AvailableExtensions.SoftwareVersion) == AvailableExtensions.SoftwareVersion) version = im.LoadExtension();
+ if ((loadExtensions & AvailableExtensions.ServiceDiscovery) == AvailableExtensions.ServiceDiscovery) sdisco = im.LoadExtension();
+ if ((loadExtensions & AvailableExtensions.EntityCapabilities) == AvailableExtensions.EntityCapabilities) ecapa = im.LoadExtension();
+ if ((loadExtensions & AvailableExtensions.Ping) == AvailableExtensions.Ping) ping = im.LoadExtension();
+ if ((loadExtensions & AvailableExtensions.Attention) == AvailableExtensions.Attention) attention = im.LoadExtension();
+ if ((loadExtensions & AvailableExtensions.EntityTime) == AvailableExtensions.EntityTime) time = im.LoadExtension();
+ if ((loadExtensions & AvailableExtensions.BlockingCommand) == AvailableExtensions.BlockingCommand) block = im.LoadExtension();
+ if ((loadExtensions & AvailableExtensions.Pep) == AvailableExtensions.Pep) pep = im.LoadExtension();
+ if ((loadExtensions & AvailableExtensions.UserTune) == AvailableExtensions.UserTune) userTune = im.LoadExtension();
#if WINDOWSPLATFORM
- userAvatar = im.LoadExtension();
+ if ((loadExtensions & AvailableExtensions.UserAvatar) == AvailableExtensions.UserAvatar) userAvatar = im.LoadExtension();
#endif
- userMood = im.LoadExtension();
- dataForms = im.LoadExtension();
- featureNegotiation = im.LoadExtension();
- streamInitiation = im.LoadExtension();
- siFileTransfer = im.LoadExtension();
- inBandBytestreams = im.LoadExtension();
- userActivity = im.LoadExtension();
- socks5Bytestreams = im.LoadExtension();
- FileTransferSettings = new FileTransferSettings(socks5Bytestreams,
- siFileTransfer);
- serverIpCheck = im.LoadExtension();
- messageCarbons = im.LoadExtension();
- inBandRegistration = im.LoadExtension();
- chatStateNotifications = im.LoadExtension();
- bitsOfBinary = im.LoadExtension();
- vcardAvatars = im.LoadExtension();
- cusiqextension = im.LoadExtension();
- groupChat = im.LoadExtension();
+ if ((loadExtensions & AvailableExtensions.UserMood) == AvailableExtensions.UserMood) userMood = im.LoadExtension();
+ if ((loadExtensions & AvailableExtensions.DataForms) == AvailableExtensions.DataForms) dataForms = im.LoadExtension();
+ if ((loadExtensions & AvailableExtensions.FeatureNegotiation) == AvailableExtensions.FeatureNegotiation) featureNegotiation = im.LoadExtension();
+ if ((loadExtensions & AvailableExtensions.StreamInitiation) == AvailableExtensions.StreamInitiation) streamInitiation = im.LoadExtension();
+ if ((loadExtensions & AvailableExtensions.SIFileTransfer) == AvailableExtensions.SIFileTransfer) siFileTransfer = im.LoadExtension();
+ if ((loadExtensions & AvailableExtensions.InBandBytestreams) == AvailableExtensions.InBandBytestreams) inBandBytestreams = im.LoadExtension();
+ if ((loadExtensions & AvailableExtensions.UserActivity) == AvailableExtensions.UserActivity) userActivity = im.LoadExtension();
+ if ((loadExtensions & AvailableExtensions.Socks5Bytestreams) == AvailableExtensions.Socks5Bytestreams) socks5Bytestreams = im.LoadExtension();
+ if ((loadExtensions & AvailableExtensions.FileTransfer) == AvailableExtensions.FileTransfer)
+ FileTransferSettings = new FileTransferSettings(socks5Bytestreams,
+ siFileTransfer);
+
+ if ((loadExtensions & AvailableExtensions.ServerIpCheck) == AvailableExtensions.ServerIpCheck) serverIpCheck = im.LoadExtension();
+ if ((loadExtensions & AvailableExtensions.MessageCarbons) == AvailableExtensions.MessageCarbons) messageCarbons = im.LoadExtension();
+ if ((loadExtensions & AvailableExtensions.InBandRegistration) == AvailableExtensions.InBandRegistration) inBandRegistration = im.LoadExtension();
+ if ((loadExtensions & AvailableExtensions.ChatStateNotifications) == AvailableExtensions.ChatStateNotifications) chatStateNotifications = im.LoadExtension();
+ if ((loadExtensions & AvailableExtensions.BitsOfBinary) == AvailableExtensions.BitsOfBinary) bitsOfBinary = im.LoadExtension();
+ if ((loadExtensions & AvailableExtensions.VCardAvatars) == AvailableExtensions.VCardAvatars) vcardAvatars = im.LoadExtension();
+ if ((loadExtensions & AvailableExtensions.CustomIqExtension) == AvailableExtensions.CustomIqExtension) cusiqextension = im.LoadExtension();
+ if ((loadExtensions & AvailableExtensions.MultiUserChat) == AvailableExtensions.MultiUserChat) groupChat = im.LoadExtension();
}
}
}
\ No newline at end of file
diff --git a/Core/ErrorEventArgs.cs b/Core/ErrorEventArgs.cs
index 9b750f1f..65c1bf1a 100644
--- a/Core/ErrorEventArgs.cs
+++ b/Core/ErrorEventArgs.cs
@@ -1,6 +1,6 @@
using System;
-namespace Sharp.Xmpp.Core
+namespace XMPPEngineer.Core
{
///
/// Provides data for the Error event.
diff --git a/Core/Iq.cs b/Core/Iq.cs
index ca7e8ff6..31095949 100644
--- a/Core/Iq.cs
+++ b/Core/Iq.cs
@@ -3,7 +3,7 @@
using System.Globalization;
using System.Xml;
-namespace Sharp.Xmpp.Core
+namespace XMPPEngineer.Core
{
///
/// Represents an IQ XML stanza.
diff --git a/Core/IqEventArgs.cs b/Core/IqEventArgs.cs
index 7805c318..f740909e 100644
--- a/Core/IqEventArgs.cs
+++ b/Core/IqEventArgs.cs
@@ -1,6 +1,6 @@
using System;
-namespace Sharp.Xmpp.Core
+namespace XMPPEngineer.Core
{
///
/// Provides data for the Iq event.
diff --git a/Core/IqType.cs b/Core/IqType.cs
index 5def7dc0..f1e8c149 100644
--- a/Core/IqType.cs
+++ b/Core/IqType.cs
@@ -1,4 +1,4 @@
-namespace Sharp.Xmpp.Core
+namespace XMPPEngineer.Core
{
///
/// Defines the possible types for IQ stanzas.
diff --git a/Core/Message.cs b/Core/Message.cs
index 526e2620..edc904f6 100644
--- a/Core/Message.cs
+++ b/Core/Message.cs
@@ -2,7 +2,7 @@
using System.Globalization;
using System.Xml;
-namespace Sharp.Xmpp.Core
+namespace XMPPEngineer.Core
{
///
/// Represents a Message XML stanza.
diff --git a/Core/MessageEventArgs.cs b/Core/MessageEventArgs.cs
index 704dc9d7..a7c1228d 100644
--- a/Core/MessageEventArgs.cs
+++ b/Core/MessageEventArgs.cs
@@ -1,6 +1,6 @@
using System;
-namespace Sharp.Xmpp.Core
+namespace XMPPEngineer.Core
{
///
/// Provides data for the Message event.
diff --git a/Core/Presence.cs b/Core/Presence.cs
index d65e0217..8ecf83b8 100644
--- a/Core/Presence.cs
+++ b/Core/Presence.cs
@@ -2,7 +2,7 @@
using System.Globalization;
using System.Xml;
-namespace Sharp.Xmpp.Core
+namespace XMPPEngineer.Core
{
///
/// Represents a Presence XML stanza.
diff --git a/Core/PresenceEventArgs.cs b/Core/PresenceEventArgs.cs
index 44e146a9..84254a5c 100644
--- a/Core/PresenceEventArgs.cs
+++ b/Core/PresenceEventArgs.cs
@@ -1,6 +1,6 @@
using System;
-namespace Sharp.Xmpp.Core
+namespace XMPPEngineer.Core
{
///
/// Provides data for the Presence event.
diff --git a/Core/Sasl/Mechanisms/SaslDigestMd5.cs b/Core/Sasl/Mechanisms/SaslDigestMd5.cs
index 4d92e881..45542198 100644
--- a/Core/Sasl/Mechanisms/SaslDigestMd5.cs
+++ b/Core/Sasl/Mechanisms/SaslDigestMd5.cs
@@ -3,7 +3,7 @@
using System.Security.Cryptography;
using System.Text;
-namespace Sharp.Xmpp.Core.Sasl.Mechanisms
+namespace XMPPEngineer.Core.Sasl.Mechanisms
{
///
/// Implements the Sasl Digest-Md5 authentication method as described in
@@ -299,7 +299,7 @@ private static string Dquote(string s)
/// Add an additional backslash, if any backslashes are found in the username
/// For XEP106 jid nodes, Openfire seems that it needs to escape the backslash
/// within the user name. See discussion at https://community.igniterealtime.org/message/254096#254096
- /// It is not clear if this is an Openfire bug or a Sharp.Xmpp issue, so please treat this
+ /// It is not clear if this is an Openfire bug or a XMPPEngineer issue, so please treat this
/// as experimental
///
/// String to escape in order to resolve https://community.igniterealtime.org/message/254096#254096 issue
diff --git a/Core/Sasl/Mechanisms/SaslPlain.cs b/Core/Sasl/Mechanisms/SaslPlain.cs
index c078c500..56cba3b1 100644
--- a/Core/Sasl/Mechanisms/SaslPlain.cs
+++ b/Core/Sasl/Mechanisms/SaslPlain.cs
@@ -1,7 +1,7 @@
using System;
using System.Text;
-namespace Sharp.Xmpp.Core.Sasl.Mechanisms
+namespace XMPPEngineer.Core.Sasl.Mechanisms
{
///
/// Implements the Sasl Plain authentication method as described in
diff --git a/Core/Sasl/Mechanisms/SaslScramSha1.cs b/Core/Sasl/Mechanisms/SaslScramSha1.cs
index 5b8f2249..37320a70 100644
--- a/Core/Sasl/Mechanisms/SaslScramSha1.cs
+++ b/Core/Sasl/Mechanisms/SaslScramSha1.cs
@@ -4,7 +4,7 @@
using System.Security.Cryptography;
using System.Text;
-namespace Sharp.Xmpp.Core.Sasl.Mechanisms
+namespace XMPPEngineer.Core.Sasl.Mechanisms
{
///
/// Implements the Sasl SCRAM-SHA-1 authentication method as described in
diff --git a/Core/Sasl/SaslException.cs b/Core/Sasl/SaslException.cs
index c22e62d4..cf2933a6 100644
--- a/Core/Sasl/SaslException.cs
+++ b/Core/Sasl/SaslException.cs
@@ -1,7 +1,7 @@
using System;
using System.Runtime.Serialization;
-namespace Sharp.Xmpp.Core.Sasl
+namespace XMPPEngineer.Core.Sasl
{
///
/// The exception is thrown when a Sasl-related error or unexpected condition occurs.
diff --git a/Core/Sasl/SaslFactory.cs b/Core/Sasl/SaslFactory.cs
index 84e3dda2..a8d875a7 100644
--- a/Core/Sasl/SaslFactory.cs
+++ b/Core/Sasl/SaslFactory.cs
@@ -1,7 +1,7 @@
using System;
using System.Collections.Generic;
-namespace Sharp.Xmpp.Core.Sasl
+namespace XMPPEngineer.Core.Sasl
{
///
/// A factory class for producing instances of Sasl mechanisms.
diff --git a/Core/Sasl/SaslMechanism.cs b/Core/Sasl/SaslMechanism.cs
index 3ce0b634..fde0a9cb 100644
--- a/Core/Sasl/SaslMechanism.cs
+++ b/Core/Sasl/SaslMechanism.cs
@@ -1,7 +1,7 @@
using System;
using System.Collections.Generic;
-namespace Sharp.Xmpp.Core.Sasl
+namespace XMPPEngineer.Core.Sasl
{
///
/// The abstract base class from which all classes implementing a Sasl
diff --git a/Core/Stanza.cs b/Core/Stanza.cs
index 99f7bd0f..80b56000 100644
--- a/Core/Stanza.cs
+++ b/Core/Stanza.cs
@@ -2,7 +2,7 @@
using System.Globalization;
using System.Xml;
-namespace Sharp.Xmpp.Core
+namespace XMPPEngineer.Core
{
///
/// Represents the base class for XML stanzas as are used by XMPP from which
diff --git a/Core/StreamParser.cs b/Core/StreamParser.cs
index 41b29681..18932a2e 100644
--- a/Core/StreamParser.cs
+++ b/Core/StreamParser.cs
@@ -4,7 +4,7 @@
using System.Linq;
using System.Xml;
-namespace Sharp.Xmpp.Core
+namespace XMPPEngineer.Core
{
///
/// Implements a parser for parsing XMPP XML-streams as defined per XMPP:Core
diff --git a/Core/XmppCore.cs b/Core/XmppCore.cs
index 6ebd67ad..d18e1392 100644
--- a/Core/XmppCore.cs
+++ b/Core/XmppCore.cs
@@ -1,5 +1,4 @@
-using ARSoft.Tools.Net.Dns;
-using Sharp.Xmpp.Core.Sasl;
+using XMPPEngineer.Core.Sasl;
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
@@ -14,7 +13,7 @@
using System.Threading.Tasks;
using System.Xml;
-namespace Sharp.Xmpp.Core
+namespace XMPPEngineer.Core
{
///
/// Implements the core features of the XMPP protocol.
@@ -22,21 +21,6 @@ namespace Sharp.Xmpp.Core
/// For implementation details, refer to RFC 3920.
public class XmppCore : IDisposable
{
- ///
- /// The DNS SRV name records
- ///
- private List dnsRecordList;
-
- ///
- /// The current SRV DNS record to use
- ///
- private SrvRecord dnsCurrent;
-
- ///
- /// Bool variable indicating whether DNS records are initialised
- ///
- private bool dnsIsInit = false;
-
///
/// The TCP connection to the XMPP server.
///
@@ -72,6 +56,11 @@ public class XmppCore : IDisposable
///
private string hostname;
+ ///
+ /// The server IP or domain name of the XMPP server to connect to.
+ ///
+ private string server;
+
///
/// The username with which to authenticate.
///
@@ -157,6 +146,22 @@ public string Hostname
}
}
+ ///
+ /// The server IP address or domain name of the XMPP server, if different from the Hostname.
+ ///
+ public string Server
+ {
+ get
+ {
+ return server;
+ }
+
+ set
+ {
+ server = value;
+ }
+ }
+
///
/// The port number of the XMPP service of the server.
///
@@ -339,24 +344,48 @@ public bool Authenticated
/// The value of the port parameter
/// is not a valid port number.
public XmppCore(string hostname, string username, string password,
- int port = 5222, bool tls = true, RemoteCertificateValidationCallback validate = null)
- {
- moveNextSrvDNS(hostname);
- if (dnsCurrent != null)
- {
- Hostname = dnsCurrent.Target.ToString();
- Port = dnsCurrent.Port;
- }
- else
- {
- Hostname = hostname;
- Port = port;
- }
- Username = username;
- Password = password;
- Tls = tls;
- Validate = validate;
- }
+ int port = 5222, bool tls = true, RemoteCertificateValidationCallback validate = null):
+ this(hostname, username, password, null, port, tls, validate) { }
+
+ ///
+ /// Initializes a new instance of the XmppCore class.
+ ///
+ /// The hostname of the XMPP server to connect to.
+ /// The username with which to authenticate. In XMPP jargon
+ /// this is known as the 'node' part of the JID.
+ /// The password with which to authenticate.
+ /// The IP address or domain of the XMPP server, if different from the hostname eg. xmpp.server.com
+ /// The port number of the XMPP service of the server.
+ /// If true the session will be TLS/SSL-encrypted if the server
+ /// supports TLS/SSL-encryption.
+ /// A delegate used for verifying the remote Secure Sockets
+ /// Layer (SSL) certificate which is used for authentication. Can be null if not
+ /// needed.
+ /// The hostname parameter or the
+ /// username parameter or the password parameter is null.
+ /// The hostname parameter or the username
+ /// parameter is the empty string.
+ /// The value of the port parameter
+ /// is not a valid port number.
+ public XmppCore(string hostname, string username, string password, string server,
+ int port = 5222, bool tls = true, RemoteCertificateValidationCallback validate = null)
+ {
+ if (String.IsNullOrWhiteSpace(server)) {
+ Hostname = hostname;
+ Server = hostname;
+ Port = port;
+ }
+ else {
+ Server = server;
+ Hostname = hostname;
+ Port = port;
+ }
+
+ Username = username;
+ Password = password;
+ Tls = tls;
+ Validate = validate;
+ }
///
/// Initializes a new instance of the XmppCore class.
@@ -375,77 +404,45 @@ public XmppCore(string hostname, string username, string password,
/// The value of the port parameter
/// is not a valid port number.
public XmppCore(string hostname, int port = 5222, bool tls = true,
- RemoteCertificateValidationCallback validate = null)
- {
- moveNextSrvDNS(hostname);
- if (dnsCurrent != null)
- {
- Hostname = dnsCurrent.Target.ToString();
- Port = dnsCurrent.Port;
- }
- else
- {
- Hostname = hostname;
- Port = port;
- }
- Tls = tls;
- Validate = validate;
- }
-
- ///
- /// Initialises and resolves the DNS Domain, and set to dnsCurrent the next
- /// SRV record to use
- ///
- /// XMPP Domain
- /// XMPP server hostname for the Domain
- private SrvRecord moveNextSrvDNS(string domain)
- {
- domain.ThrowIfNullOrEmpty("domain");
- //If already a lookup has being made return
- if (dnsIsInit)
- {
- //If it is already init we remove the current
- if (dnsRecordList != null && dnsCurrent != null) dnsRecordList.Remove(dnsCurrent);
- dnsCurrent = dnsRecordList.FirstOrDefault();
- return dnsCurrent;
- };
- dnsIsInit = true;
-
- var domainName = ARSoft.Tools.Net.DomainName.Parse(("_xmpp-client._tcp." + domain));
- DnsMessage dnsMessage = DnsClient.Default.Resolve(domainName, RecordType.Srv);
- if ((dnsMessage == null) || ((dnsMessage.ReturnCode != ReturnCode.NoError) && (dnsMessage.ReturnCode != ReturnCode.NxDomain)))
- {
- //If DNS SRV records lookup fails then continue with the host name
-#if DEBUG
- System.Diagnostics.Debug.WriteLine("DNS Lookup Failed");
-#endif
- return null;
- }
- else
- {
- var tempList = new List();
-
- foreach (DnsRecordBase dnsRecord in dnsMessage.AnswerRecords)
- {
- SrvRecord srvRecord = dnsRecord as SrvRecord;
- if (srvRecord != null)
- {
- tempList.Add(srvRecord);
- Console.WriteLine(srvRecord.ToString());
- Console.WriteLine(" |--- Name " + srvRecord.Name);
- Console.WriteLine(" |--- Port: " + srvRecord.Port);
- Console.WriteLine(" |--- Priority" + srvRecord.Priority);
- Console.WriteLine(" |--- Type " + srvRecord.RecordType);
- Console.WriteLine(" |--- Target: " + srvRecord.Target);
- Console.WriteLine();
- }
- }
- dnsRecordList = tempList.OrderBy(o => o.Priority).ThenBy(order => order.Weight).ToList();
-
- dnsCurrent = dnsRecordList.FirstOrDefault();
- return dnsCurrent;
- }
- }
+ RemoteCertificateValidationCallback validate = null):
+ this(hostname, null, port, tls, validate) { }
+
+ ///
+ /// Initializes a new instance of the XmppCore class.
+ ///
+ /// The hostname of the XMPP server to connect to.
+ /// The IP address or domain of the XMPP server, if different from the hostname eg. xmpp.server.com
+ /// The port number of the XMPP service of the server.
+ /// If true the session will be TLS/SSL-encrypted if the server
+ /// supports TLS/SSL-encryption.
+ /// A delegate used for verifying the remote Secure Sockets
+ /// Layer (SSL) certificate which is used for authentication. Can be null if not
+ /// needed.
+ /// The hostname parameter is
+ /// null.
+ /// The hostname parameter is the empty
+ /// string.
+ /// The value of the port parameter
+ /// is not a valid port number.
+ public XmppCore(string hostname, string server, int port = 5222, bool tls = true,
+ RemoteCertificateValidationCallback validate = null)
+ {
+ if (String.IsNullOrWhiteSpace(server))
+ {
+
+ Hostname = hostname;
+ Server = hostname;
+ Port = port;
+ }
+ else {
+ Server = server;
+ Hostname = hostname;
+ Port = port;
+ }
+
+ Tls = tls;
+ Validate = validate;
+ }
///
/// Establishes a connection to the XMPP server.
@@ -465,17 +462,17 @@ private SrvRecord moveNextSrvDNS(string domain)
/// disposed.
/// If a username has been supplied, this method automatically performs
/// authentication.
- public void Connect(string resource = null)
+ public void Connect(string resource = null, bool bind = true)
{
if (disposed)
throw new ObjectDisposedException(GetType().FullName);
this.resource = resource;
try
{
- client = new TcpClient(Hostname, Port);
+ client = new TcpClient(Server, Port);
stream = client.GetStream();
// Sets up the connection which includes TLS and possibly SASL negotiation.
- SetupConnection(this.resource);
+ SetupConnection(this.resource, bind);
// We are connected.
Connected = true;
// Set up the listener and dispatcher tasks.
@@ -904,6 +901,7 @@ private void AssertValid()
///
/// The resource identifier to bind with. If this is null,
/// it is assigned by the server.
+ /// Do we bind - this is false in Stream Resumption but usually true.
/// The resource binding process failed.
/// Invalid or unexpected XML data has been
/// received from the XMPP server.
@@ -911,7 +909,7 @@ private void AssertValid()
/// trying to establish a secure connection, or the provided credentials were
/// rejected by the server, or the server requires TLS/SSL and TLS has been
/// turned off.
- private void SetupConnection(string resource = null)
+ private void SetupConnection(string resource = null, bool bind = true)
{
// Request the initial stream.
XmlElement feats = InitiateStream(Hostname);
@@ -944,7 +942,7 @@ private void SetupConnection(string resource = null)
feats = Authenticate(list, Username, Password, Hostname);
// FIXME: How is the client's JID constructed if the server does not support
// resource binding?
- if (feats["bind"] != null)
+ if (bind && feats["bind"] != null)
Jid = BindResource(resource);
}
catch (SaslException e)
@@ -1177,11 +1175,22 @@ private void Send(string xml)
/// The stanza parameter is null.
/// There was a failure while writing to
/// the network.
- private void Send(Stanza stanza)
+ private void Send(Stanza stanza, bool addToCache = true)
{
- stanza.ThrowIfNull("stanza");
+ stanza.ThrowIfNull("stanza");
Send(stanza.ToString());
- }
+
+ // we only want to cache specific stanzas if they are not being resent
+ if (addToCache &&
+ (stanza is XMPPEngineer.Core.Presence || stanza is XMPPEngineer.Core.Iq || stanza is XMPPEngineer.Core.Message))
+ {
+ // cache until receipt is confirmed
+ stanzaQueueCache.Add(stanza);
+
+ // add one to the sequence
+ currentOutboundStanzaSequence++;
+ }
+ }
///
/// Serializes and sends the specified XML element to the server and
@@ -1223,11 +1232,13 @@ private void ReadXmlStream()
{
while (true)
{
- XmlElement elem = parser.NextElement("iq", "message", "presence");
+ XmlElement elem = parser.NextElement("iq", "message", "presence", "enabled", "resumed", "a", "r", "failed");
// Parse element and dispatch.
switch (elem.Name)
{
case "iq":
+ currentInboundStanzaSequence++;
+
Iq iq = new Iq(elem);
if (iq.IsRequest)
stanzaQueue.Add(iq);
@@ -1236,11 +1247,40 @@ private void ReadXmlStream()
break;
case "message":
+ currentInboundStanzaSequence++;
+
stanzaQueue.Add(new Message(elem));
break;
case "presence":
+ currentInboundStanzaSequence++;
+
stanzaQueue.Add(new Presence(elem));
+ break;
+
+ // xep 1098 ###
+ case "failed":
+ HandleStreamManagementFailedResponse(elem);
+ break;
+
+ case "enabled":
+ HandleStreamManagementEnabledResponse(elem);
+ break;
+
+ case "resumed":
+ HandleResumedStreamResponse(elem);
+ break;
+
+ case "a":
+ currentInboundStanzaSequence++;
+ HandleAcknowledgementResponse(elem);
+ break;
+
+ case "r":
+ lastConfirmationAttemptServerTime = DateTime.Now;
+
+ // we tell the server about the number of items we have received in this stream
+ Send("");
break;
}
}
@@ -1266,6 +1306,501 @@ private void ReadXmlStream()
}
}
+ #region xep-0198 ###
+
+ ///
+ /// The event that is raised when stream management is enabled.
+ ///
+ public event EventHandler StreamManagementEnabled;
+
+ ///
+ /// The event that is raised when a stream is resumed.
+ ///
+ public event EventHandler StreamResumed;
+
+ ///
+ /// Is stream management enabled.
+ ///
+ private bool streamManagementEnabled = false;
+
+ ///
+ /// Is stream management resumption enabled.
+ ///
+ private bool resumptionEnabled = false;
+
+ ///
+ /// The resumption id that can be used if the stream drops.
+ ///
+ private string resumptionId = null;
+
+ ///
+ /// The cycle that checks for items to process and timeouts.
+ ///
+ private int streamCycleCheckTimeInSeconds = 10;
+
+ ///
+ /// The maximum time between a connection being dropped and being allowed to reconnect the stream.
+ /// The server can choose to override what is set here.
+ ///
+ private int maxResumptionPeriodInSeconds = 30;
+
+ ///
+ /// The maximum number of times we can try to resume a broken connection
+ ///
+ private const int MAX_RESUMPTION_ATTEMPTS = 3;
+
+ ///
+ /// The maximum number of times we can try to create a broken stream
+ ///
+ private const int MAX_STREAM_ATTEMPTS = 3;
+
+ ///
+ /// The current resumption attempt downward counter
+ ///
+ private int currentResumptionAttempt = 0;
+
+ ///
+ /// The current stream attempt downward counter
+ ///
+ private int currentStreamAttempt = 0;
+
+ ///
+ /// The last time any kind of confirmation was asked of the server.
+ /// Acknowledgements, Resumption and so on.
+ ///
+ private DateTime lastConfirmationAttemptServerTime = DateTime.MinValue;
+
+ ///
+ /// The last sequence number we have that was confirmed by the server
+ ///
+ private int lastConfirmedServerSequence = 0;
+
+ ///
+ /// When the server confirmed the above sequence number.
+ ///
+ private DateTime lastConfirmedServerTime = DateTime.MinValue;
+
+ ///
+ /// The maximum time without any kind of confirmation from the server.
+ ///
+ private int maxTimeBetweenConfirmationsInSeconds = 60;
+
+ ///
+ /// The namespace for stream management.
+ ///
+ const string STREAM_MANAGEMENT_NS = "urn:xmpp:sm:3";
+
+ ///
+ /// A global so we know if we are in the process of trying to resume the stream
+ ///
+ private bool isAttemptingStreamResumption = false;
+
+ ///
+ /// A record of when the last attempt to resume the stream started - must reset it on success.
+ ///
+ private DateTime? lastAttemptAtStreamResumptionTime = null;
+
+ ///
+ /// The max time we will wait before we regard resumption is failed and lost.
+ ///
+ private int maxStreamResumptionTimeoutInSecond = 30;
+
+ ///
+ /// A global so we know if we are in the process of trying to create a new stream
+ ///
+ private bool isAttemptingNewStream = false;
+
+ ///
+ /// A record of when the last attempt to create a new stream - must reset it on success.
+ ///
+ private DateTime? lastAttemptAtNewStreamTime = null;
+
+ ///
+ /// The max time we will wait before we regard creating a new stream has failed.
+ ///
+ private int maxNewStreamTimeoutInSecond = 30;
+
+ ///
+ /// The maximum number of times we can try to resume a broken connection
+ ///
+ private const int MAX_STANZAS_BEFORE_ACK_REQUEST = 3;
+
+ ///
+ /// The maximum time without any kind of acknowledgement request to the server.
+ ///
+ private int maxTimeBetweenAcknowledgementInSeconds = 20;
+
+
+ ///
+ /// The sequence of stanzas that has been sent for this connection.
+ ///
+ private int currentOutboundStanzaSequence = 0;
+
+ ///
+ /// The number of messages that have been receieved by this client.
+ ///
+ private int currentInboundStanzaSequence = 0;
+
+ ///
+ /// A cache of items that have been sent but not confirmed.
+ ///
+ private BlockingCollection stanzaQueueCache = new BlockingCollection();
+
+ ///
+ /// Stores the sequence identifier from the previous stream if there was a failure.
+ /// Allows us to at least attempt a recovery.
+ ///
+ int? resumedStreamServerSequence = null;
+
+ ///
+ /// Enables stream management. You should listen for the StreamManagementEnabled event
+ /// to know when it is ready.
+ /// Whether we should enabled resumption on the stream.
+ /// The max timeout client request - the server can override this.
+ ///
+ public void EnableStreamManagement(bool withresumption = true, int maxTimeout = 60)
+ {
+ // Send
+ XmlElement sm = Xml.Element("enable", STREAM_MANAGEMENT_NS);
+ sm.SetAttribute("resume", withresumption.ToString().ToLower());
+ sm.SetAttribute("max", maxTimeout.ToString());
+
+ // send to the server - a message will be sent back later
+ Send(sm);
+ }
+
+ ///
+ /// This will check if the stream management has been re-enabled after a previous stream failure.
+ /// If so, it will try to send anything that may hvae been missed.
+ ///
+ private void CheckIfResumedFromFailure()
+ {
+ // IF WE ARE COMING FROM A STREAM THAT WAS BROUGHT BACK FROM A PREVIOUS FAILURE
+ if (resumedStreamServerSequence.HasValue)
+ {
+ // update as the last sequence
+ lastConfirmedServerSequence = resumedStreamServerSequence.Value;
+
+ // from the last confirmed value up to the one it has now, remove from the cache
+ for (int i = lastConfirmedServerSequence; i < resumedStreamServerSequence; i++)
+ {
+ stanzaQueueCache.Take();
+ }
+
+ // now resend anything left over
+ for (int i = 0; i < stanzaQueueCache.Count; i++)
+ {
+ Stanza stanza = stanzaQueueCache.ElementAt(i);
+ Send(stanza, false);
+ }
+
+ // reset
+ resumedStreamServerSequence = null;
+ }
+ else
+ {
+ // if we have anything in the cache (from a previously fauiled session) then send it
+ for (int i = 0; i < stanzaQueueCache.Count; i++)
+ {
+ Stanza stanza = stanzaQueueCache.ElementAt(i);
+ Send(stanza, false);
+ }
+ }
+ }
+
+ ///
+ /// The callback when stream management is enabled.
+ ///
+ /// Enabled.
+ private void HandleStreamManagementEnabledResponse(XmlElement enabled)
+ {
+ CheckIfResumedFromFailure();
+
+ // normal behaviour below ...
+
+ // reset other variables - usually these are set when there was a previous stream
+ isAttemptingNewStream = false;
+ lastAttemptAtNewStreamTime = null;
+ isAttemptingStreamResumption = false;
+ lastAttemptAtStreamResumptionTime = null;
+ lastConfirmedServerTime = DateTime.Now;
+ currentResumptionAttempt = 0; //reset for next time
+ currentStreamAttempt = 0;
+ currentOutboundStanzaSequence = 0; //resets when it is a new stream
+ currentInboundStanzaSequence = 0;
+
+ // we have stream management enabled so lets get started
+ streamManagementEnabled = true;
+ resumptionEnabled = Boolean.Parse(enabled.GetAttribute("resume"));
+ resumptionId = enabled.GetAttribute("id");
+ int.TryParse(enabled.GetAttribute("max"), out maxResumptionPeriodInSeconds);
+
+ // manage the stream uptime
+ CheckStreamCycle();
+
+ // throw an event to say we're ready with resumption
+ StreamManagementEnabled.Raise(this, null);
+ }
+
+ ///
+ /// This will periodically check whether the server connection is up and
+ /// if not it will kick of a process to try and resume it, or create a new stream.
+ ///
+ private void CheckStreamCycle()
+ {
+ System.Timers.Timer timer = new System.Timers.Timer();
+ timer.Interval = streamCycleCheckTimeInSeconds * 1000;
+ timer.Enabled = true;
+
+ // inside here we manage the stream uptime - AT THE MOMENT we assume one attempt at stream resumption and then one attempt at connecting
+ timer.Elapsed += (sender, e) => {
+
+ // if we are in the process of trying to create a new stream and that has been going on too long throw an error (for now)
+
+ if (isAttemptingNewStream
+ && currentStreamAttempt > MAX_STREAM_ATTEMPTS
+ && lastAttemptAtNewStreamTime.HasValue
+ && DateTime.Now > lastAttemptAtNewStreamTime.Value.AddSeconds(maxNewStreamTimeoutInSecond))
+ {
+ var connex = new XmppDisconnectionException("Unable to create a new connection in the time period.");
+ Error.Raise(this, new ErrorEventArgs(connex));
+ }
+ else if (isAttemptingNewStream && currentStreamAttempt > MAX_STREAM_ATTEMPTS) // we are in the process of creating so let it run
+ return;
+
+ // if we are in the process of trying to resume and that has been going on too long, consider it failed and restart the stream
+ if (isAttemptingStreamResumption
+ && currentResumptionAttempt > MAX_RESUMPTION_ATTEMPTS
+ && lastAttemptAtStreamResumptionTime.HasValue
+ && DateTime.Now > lastAttemptAtStreamResumptionTime.Value.AddSeconds(maxStreamResumptionTimeoutInSecond))
+ {
+ // full stream restart - we cannot use resumption in this case as it is a brand new stream
+ isAttemptingNewStream = true;
+ lastAttemptAtNewStreamTime = DateTime.Now;
+
+ try
+ {
+ // we will try getting the connection back again
+ currentStreamAttempt++;
+
+ // try to create a new connection
+ Connect(this.resource);
+
+ // finally, we enable stream management if it is on - IF WE DO THIS HERE
+ // ARE THERE ANY RACE CONDITIONS BY RESETING THE VARIBLES ABOVE BEFORE THE RESPONSE ?
+ if (streamManagementEnabled)
+ {
+ // we will reset the variables below when we get a stream management response
+ EnableStreamManagement(resumptionEnabled, maxResumptionPeriodInSeconds);
+
+ // send items we have in the cache - we don't know what failed
+ for (int i = 0; i < stanzaQueueCache.Count; i++)
+ {
+ Stanza stanza = stanzaQueueCache.ElementAt(i);
+ Send(stanza, false);
+ }
+
+ } else {
+
+ // if successful then reset
+ isAttemptingNewStream = false;
+ lastAttemptAtNewStreamTime = null;
+ isAttemptingStreamResumption = false;
+ lastAttemptAtStreamResumptionTime = null;
+ lastConfirmedServerTime = DateTime.Now;
+ currentResumptionAttempt = 0; //reset for next time
+ currentStreamAttempt = 0;
+ currentOutboundStanzaSequence = 0; //resets when it is a new stream
+ currentInboundStanzaSequence = 0;
+ }
+
+ return;
+ }
+ catch {
+
+ // a network error of some kind - timer will ensure a rerty is done shortly.
+ return;
+ }
+ }
+
+ // If we are not trying to resume the connection && have had no response from the server at all in a given period despite an attempt we will try to resume the stream
+ if (!isAttemptingStreamResumption
+ && DateTime.Now > lastConfirmedServerTime.AddSeconds(maxTimeBetweenConfirmationsInSeconds))
+ {
+ // we will try getting the connection back again
+ currentResumptionAttempt++;
+
+ // try to resume the connection
+ ResumeStream();
+
+ // we don't want to send through a request until the stream says it is ready
+ return;
+ }
+
+ // if you ARE attempting a resumption but it has been going on too long then we need to try again
+ if (isAttemptingStreamResumption
+ && lastAttemptAtStreamResumptionTime.HasValue
+ && DateTime.Now > lastAttemptAtStreamResumptionTime.Value.AddSeconds(maxStreamResumptionTimeoutInSecond))
+ {
+ // we will try getting the connection back again
+ currentResumptionAttempt++;
+
+ // try to resume the connection
+ ResumeStream();
+
+ // we don't want to send through a request until the stream says it is ready
+ return;
+ }
+
+ // Normal path here - have we got to the threshhold of items added or the timeout for checks for acks?
+ if ((currentOutboundStanzaSequence > 0
+ && currentOutboundStanzaSequence % MAX_STANZAS_BEFORE_ACK_REQUEST == 0)
+ || DateTime.Now > lastConfirmedServerTime.AddSeconds(maxTimeBetweenAcknowledgementInSeconds))
+ {
+ // request for acknowlegement
+ Send("");
+ }
+ };
+
+ timer.Start();
+ }
+
+ ///
+ /// This will try to resume a stream, often caused by a dropped connection.
+ ///
+ private void ResumeStream()
+ {
+ // don't run multiple of these
+ if (isAttemptingStreamResumption) return;
+
+ // set these management vars
+ isAttemptingStreamResumption = true;
+ lastAttemptAtStreamResumptionTime = DateTime.Now;
+
+ // recreate the connection without binding
+ Connect(this.resource, false);
+
+ // Send
+ XmlElement rs = Xml.Element("resume", STREAM_MANAGEMENT_NS);
+ rs.SetAttribute("h", lastConfirmedServerSequence.ToString());
+ rs.SetAttribute("previd", resumptionId);
+
+ // send to the server - a message will be sent back later
+ Send(rs);
+ }
+
+ ///
+ /// Thrown when we receive an exception in stream management.
+ ///
+ /// Failure element.
+ private void HandleStreamManagementFailedResponse(XmlElement failed)
+ {
+ /*
+
+
+
+ */
+
+ // I think it is supposed to create a new session when this happens - even if it is not the same
+ // as the previous one, but this doesn't *seem* to be working. In this case, let's create a brand new
+ // session.
+
+ if (failed.FirstChild.LocalName == "item-not-found")
+ {
+ // store this so we can resend after the stream is back up
+ if (failed.HasAttribute("h"))
+ {
+ // store the sequence so we can resend once we've connected
+ resumedStreamServerSequence = int.Parse(failed.GetAttribute("h"));
+ }
+
+ // create a new connection
+ Connect(this.resource);
+ lastConfirmedServerTime = DateTime.Now;
+
+ // ### reset as we are now no longer trying to resume the stream
+ isAttemptingStreamResumption = false;
+ lastAttemptAtStreamResumptionTime = null;
+ currentResumptionAttempt = 0; //reset for next time
+ // ###
+
+ ///// we will reset the variables below when we get a stream management response
+ EnableStreamManagement(resumptionEnabled, maxResumptionPeriodInSeconds);
+ }
+ else
+ {
+ // we have some other issue
+ var err = new XmppErrorException(new XmppError(failed));
+ Error.Raise(this, new ErrorEventArgs(err));
+ }
+
+ // throw an event to say we're ready with resumption
+ StreamResumed.Raise(this, null);
+ }
+
+ ///
+ /// The callback when stream is resumed.
+ ///
+ /// Resumed xml element.
+ private void HandleResumedStreamResponse(XmlElement resumed)
+ {
+ // reset as we are now no longer trying to resume the stream
+ isAttemptingStreamResumption = false;
+ lastAttemptAtStreamResumptionTime = null;
+ currentResumptionAttempt = 0; //reset for next time
+
+ // what is the last item the server is aware of and record at what point that is
+ int sequence = int.Parse(resumed.GetAttribute("h"));
+
+ // from the last confirmed value up to the one it has now, remove from the cache
+ for (int i = lastConfirmedServerSequence; i < sequence; i++)
+ {
+ stanzaQueueCache.Take();
+ }
+
+ // now resend anything left over
+ for (int i = 0; i < stanzaQueueCache.Count; i++)
+ {
+ Stanza stanza = stanzaQueueCache.ElementAt(i);
+ Send(stanza, false);
+ }
+
+ // update as the last sequence
+ lastConfirmedServerSequence = sequence;
+ lastConfirmedServerTime = DateTime.Now;
+
+ // throw an event to say we're ready with resumption
+ StreamResumed.Raise(this, null);
+ }
+
+ ///
+ /// When an acknowledgement event is recieved.
+ ///
+ /// Ack element.
+ private void HandleAcknowledgementResponse(XmlElement ack)
+ {
+ // what sequence does the server have>
+ int sequence = int.Parse(ack.GetAttribute("h"));
+
+ // from the last confirmed value up to the one it has now, remove from the cache
+ for (int i = lastConfirmedServerSequence; i < sequence; i++)
+ {
+ stanzaQueueCache.Take();
+ }
+
+ // ###
+ isAttemptingStreamResumption = false;
+ lastAttemptAtStreamResumptionTime = null;
+ currentResumptionAttempt = 0; //reset for next time
+
+ // update as the last sequence
+ lastConfirmedServerSequence = sequence;
+ lastConfirmedServerTime = DateTime.Now;
+ }
+
+ #endregion
+
///
/// Continously removes stanzas from the FIFO of incoming stanzas and raises
/// the respective events.
diff --git a/ErrorCondition.cs b/ErrorCondition.cs
index 787ed17a..8104da65 100644
--- a/ErrorCondition.cs
+++ b/ErrorCondition.cs
@@ -1,4 +1,4 @@
-namespace Sharp.Xmpp
+namespace XMPPEngineer
{
///
/// Defines possible values for the condition of XMPP errors.
diff --git a/ErrorType.cs b/ErrorType.cs
index 152437fa..b940981a 100644
--- a/ErrorType.cs
+++ b/ErrorType.cs
@@ -1,4 +1,4 @@
-namespace Sharp.Xmpp
+namespace XMPPEngineer
{
///
/// Defines possible values for the type of XMPP errors.
diff --git a/Extensions/CustomExtension/CustomIqExtension.cs b/Extensions/CustomExtension/CustomIqExtension.cs
index ec4d2153..c94c47ee 100644
--- a/Extensions/CustomExtension/CustomIqExtension.cs
+++ b/Extensions/CustomExtension/CustomIqExtension.cs
@@ -1,10 +1,10 @@
-using Sharp.Xmpp.Core;
-using Sharp.Xmpp.Im;
+using XMPPEngineer.Core;
+using XMPPEngineer.Im;
using System;
using System.Collections.Generic;
using System.Xml;
-namespace Sharp.Xmpp.Extensions
+namespace XMPPEngineer.Extensions
{
///
/// Implements Mechanism for providing Custom IQ Extensions
@@ -25,7 +25,7 @@ public override IEnumerable Namespaces
{
get
{
- return new string[] { "urn:sharp.xmpp:customiq" };
+ return new string[] { "urn:xmppengineer.xmpp:customiq" };
}
}
@@ -67,7 +67,7 @@ public bool Input(Iq stanza)
// return false;
//get,set, result are supported
var customIqStanza = stanza.Data["customiq"];
- if (customIqStanza == null || customIqStanza.NamespaceURI != "urn:sharp.xmpp:customiq")
+ if (customIqStanza == null || customIqStanza.NamespaceURI != "urn:xmppengineer.xmpp:customiq")
return false;
//Result indicates that the request has been received.
//It has not to do with the semantics of the message
@@ -77,7 +77,7 @@ public bool Input(Iq stanza)
CopyNodes(targetDocument, targetDocument, query.FirstChild);
- var xmlresponse = Xml.Element("customiq", "urn:sharp.xmpp:customiq");
+ var xmlresponse = Xml.Element("customiq", "urn:xmppengineer.xmpp:customiq");
try
{
//call the callback for receiving a relevant stanza
@@ -142,7 +142,7 @@ public void RequestCustomIqAsync(Jid jid, string request, Action callback)
throw new NotSupportedException("The XMPP entity does not support the " +
"'CustomIqExtension' extension.");
}
- var xml = Xml.Element("customiq", "urn:sharp.xmpp:customiq").Text(request);
+ var xml = Xml.Element("customiq", "urn:xmppengineer.xmpp:customiq").Text(request);
//The Request is Async
im.IqRequestAsync(IqType.Get, jid, im.Jid, xml, null, (id, iq) =>
@@ -195,7 +195,7 @@ public void RequestCustomIq(Jid jid, string request)
throw new NotSupportedException("The XMPP entity does not support the " +
"'CustomIqExtension' extension.");
}
- var xml = Xml.Element("customiq", "urn:sharp.xmpp:customiq").Text(request);
+ var xml = Xml.Element("customiq", "urn:xmppengineer.xmpp:customiq").Text(request);
//The Request is Async
im.IqRequest(IqType.Get, jid, im.Jid, xml);
diff --git a/Extensions/CustomExtension/CustomIqRequestDelegate.cs b/Extensions/CustomExtension/CustomIqRequestDelegate.cs
index f9f19247..4993ac5a 100644
--- a/Extensions/CustomExtension/CustomIqRequestDelegate.cs
+++ b/Extensions/CustomExtension/CustomIqRequestDelegate.cs
@@ -1,4 +1,4 @@
-namespace Sharp.Xmpp.Extensions
+namespace XMPPEngineer.Extensions
{
///
/// Invoked when a CustomIqRequest is made.
diff --git a/Extensions/Extension.cs b/Extensions/Extension.cs
index e5187c77..50026d4e 100644
--- a/Extensions/Extension.cs
+++ b/Extensions/Extension.cs
@@ -1,4 +1,4 @@
-namespace Sharp.Xmpp.Extensions
+namespace XMPPEngineer.Extensions
{
///
/// An enumeration of supported XMPP extensions.
diff --git a/Extensions/IInputFilter.cs b/Extensions/IInputFilter.cs
index 52b8f31c..fd12fb0d 100644
--- a/Extensions/IInputFilter.cs
+++ b/Extensions/IInputFilter.cs
@@ -1,6 +1,6 @@
-using Sharp.Xmpp.Core;
+using XMPPEngineer.Core;
-namespace Sharp.Xmpp.Extensions
+namespace XMPPEngineer.Extensions
{
///
/// Represents an extension that filters incoming stanzas.
diff --git a/Extensions/IOutputFilter.cs b/Extensions/IOutputFilter.cs
index 34894b3c..6d3a64bf 100644
--- a/Extensions/IOutputFilter.cs
+++ b/Extensions/IOutputFilter.cs
@@ -1,6 +1,6 @@
-using Sharp.Xmpp.Core;
+using XMPPEngineer.Core;
-namespace Sharp.Xmpp.Extensions
+namespace XMPPEngineer.Extensions
{
///
/// Represents an extension that filters outgoing stanzas.
diff --git a/Extensions/XEP-0004/DataForms.cs b/Extensions/XEP-0004/DataForms.cs
index 731a4a93..2877b03f 100644
--- a/Extensions/XEP-0004/DataForms.cs
+++ b/Extensions/XEP-0004/DataForms.cs
@@ -1,7 +1,7 @@
-using Sharp.Xmpp.Im;
+using XMPPEngineer.Im;
using System.Collections.Generic;
-namespace Sharp.Xmpp.Extensions
+namespace XMPPEngineer.Extensions
{
///
/// Implements the 'Data Forms' extension as defined in XEP-0004.
diff --git a/Extensions/XEP-0004/Dataforms/BooleanField.cs b/Extensions/XEP-0004/Dataforms/BooleanField.cs
index e97af276..60515ab0 100644
--- a/Extensions/XEP-0004/Dataforms/BooleanField.cs
+++ b/Extensions/XEP-0004/Dataforms/BooleanField.cs
@@ -1,7 +1,7 @@
using System;
using System.Xml;
-namespace Sharp.Xmpp.Extensions.Dataforms
+namespace XMPPEngineer.Extensions.Dataforms
{
///
/// Represents a field that provides an either-or choice between two options.
diff --git a/Extensions/XEP-0004/Dataforms/CancelForm.cs b/Extensions/XEP-0004/Dataforms/CancelForm.cs
index e5729176..24fd701e 100644
--- a/Extensions/XEP-0004/Dataforms/CancelForm.cs
+++ b/Extensions/XEP-0004/Dataforms/CancelForm.cs
@@ -1,7 +1,7 @@
using System;
using System.Xml;
-namespace Sharp.Xmpp.Extensions.Dataforms
+namespace XMPPEngineer.Extensions.Dataforms
{
///
/// Represents a data-form that signals cancellation of submission of data.
diff --git a/Extensions/XEP-0004/Dataforms/DataField.cs b/Extensions/XEP-0004/Dataforms/DataField.cs
index f12a47aa..78b7a5b8 100644
--- a/Extensions/XEP-0004/Dataforms/DataField.cs
+++ b/Extensions/XEP-0004/Dataforms/DataField.cs
@@ -3,7 +3,7 @@
using System.Text;
using System.Xml;
-namespace Sharp.Xmpp.Extensions.Dataforms
+namespace XMPPEngineer.Extensions.Dataforms
{
///
/// The base class from which all implementations of data-fields must derive.
diff --git a/Extensions/XEP-0004/Dataforms/DataFieldType.cs b/Extensions/XEP-0004/Dataforms/DataFieldType.cs
index 468cb2a8..5563dcc2 100644
--- a/Extensions/XEP-0004/Dataforms/DataFieldType.cs
+++ b/Extensions/XEP-0004/Dataforms/DataFieldType.cs
@@ -1,4 +1,4 @@
-namespace Sharp.Xmpp.Extensions.Dataforms
+namespace XMPPEngineer.Extensions.Dataforms
{
///
/// Defines possible values for the different types of data-fields.
diff --git a/Extensions/XEP-0004/Dataforms/DataForm.cs b/Extensions/XEP-0004/Dataforms/DataForm.cs
index d970f938..051b219a 100644
--- a/Extensions/XEP-0004/Dataforms/DataForm.cs
+++ b/Extensions/XEP-0004/Dataforms/DataForm.cs
@@ -1,7 +1,7 @@
using System;
using System.Xml;
-namespace Sharp.Xmpp.Extensions.Dataforms
+namespace XMPPEngineer.Extensions.Dataforms
{
///
/// The abstract base class from which all implementations of concrete
diff --git a/Extensions/XEP-0004/Dataforms/DataFormFactory.cs b/Extensions/XEP-0004/Dataforms/DataFormFactory.cs
index 01d0a878..987a5b9a 100644
--- a/Extensions/XEP-0004/Dataforms/DataFormFactory.cs
+++ b/Extensions/XEP-0004/Dataforms/DataFormFactory.cs
@@ -1,7 +1,7 @@
using System;
using System.Xml;
-namespace Sharp.Xmpp.Extensions.Dataforms
+namespace XMPPEngineer.Extensions.Dataforms
{
///
/// A factory for creating data-form instances.
diff --git a/Extensions/XEP-0004/Dataforms/DataFormType.cs b/Extensions/XEP-0004/Dataforms/DataFormType.cs
index 8f1277ac..e137c922 100644
--- a/Extensions/XEP-0004/Dataforms/DataFormType.cs
+++ b/Extensions/XEP-0004/Dataforms/DataFormType.cs
@@ -1,4 +1,4 @@
-namespace Sharp.Xmpp.Extensions.Dataforms
+namespace XMPPEngineer.Extensions.Dataforms
{
///
/// Defines possible values for the different types of data-forms.
diff --git a/Extensions/XEP-0004/Dataforms/FieldList.cs b/Extensions/XEP-0004/Dataforms/FieldList.cs
index cf098696..a112e4f7 100644
--- a/Extensions/XEP-0004/Dataforms/FieldList.cs
+++ b/Extensions/XEP-0004/Dataforms/FieldList.cs
@@ -4,7 +4,7 @@
using System.Text;
using System.Xml;
-namespace Sharp.Xmpp.Extensions.Dataforms
+namespace XMPPEngineer.Extensions.Dataforms
{
///
/// Represents a list of data-fields contained in a data-form.
diff --git a/Extensions/XEP-0004/Dataforms/FixedField.cs b/Extensions/XEP-0004/Dataforms/FixedField.cs
index c192d325..b2a7f164 100644
--- a/Extensions/XEP-0004/Dataforms/FixedField.cs
+++ b/Extensions/XEP-0004/Dataforms/FixedField.cs
@@ -1,7 +1,7 @@
using System;
using System.Xml;
-namespace Sharp.Xmpp.Extensions.Dataforms
+namespace XMPPEngineer.Extensions.Dataforms
{
///
/// Represents a field that is intended for data description rather
diff --git a/Extensions/XEP-0004/Dataforms/HiddenField.cs b/Extensions/XEP-0004/Dataforms/HiddenField.cs
index 2f5633ab..3789805a 100644
--- a/Extensions/XEP-0004/Dataforms/HiddenField.cs
+++ b/Extensions/XEP-0004/Dataforms/HiddenField.cs
@@ -2,7 +2,7 @@
using System.Collections.Generic;
using System.Xml;
-namespace Sharp.Xmpp.Extensions.Dataforms
+namespace XMPPEngineer.Extensions.Dataforms
{
///
/// Represents a field that is intended to be invisible to the form-submitting
diff --git a/Extensions/XEP-0004/Dataforms/JidField.cs b/Extensions/XEP-0004/Dataforms/JidField.cs
index 639f43c3..8dcbc7ff 100644
--- a/Extensions/XEP-0004/Dataforms/JidField.cs
+++ b/Extensions/XEP-0004/Dataforms/JidField.cs
@@ -1,7 +1,7 @@
using System;
using System.Xml;
-namespace Sharp.Xmpp.Extensions.Dataforms
+namespace XMPPEngineer.Extensions.Dataforms
{
///
/// Represents a field for gathering or providing a single Jabber ID.
diff --git a/Extensions/XEP-0004/Dataforms/JidMultiField.cs b/Extensions/XEP-0004/Dataforms/JidMultiField.cs
index 74fab1ff..73ba7be2 100644
--- a/Extensions/XEP-0004/Dataforms/JidMultiField.cs
+++ b/Extensions/XEP-0004/Dataforms/JidMultiField.cs
@@ -2,7 +2,7 @@
using System.Collections.Generic;
using System.Xml;
-namespace Sharp.Xmpp.Extensions.Dataforms
+namespace XMPPEngineer.Extensions.Dataforms
{
///
/// Represents a field for gathering or providing multiple Jabber IDs.
diff --git a/Extensions/XEP-0004/Dataforms/ListField.cs b/Extensions/XEP-0004/Dataforms/ListField.cs
index 0f9297fb..864065ca 100644
--- a/Extensions/XEP-0004/Dataforms/ListField.cs
+++ b/Extensions/XEP-0004/Dataforms/ListField.cs
@@ -2,7 +2,7 @@
using System.Collections.Generic;
using System.Xml;
-namespace Sharp.Xmpp.Extensions.Dataforms
+namespace XMPPEngineer.Extensions.Dataforms
{
///
/// Represents a field for gathering or providing one option from among many.
diff --git a/Extensions/XEP-0004/Dataforms/ListMultiField.cs b/Extensions/XEP-0004/Dataforms/ListMultiField.cs
index 0a39da7e..3fcb2aae 100644
--- a/Extensions/XEP-0004/Dataforms/ListMultiField.cs
+++ b/Extensions/XEP-0004/Dataforms/ListMultiField.cs
@@ -2,7 +2,7 @@
using System.Collections.Generic;
using System.Xml;
-namespace Sharp.Xmpp.Extensions.Dataforms
+namespace XMPPEngineer.Extensions.Dataforms
{
///
/// Represents a field for gathering or providing one or more options
diff --git a/Extensions/XEP-0004/Dataforms/Option.cs b/Extensions/XEP-0004/Dataforms/Option.cs
index effd1a6f..be104360 100644
--- a/Extensions/XEP-0004/Dataforms/Option.cs
+++ b/Extensions/XEP-0004/Dataforms/Option.cs
@@ -1,7 +1,7 @@
using System;
using System.Xml;
-namespace Sharp.Xmpp.Extensions.Dataforms
+namespace XMPPEngineer.Extensions.Dataforms
{
///
/// Represents an option of a list data-field.
diff --git a/Extensions/XEP-0004/Dataforms/PasswordField.cs b/Extensions/XEP-0004/Dataforms/PasswordField.cs
index c61dd453..e4c99d72 100644
--- a/Extensions/XEP-0004/Dataforms/PasswordField.cs
+++ b/Extensions/XEP-0004/Dataforms/PasswordField.cs
@@ -1,7 +1,7 @@
using System;
using System.Xml;
-namespace Sharp.Xmpp.Extensions.Dataforms
+namespace XMPPEngineer.Extensions.Dataforms
{
///
/// Represents a field for gathering or providing a single line or word of
diff --git a/Extensions/XEP-0004/Dataforms/RequestForm.cs b/Extensions/XEP-0004/Dataforms/RequestForm.cs
index f7173534..2d32ba2e 100644
--- a/Extensions/XEP-0004/Dataforms/RequestForm.cs
+++ b/Extensions/XEP-0004/Dataforms/RequestForm.cs
@@ -1,7 +1,7 @@
using System;
using System.Xml;
-namespace Sharp.Xmpp.Extensions.Dataforms
+namespace XMPPEngineer.Extensions.Dataforms
{
///
/// Represents a requesting data-form.
diff --git a/Extensions/XEP-0004/Dataforms/ResultForm.cs b/Extensions/XEP-0004/Dataforms/ResultForm.cs
index f9f0b34b..a562350a 100644
--- a/Extensions/XEP-0004/Dataforms/ResultForm.cs
+++ b/Extensions/XEP-0004/Dataforms/ResultForm.cs
@@ -2,7 +2,7 @@
using System.Collections.Generic;
using System.Xml;
-namespace Sharp.Xmpp.Extensions.Dataforms
+namespace XMPPEngineer.Extensions.Dataforms
{
///
/// Represents a result form containing returned data or a generic data set.
diff --git a/Extensions/XEP-0004/Dataforms/SubmitForm.cs b/Extensions/XEP-0004/Dataforms/SubmitForm.cs
index 05ba174d..2aeef4f0 100644
--- a/Extensions/XEP-0004/Dataforms/SubmitForm.cs
+++ b/Extensions/XEP-0004/Dataforms/SubmitForm.cs
@@ -1,7 +1,7 @@
using System;
using System.Xml;
-namespace Sharp.Xmpp.Extensions.Dataforms
+namespace XMPPEngineer.Extensions.Dataforms
{
///
/// Represents a data-form for data submission.
diff --git a/Extensions/XEP-0004/Dataforms/TextField.cs b/Extensions/XEP-0004/Dataforms/TextField.cs
index 2c381d3f..57d1e953 100644
--- a/Extensions/XEP-0004/Dataforms/TextField.cs
+++ b/Extensions/XEP-0004/Dataforms/TextField.cs
@@ -1,7 +1,7 @@
using System;
using System.Xml;
-namespace Sharp.Xmpp.Extensions.Dataforms
+namespace XMPPEngineer.Extensions.Dataforms
{
///
/// Represents a field for gathering or providing a single line or word of
diff --git a/Extensions/XEP-0004/Dataforms/TextMultiField.cs b/Extensions/XEP-0004/Dataforms/TextMultiField.cs
index fcd6687e..1b927537 100644
--- a/Extensions/XEP-0004/Dataforms/TextMultiField.cs
+++ b/Extensions/XEP-0004/Dataforms/TextMultiField.cs
@@ -2,7 +2,7 @@
using System.Collections.Generic;
using System.Xml;
-namespace Sharp.Xmpp.Extensions.Dataforms
+namespace XMPPEngineer.Extensions.Dataforms
{
///
/// Represents a field for gathering or providing multiple lines of text.
diff --git a/Extensions/XEP-0004/Dataforms/XmlCollection.cs b/Extensions/XEP-0004/Dataforms/XmlCollection.cs
index 6169f8e2..b7149a55 100644
--- a/Extensions/XEP-0004/Dataforms/XmlCollection.cs
+++ b/Extensions/XEP-0004/Dataforms/XmlCollection.cs
@@ -3,7 +3,7 @@
using System.Collections.Generic;
using System.Xml;
-namespace Sharp.Xmpp.Extensions.Dataforms
+namespace XMPPEngineer.Extensions.Dataforms
{
///
/// Represents an XML-backed generic collection.
diff --git a/Extensions/XEP-0020/FeatureNegotiation.cs b/Extensions/XEP-0020/FeatureNegotiation.cs
index 50f49d9e..0dff32f8 100644
--- a/Extensions/XEP-0020/FeatureNegotiation.cs
+++ b/Extensions/XEP-0020/FeatureNegotiation.cs
@@ -1,10 +1,10 @@
-using Sharp.Xmpp.Extensions.Dataforms;
-using Sharp.Xmpp.Im;
+using XMPPEngineer.Extensions.Dataforms;
+using XMPPEngineer.Im;
using System;
using System.Collections.Generic;
using System.Xml;
-namespace Sharp.Xmpp.Extensions
+namespace XMPPEngineer.Extensions
{
///
/// Implements the 'Feature Negotiation' extension as defined in XEP-0020.
diff --git a/Extensions/XEP-0030/Identity.cs b/Extensions/XEP-0030/Identity.cs
index b8a3f353..e79579e6 100644
--- a/Extensions/XEP-0030/Identity.cs
+++ b/Extensions/XEP-0030/Identity.cs
@@ -1,7 +1,7 @@
using System;
using System.Collections.Generic;
-namespace Sharp.Xmpp.Extensions
+namespace XMPPEngineer.Extensions
{
///
/// Represents an identity of an XMPP entity as defined in XEP-0030.
diff --git a/Extensions/XEP-0030/Item.cs b/Extensions/XEP-0030/Item.cs
index d8b2b0a0..492b59fd 100644
--- a/Extensions/XEP-0030/Item.cs
+++ b/Extensions/XEP-0030/Item.cs
@@ -1,6 +1,6 @@
using System;
-namespace Sharp.Xmpp.Extensions
+namespace XMPPEngineer.Extensions
{
///
/// Represents an item of an XMPP entity as defined in XEP-0030.
diff --git a/Extensions/XEP-0030/ServiceDiscovery.cs b/Extensions/XEP-0030/ServiceDiscovery.cs
index be4d56eb..5255bbf3 100644
--- a/Extensions/XEP-0030/ServiceDiscovery.cs
+++ b/Extensions/XEP-0030/ServiceDiscovery.cs
@@ -1,12 +1,12 @@
-using Sharp.Xmpp.Core;
-using Sharp.Xmpp.Im;
+using XMPPEngineer.Core;
+using XMPPEngineer.Im;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Xml;
-namespace Sharp.Xmpp.Extensions
+namespace XMPPEngineer.Extensions
{
///
/// Implements the 'Service Discovery' extension as defined in XEP-0030.
diff --git a/Extensions/XEP-0045/Affiliation.cs b/Extensions/XEP-0045/Affiliation.cs
index 56ccbdaa..33b2c323 100644
--- a/Extensions/XEP-0045/Affiliation.cs
+++ b/Extensions/XEP-0045/Affiliation.cs
@@ -1,4 +1,4 @@
-namespace Sharp.Xmpp.Extensions
+namespace XMPPEngineer.Extensions
{
///
/// Describes the Affiliation of a participant in a group chat.
diff --git a/Extensions/XEP-0045/GroupErrorEventArgs.cs b/Extensions/XEP-0045/GroupErrorEventArgs.cs
index 9adb4e79..ef1109ca 100644
--- a/Extensions/XEP-0045/GroupErrorEventArgs.cs
+++ b/Extensions/XEP-0045/GroupErrorEventArgs.cs
@@ -1,6 +1,6 @@
using System;
-namespace Sharp.Xmpp.Extensions
+namespace XMPPEngineer.Extensions
{
///
/// Represents a group presence error event in a group chat. Ref XEP-0045
diff --git a/Extensions/XEP-0045/GroupInviteDeclinedEventArgs.cs b/Extensions/XEP-0045/GroupInviteDeclinedEventArgs.cs
index 5a0e28f2..ce26b113 100644
--- a/Extensions/XEP-0045/GroupInviteDeclinedEventArgs.cs
+++ b/Extensions/XEP-0045/GroupInviteDeclinedEventArgs.cs
@@ -1,6 +1,6 @@
using System;
-namespace Sharp.Xmpp.Extensions
+namespace XMPPEngineer.Extensions
{
///
/// Represents a group invite event in a group chat. Ref XEP-0045
diff --git a/Extensions/XEP-0045/GroupInviteEventArgs.cs b/Extensions/XEP-0045/GroupInviteEventArgs.cs
index 4ec38b71..3b0d7863 100644
--- a/Extensions/XEP-0045/GroupInviteEventArgs.cs
+++ b/Extensions/XEP-0045/GroupInviteEventArgs.cs
@@ -1,6 +1,6 @@
using System;
-namespace Sharp.Xmpp.Extensions
+namespace XMPPEngineer.Extensions
{
///
/// Represents a group invite event in a group chat. Ref XEP-0045
diff --git a/Extensions/XEP-0045/GroupPresenceEventArgs.cs b/Extensions/XEP-0045/GroupPresenceEventArgs.cs
index 73cb9def..1ebe81c3 100644
--- a/Extensions/XEP-0045/GroupPresenceEventArgs.cs
+++ b/Extensions/XEP-0045/GroupPresenceEventArgs.cs
@@ -1,7 +1,7 @@
using System;
using System.Collections.Generic;
-namespace Sharp.Xmpp.Extensions
+namespace XMPPEngineer.Extensions
{
///
/// Represents a presence change event in a group chat. Ref XEP-0045
@@ -13,6 +13,8 @@ public class GroupPresenceEventArgs : EventArgs
///
public Occupant Person { get; set; }
+ public Jid Group { get; }
+
///
///
///
@@ -22,10 +24,12 @@ public class GroupPresenceEventArgs : EventArgs
///
///
///
+ ///
///
- public GroupPresenceEventArgs(Occupant person, IEnumerable statuses) : base()
+ public GroupPresenceEventArgs(Occupant person, Jid group, IEnumerable statuses) : base()
{
Person = person;
+ Group = group;
Statuses = statuses;
}
}
diff --git a/Extensions/XEP-0045/History.cs b/Extensions/XEP-0045/History.cs
index b2a931bd..b0646ebb 100644
--- a/Extensions/XEP-0045/History.cs
+++ b/Extensions/XEP-0045/History.cs
@@ -1,8 +1,8 @@
using System;
using System.Xml;
-using Sharp.Xmpp.Core;
+using XMPPEngineer.Core;
-namespace Sharp.Xmpp.Extensions
+namespace XMPPEngineer.Extensions
{
///
/// Implements the message history request object as described in XEP-0045.
diff --git a/Extensions/XEP-0045/Invite.cs b/Extensions/XEP-0045/Invite.cs
index 2441fe74..d994b97f 100644
--- a/Extensions/XEP-0045/Invite.cs
+++ b/Extensions/XEP-0045/Invite.cs
@@ -2,9 +2,9 @@
using System.Collections.Generic;
using System.Linq;
using System.Xml;
-using Sharp.Xmpp.Core;
+using XMPPEngineer.Core;
-namespace Sharp.Xmpp.Extensions
+namespace XMPPEngineer.Extensions
{
///
/// Implements MUC Mediated Invitation as described in XEP-0045.
diff --git a/Extensions/XEP-0045/InviteDeclined.cs b/Extensions/XEP-0045/InviteDeclined.cs
index 1e131dfd..c04f5744 100644
--- a/Extensions/XEP-0045/InviteDeclined.cs
+++ b/Extensions/XEP-0045/InviteDeclined.cs
@@ -2,9 +2,9 @@
using System.Collections.Generic;
using System.Linq;
using System.Xml;
-using Sharp.Xmpp.Core;
+using XMPPEngineer.Core;
-namespace Sharp.Xmpp.Extensions
+namespace XMPPEngineer.Extensions
{
///
/// Implements MUC Mediated Invitation as described in XEP-0045.
diff --git a/Extensions/XEP-0045/MucError.cs b/Extensions/XEP-0045/MucError.cs
index 6ed87c97..b93a83e7 100644
--- a/Extensions/XEP-0045/MucError.cs
+++ b/Extensions/XEP-0045/MucError.cs
@@ -3,7 +3,7 @@
using System.Linq;
using System.Xml;
-namespace Sharp.Xmpp.Extensions
+namespace XMPPEngineer.Extensions
{
///
/// Implements a MUC error response which may be contained in either an IQ or a Presence.
diff --git a/Extensions/XEP-0045/MucNs.cs b/Extensions/XEP-0045/MucNs.cs
index ac23cc86..96db64bb 100644
--- a/Extensions/XEP-0045/MucNs.cs
+++ b/Extensions/XEP-0045/MucNs.cs
@@ -1,4 +1,4 @@
-namespace Sharp.Xmpp.Extensions
+namespace XMPPEngineer.Extensions
{
///
/// Identifiers used to describe objects in objects in the MUC Namespace.
diff --git a/Extensions/XEP-0045/MucStatusType.cs b/Extensions/XEP-0045/MucStatusType.cs
index 347b10be..115919c2 100644
--- a/Extensions/XEP-0045/MucStatusType.cs
+++ b/Extensions/XEP-0045/MucStatusType.cs
@@ -1,5 +1,5 @@
using System;
-namespace Sharp.Xmpp.Extensions
+namespace XMPPEngineer.Extensions
{
///
/// Defines an extensible format for status conditions in MUC.
diff --git a/Extensions/XEP-0045/MultiUserChat.cs b/Extensions/XEP-0045/MultiUserChat.cs
index 81ba6f57..72fb843c 100644
--- a/Extensions/XEP-0045/MultiUserChat.cs
+++ b/Extensions/XEP-0045/MultiUserChat.cs
@@ -4,11 +4,11 @@
using System.Text;
using System.Threading.Tasks;
using System.Xml;
-using Sharp.Xmpp.Core;
-using Sharp.Xmpp.Extensions.Dataforms;
-using Sharp.Xmpp.Im;
+using XMPPEngineer.Core;
+using XMPPEngineer.Extensions.Dataforms;
+using XMPPEngineer.Im;
-namespace Sharp.Xmpp.Extensions
+namespace XMPPEngineer.Extensions
{
internal class MultiUserChat : XmppExtension, IInputFilter, IInputFilter
{
@@ -169,10 +169,11 @@ public bool Input (Im.Presence stanza)
}
}
+ bool hasNoAvailability = string.IsNullOrWhiteSpace(stanza.Data["show"]?.InnerText);
if (person != null) {
- PrescenceChanged.Raise (this, new GroupPresenceEventArgs (person, statusCodeList));
- return true;
+ PrescenceChanged.Raise (this, new GroupPresenceEventArgs (person, new Jid(stanza.From.Domain, stanza.From.Node), statusCodeList));
+ return hasNoAvailability;
}
}
@@ -397,7 +398,7 @@ public void DeclineInvite(Invite invite, string reason)
public void EditRoomSubject(Jid room, string subject)
{
subject.ThrowIfNull("subject");
- Im.Message message = new Im.Message(room, null, subject, null, MessageType.Groupchat);
+ Im.Message message = new Im.Message(room, null, subject, null, null, MessageType.Groupchat);
SendMessage(message);
}
diff --git a/Extensions/XEP-0045/Occupant.cs b/Extensions/XEP-0045/Occupant.cs
index 5d68d7ed..a63c4152 100644
--- a/Extensions/XEP-0045/Occupant.cs
+++ b/Extensions/XEP-0045/Occupant.cs
@@ -4,7 +4,7 @@
using System.Text;
using System.Threading.Tasks;
-namespace Sharp.Xmpp.Extensions
+namespace XMPPEngineer.Extensions
{
///
/// Represents an participant in a group chat.
diff --git a/Extensions/XEP-0045/Role.cs b/Extensions/XEP-0045/Role.cs
index 1d3e4c6d..80f8e5b4 100644
--- a/Extensions/XEP-0045/Role.cs
+++ b/Extensions/XEP-0045/Role.cs
@@ -1,4 +1,4 @@
-namespace Sharp.Xmpp.Extensions
+namespace XMPPEngineer.Extensions
{
///
/// Describes the role of a participant in a group chat.
diff --git a/Extensions/XEP-0045/RoomAnonymity.cs b/Extensions/XEP-0045/RoomAnonymity.cs
index be6028a8..28317f6d 100644
--- a/Extensions/XEP-0045/RoomAnonymity.cs
+++ b/Extensions/XEP-0045/RoomAnonymity.cs
@@ -1,4 +1,4 @@
-namespace Sharp.Xmpp.Extensions
+namespace XMPPEngineer.Extensions
{
///
/// Describes whether a conference room occupant's full JID is visible
diff --git a/Extensions/XEP-0045/RoomInfoBasic.cs b/Extensions/XEP-0045/RoomInfoBasic.cs
index 9835be8b..b015968e 100644
--- a/Extensions/XEP-0045/RoomInfoBasic.cs
+++ b/Extensions/XEP-0045/RoomInfoBasic.cs
@@ -4,7 +4,7 @@
using System.Text;
using System.Threading.Tasks;
-namespace Sharp.Xmpp.Extensions
+namespace XMPPEngineer.Extensions
{
///
/// The most basic form of a chat room
diff --git a/Extensions/XEP-0045/RoomInfoExtended.cs b/Extensions/XEP-0045/RoomInfoExtended.cs
index 7e621722..30fd77e4 100644
--- a/Extensions/XEP-0045/RoomInfoExtended.cs
+++ b/Extensions/XEP-0045/RoomInfoExtended.cs
@@ -4,9 +4,9 @@
using System.Linq;
using System.Text;
using System.Threading.Tasks;
-using Sharp.Xmpp.Extensions.Dataforms;
+using XMPPEngineer.Extensions.Dataforms;
-namespace Sharp.Xmpp.Extensions
+namespace XMPPEngineer.Extensions
{
///
/// Room information provided upon inspection.
diff --git a/Extensions/XEP-0045/RoomModeration.cs b/Extensions/XEP-0045/RoomModeration.cs
index cd2c4228..70116975 100644
--- a/Extensions/XEP-0045/RoomModeration.cs
+++ b/Extensions/XEP-0045/RoomModeration.cs
@@ -1,4 +1,4 @@
-namespace Sharp.Xmpp.Extensions
+namespace XMPPEngineer.Extensions
{
///
/// Describes whether a conference room is moderated.
diff --git a/Extensions/XEP-0045/RoomPersistence.cs b/Extensions/XEP-0045/RoomPersistence.cs
index 6fa28274..7a206c47 100644
--- a/Extensions/XEP-0045/RoomPersistence.cs
+++ b/Extensions/XEP-0045/RoomPersistence.cs
@@ -1,4 +1,4 @@
-namespace Sharp.Xmpp.Extensions
+namespace XMPPEngineer.Extensions
{
///
/// Describes how long a conference room will exist for.
diff --git a/Extensions/XEP-0045/RoomPrivacy.cs b/Extensions/XEP-0045/RoomPrivacy.cs
index 374e64f7..ec9c01d6 100644
--- a/Extensions/XEP-0045/RoomPrivacy.cs
+++ b/Extensions/XEP-0045/RoomPrivacy.cs
@@ -1,4 +1,4 @@
-namespace Sharp.Xmpp.Extensions
+namespace XMPPEngineer.Extensions
{
///
/// Describes whether a conference room requires a membership to enter.
diff --git a/Extensions/XEP-0045/RoomProtection.cs b/Extensions/XEP-0045/RoomProtection.cs
index d84ce315..0b68d449 100644
--- a/Extensions/XEP-0045/RoomProtection.cs
+++ b/Extensions/XEP-0045/RoomProtection.cs
@@ -1,4 +1,4 @@
-namespace Sharp.Xmpp.Extensions
+namespace XMPPEngineer.Extensions
{
///
/// Describes whether a conference room is password protected.
diff --git a/Extensions/XEP-0045/RoomVisibility.cs b/Extensions/XEP-0045/RoomVisibility.cs
index 29169389..a9019f4c 100644
--- a/Extensions/XEP-0045/RoomVisibility.cs
+++ b/Extensions/XEP-0045/RoomVisibility.cs
@@ -1,4 +1,4 @@
-namespace Sharp.Xmpp.Extensions
+namespace XMPPEngineer.Extensions
{
///
/// Describes the visibility of a conference room.
diff --git a/Extensions/XEP-0047/InBandBytestreams.cs b/Extensions/XEP-0047/InBandBytestreams.cs
index 2b79ff48..b4c8ca79 100644
--- a/Extensions/XEP-0047/InBandBytestreams.cs
+++ b/Extensions/XEP-0047/InBandBytestreams.cs
@@ -1,10 +1,10 @@
-using Sharp.Xmpp.Core;
-using Sharp.Xmpp.Im;
+using XMPPEngineer.Core;
+using XMPPEngineer.Im;
using System;
using System.Collections.Generic;
using System.IO;
-namespace Sharp.Xmpp.Extensions
+namespace XMPPEngineer.Extensions
{
///
/// Implements the 'In-Band Bytestreams' extension as defined in XEP-0047.
diff --git a/Extensions/XEP-0065/IPAddressExtensions.cs b/Extensions/XEP-0065/IPAddressExtensions.cs
index 343f2346..01768ad3 100644
--- a/Extensions/XEP-0065/IPAddressExtensions.cs
+++ b/Extensions/XEP-0065/IPAddressExtensions.cs
@@ -1,7 +1,7 @@
using System;
using System.Net;
-namespace Sharp.Xmpp.Extensions
+namespace XMPPEngineer.Extensions
{
///
/// Contains extension methods for the IPAddress class.
diff --git a/Extensions/XEP-0065/Socks5/ATyp.cs b/Extensions/XEP-0065/Socks5/ATyp.cs
index 2282cca3..c530d63f 100644
--- a/Extensions/XEP-0065/Socks5/ATyp.cs
+++ b/Extensions/XEP-0065/Socks5/ATyp.cs
@@ -1,4 +1,4 @@
-namespace Sharp.Xmpp.Extensions.Socks5
+namespace XMPPEngineer.Extensions.Socks5
{
///
/// Defines possible values for the address type field.
diff --git a/Extensions/XEP-0065/Socks5/AuthMethod.cs b/Extensions/XEP-0065/Socks5/AuthMethod.cs
index 853017ad..ea95e7c0 100644
--- a/Extensions/XEP-0065/Socks5/AuthMethod.cs
+++ b/Extensions/XEP-0065/Socks5/AuthMethod.cs
@@ -1,4 +1,4 @@
-namespace Sharp.Xmpp.Extensions.Socks5
+namespace XMPPEngineer.Extensions.Socks5
{
///
/// Defines possible values for the different authentication methods
diff --git a/Extensions/XEP-0065/Socks5/AuthRequest.cs b/Extensions/XEP-0065/Socks5/AuthRequest.cs
index 3218608a..f7ba7df1 100644
--- a/Extensions/XEP-0065/Socks5/AuthRequest.cs
+++ b/Extensions/XEP-0065/Socks5/AuthRequest.cs
@@ -1,7 +1,7 @@
using System;
using System.Text;
-namespace Sharp.Xmpp.Extensions.Socks5
+namespace XMPPEngineer.Extensions.Socks5
{
///
/// Represents a SOCKS5 Username/Password auth-request message.
diff --git a/Extensions/XEP-0065/Socks5/AuthResponse.cs b/Extensions/XEP-0065/Socks5/AuthResponse.cs
index fc96f5cb..64250b72 100644
--- a/Extensions/XEP-0065/Socks5/AuthResponse.cs
+++ b/Extensions/XEP-0065/Socks5/AuthResponse.cs
@@ -2,7 +2,7 @@
using System.IO;
using System.Runtime.Serialization;
-namespace Sharp.Xmpp.Extensions.Socks5
+namespace XMPPEngineer.Extensions.Socks5
{
///
/// Represents a SOCKS5 Username/Password auth-response message.
diff --git a/Extensions/XEP-0065/Socks5/BinaryReader.cs b/Extensions/XEP-0065/Socks5/BinaryReader.cs
index 507d4b70..d64bd12b 100644
--- a/Extensions/XEP-0065/Socks5/BinaryReader.cs
+++ b/Extensions/XEP-0065/Socks5/BinaryReader.cs
@@ -1,6 +1,6 @@
using System.IO;
-namespace Sharp.Xmpp.Extensions.Socks5
+namespace XMPPEngineer.Extensions.Socks5
{
///
/// Adds extension methods to the BinaryReader class to simplify the
diff --git a/Extensions/XEP-0065/Socks5/ByteBuilder.cs b/Extensions/XEP-0065/Socks5/ByteBuilder.cs
index e6d0c796..d694e220 100644
--- a/Extensions/XEP-0065/Socks5/ByteBuilder.cs
+++ b/Extensions/XEP-0065/Socks5/ByteBuilder.cs
@@ -1,7 +1,7 @@
using System;
using System.Text;
-namespace Sharp.Xmpp.Extensions.Socks5
+namespace XMPPEngineer.Extensions.Socks5
{
///
/// A utility class modeled after the BCL StringBuilder to simplify
diff --git a/Extensions/XEP-0065/Socks5/ClientGreeting.cs b/Extensions/XEP-0065/Socks5/ClientGreeting.cs
index 984bd259..7864f0cd 100644
--- a/Extensions/XEP-0065/Socks5/ClientGreeting.cs
+++ b/Extensions/XEP-0065/Socks5/ClientGreeting.cs
@@ -3,7 +3,7 @@
using System.IO;
using System.Runtime.Serialization;
-namespace Sharp.Xmpp.Extensions.Socks5
+namespace XMPPEngineer.Extensions.Socks5
{
///
/// Represents a SOCKS5 client-greeting message.
diff --git a/Extensions/XEP-0065/Socks5/ReplyStatus.cs b/Extensions/XEP-0065/Socks5/ReplyStatus.cs
index 03115851..590b98ad 100644
--- a/Extensions/XEP-0065/Socks5/ReplyStatus.cs
+++ b/Extensions/XEP-0065/Socks5/ReplyStatus.cs
@@ -1,4 +1,4 @@
-namespace Sharp.Xmpp.Extensions.Socks5
+namespace XMPPEngineer.Extensions.Socks5
{
///
/// Defines possible values for the reply field of a SOCKS5 reply.
diff --git a/Extensions/XEP-0065/Socks5/ServerGreeting.cs b/Extensions/XEP-0065/Socks5/ServerGreeting.cs
index cc99e6b2..3a4179d2 100644
--- a/Extensions/XEP-0065/Socks5/ServerGreeting.cs
+++ b/Extensions/XEP-0065/Socks5/ServerGreeting.cs
@@ -2,7 +2,7 @@
using System.IO;
using System.Runtime.Serialization;
-namespace Sharp.Xmpp.Extensions.Socks5
+namespace XMPPEngineer.Extensions.Socks5
{
///
/// Represents a SOCKS5 server-greeting message.
diff --git a/Extensions/XEP-0065/Socks5/Socks5Client.cs b/Extensions/XEP-0065/Socks5/Socks5Client.cs
index 6296dcba..4ce0980b 100644
--- a/Extensions/XEP-0065/Socks5/Socks5Client.cs
+++ b/Extensions/XEP-0065/Socks5/Socks5Client.cs
@@ -5,7 +5,7 @@
using System.Net.Sockets;
using System.Text;
-namespace Sharp.Xmpp.Extensions.Socks5
+namespace XMPPEngineer.Extensions.Socks5
{
///
/// Provides client connections for SOCKS5 network services.
diff --git a/Extensions/XEP-0065/Socks5/Socks5Exception.cs b/Extensions/XEP-0065/Socks5/Socks5Exception.cs
index a36f1c06..fd6602ce 100644
--- a/Extensions/XEP-0065/Socks5/Socks5Exception.cs
+++ b/Extensions/XEP-0065/Socks5/Socks5Exception.cs
@@ -1,7 +1,7 @@
using System;
using System.Runtime.Serialization;
-namespace Sharp.Xmpp.Extensions.Socks5
+namespace XMPPEngineer.Extensions.Socks5
{
///
/// The exception that is thrown when a SOCKS5 error has been encountered.
diff --git a/Extensions/XEP-0065/Socks5/Socks5Server.cs b/Extensions/XEP-0065/Socks5/Socks5Server.cs
index a1d21f82..d0ce7584 100644
--- a/Extensions/XEP-0065/Socks5/Socks5Server.cs
+++ b/Extensions/XEP-0065/Socks5/Socks5Server.cs
@@ -5,7 +5,7 @@
using System.Net.Sockets;
using System.Text;
-namespace Sharp.Xmpp.Extensions.Socks5
+namespace XMPPEngineer.Extensions.Socks5
{
///
/// Listens for connections from SOCKS5 network clients.
diff --git a/Extensions/XEP-0065/Socks5/SocksCommand.cs b/Extensions/XEP-0065/Socks5/SocksCommand.cs
index 5d5c078f..8ea1e380 100644
--- a/Extensions/XEP-0065/Socks5/SocksCommand.cs
+++ b/Extensions/XEP-0065/Socks5/SocksCommand.cs
@@ -1,4 +1,4 @@
-namespace Sharp.Xmpp.Extensions.Socks5
+namespace XMPPEngineer.Extensions.Socks5
{
///
/// Defines possible values for the command field of a SOCKS5 request.
diff --git a/Extensions/XEP-0065/Socks5/SocksReply.cs b/Extensions/XEP-0065/Socks5/SocksReply.cs
index affa850e..29b3b0db 100644
--- a/Extensions/XEP-0065/Socks5/SocksReply.cs
+++ b/Extensions/XEP-0065/Socks5/SocksReply.cs
@@ -5,7 +5,7 @@
using System.Runtime.Serialization;
using System.Text;
-namespace Sharp.Xmpp.Extensions.Socks5
+namespace XMPPEngineer.Extensions.Socks5
{
///
/// Represents a SOCKS5 reply message.
diff --git a/Extensions/XEP-0065/Socks5/SocksRequest.cs b/Extensions/XEP-0065/Socks5/SocksRequest.cs
index 1fcf9b5f..9e14ce6f 100644
--- a/Extensions/XEP-0065/Socks5/SocksRequest.cs
+++ b/Extensions/XEP-0065/Socks5/SocksRequest.cs
@@ -5,7 +5,7 @@
using System.Runtime.Serialization;
using System.Text;
-namespace Sharp.Xmpp.Extensions.Socks5
+namespace XMPPEngineer.Extensions.Socks5
{
///
/// Represents a SOCKS5 request message.
diff --git a/Extensions/XEP-0065/Socks5/TcpListenerExtensions.cs b/Extensions/XEP-0065/Socks5/TcpListenerExtensions.cs
index 65b1e898..aadf05a8 100644
--- a/Extensions/XEP-0065/Socks5/TcpListenerExtensions.cs
+++ b/Extensions/XEP-0065/Socks5/TcpListenerExtensions.cs
@@ -1,7 +1,7 @@
using System;
using System.Net.Sockets;
-namespace Sharp.Xmpp.Extensions.Socks5
+namespace XMPPEngineer.Extensions.Socks5
{
///
/// Provides extension methods for the TcpListener class.
diff --git a/Extensions/XEP-0065/Socks5Bytestreams.cs b/Extensions/XEP-0065/Socks5Bytestreams.cs
index 6df39596..6333b2e6 100644
--- a/Extensions/XEP-0065/Socks5Bytestreams.cs
+++ b/Extensions/XEP-0065/Socks5Bytestreams.cs
@@ -1,7 +1,7 @@
-using Sharp.Xmpp.Core;
-using Sharp.Xmpp.Extensions.Socks5;
-using Sharp.Xmpp.Extensions.Stun;
-using Sharp.Xmpp.Im;
+using XMPPEngineer.Core;
+using XMPPEngineer.Extensions.Socks5;
+using XMPPEngineer.Extensions.Stun;
+using XMPPEngineer.Im;
using System;
using System.Collections.Generic;
using System.IO;
@@ -14,7 +14,7 @@
using System.Threading.Tasks;
using System.Xml;
-namespace Sharp.Xmpp.Extensions
+namespace XMPPEngineer.Extensions
{
///
/// Implements the 'SOCKS5 Bytestreams' extension as defined in XEP-0065.
diff --git a/Extensions/XEP-0065/Streamhost.cs b/Extensions/XEP-0065/Streamhost.cs
index 1c83e610..14a9f969 100644
--- a/Extensions/XEP-0065/Streamhost.cs
+++ b/Extensions/XEP-0065/Streamhost.cs
@@ -1,6 +1,6 @@
using System;
-namespace Sharp.Xmpp.Extensions
+namespace XMPPEngineer.Extensions
{
///
/// Represents a streamhost entry as is used during S5B negotiation.
diff --git a/Extensions/XEP-0065/Stun/BindingRequest.cs b/Extensions/XEP-0065/Stun/BindingRequest.cs
index 04cee379..fc55da87 100644
--- a/Extensions/XEP-0065/Stun/BindingRequest.cs
+++ b/Extensions/XEP-0065/Stun/BindingRequest.cs
@@ -1,8 +1,8 @@
-using Sharp.Xmpp.Extensions.Socks5;
+using XMPPEngineer.Extensions.Socks5;
using System;
using System.Security.Cryptography;
-namespace Sharp.Xmpp.Extensions.Stun
+namespace XMPPEngineer.Extensions.Stun
{
///
/// Represents a STUN 'Binding Request' message.
diff --git a/Extensions/XEP-0065/Stun/BindingResponse.cs b/Extensions/XEP-0065/Stun/BindingResponse.cs
index a584d89b..6f28f2c3 100644
--- a/Extensions/XEP-0065/Stun/BindingResponse.cs
+++ b/Extensions/XEP-0065/Stun/BindingResponse.cs
@@ -1,11 +1,11 @@
-using Sharp.Xmpp.Extensions.Socks5;
+using XMPPEngineer.Extensions.Socks5;
using System;
using System.IO;
using System.Linq;
using System.Net;
using System.Runtime.Serialization;
-namespace Sharp.Xmpp.Extensions.Stun
+namespace XMPPEngineer.Extensions.Stun
{
///
/// Represents a STUN 'Binding Response' message.
diff --git a/Extensions/XEP-0065/Stun/StunClient.cs b/Extensions/XEP-0065/Stun/StunClient.cs
index b2299c36..408ea796 100644
--- a/Extensions/XEP-0065/Stun/StunClient.cs
+++ b/Extensions/XEP-0065/Stun/StunClient.cs
@@ -4,7 +4,7 @@
using System.Net.Sockets;
using System.Runtime.Serialization;
-namespace Sharp.Xmpp.Extensions.Stun
+namespace XMPPEngineer.Extensions.Stun
{
///
/// Implements a rudimentary STUN client for allowing an end host to discover
diff --git a/Extensions/XEP-0065/UPnP/DeviceFinderCallback.cs b/Extensions/XEP-0065/UPnP/DeviceFinderCallback.cs
index 9df83d30..dbdbcb7c 100644
--- a/Extensions/XEP-0065/UPnP/DeviceFinderCallback.cs
+++ b/Extensions/XEP-0065/UPnP/DeviceFinderCallback.cs
@@ -2,7 +2,7 @@
using UPNPLib;
#endif
-namespace Sharp.Xmpp.Extensions.Upnp
+namespace XMPPEngineer.Extensions.Upnp
{
#if WINDOWSPLATFORM
///
diff --git a/Extensions/XEP-0065/UPnP/UPnP.cs b/Extensions/XEP-0065/UPnP/UPnP.cs
index 44a08548..bb234d10 100644
--- a/Extensions/XEP-0065/UPnP/UPnP.cs
+++ b/Extensions/XEP-0065/UPnP/UPnP.cs
@@ -2,7 +2,7 @@
using UPNPLib;
#endif
-namespace Sharp.Xmpp.Extensions.Upnp
+namespace XMPPEngineer.Extensions.Upnp
{
#if WINDOWSPLATFORM
diff --git a/Extensions/XEP-0077/InBandRegistration.cs b/Extensions/XEP-0077/InBandRegistration.cs
index cb0519a9..3cc6a309 100644
--- a/Extensions/XEP-0077/InBandRegistration.cs
+++ b/Extensions/XEP-0077/InBandRegistration.cs
@@ -1,12 +1,12 @@
-using Sharp.Xmpp.Core;
-using Sharp.Xmpp.Extensions.Dataforms;
-using Sharp.Xmpp.Im;
+using XMPPEngineer.Core;
+using XMPPEngineer.Extensions.Dataforms;
+using XMPPEngineer.Im;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Xml;
-namespace Sharp.Xmpp.Extensions
+namespace XMPPEngineer.Extensions
{
///
/// Implements the 'In-Band Registration' extension as defined in XEP-0077.
diff --git a/Extensions/XEP-0077/RegistrationCallback.cs b/Extensions/XEP-0077/RegistrationCallback.cs
index 833cef48..677debd5 100644
--- a/Extensions/XEP-0077/RegistrationCallback.cs
+++ b/Extensions/XEP-0077/RegistrationCallback.cs
@@ -1,6 +1,6 @@
-using Sharp.Xmpp.Extensions.Dataforms;
+using XMPPEngineer.Extensions.Dataforms;
-namespace Sharp.Xmpp.Extensions
+namespace XMPPEngineer.Extensions
{
///
/// A callback method which is invoked during the registration process to
diff --git a/Extensions/XEP-0084/AvatarChangedEventArgs.cs b/Extensions/XEP-0084/AvatarChangedEventArgs.cs
index d26489cb..e0210a1a 100644
--- a/Extensions/XEP-0084/AvatarChangedEventArgs.cs
+++ b/Extensions/XEP-0084/AvatarChangedEventArgs.cs
@@ -4,7 +4,7 @@
using System.Drawing;
#endif
-namespace Sharp.Xmpp.Extensions
+namespace XMPPEngineer.Extensions
{
///
/// Provides data for the AvatarChanged event.
diff --git a/Extensions/XEP-0084/UserAvatar.cs b/Extensions/XEP-0084/UserAvatar.cs
index 14bcef93..c12ed610 100644
--- a/Extensions/XEP-0084/UserAvatar.cs
+++ b/Extensions/XEP-0084/UserAvatar.cs
@@ -3,7 +3,7 @@
using System.Drawing.Imaging;
#endif
-namespace Sharp.Xmpp.Extensions
+namespace XMPPEngineer.Extensions
{
#if WINDOWSPLATFORM
diff --git a/Extensions/XEP-0085/ChatState.cs b/Extensions/XEP-0085/ChatState.cs
index e23a5e34..db277d0d 100644
--- a/Extensions/XEP-0085/ChatState.cs
+++ b/Extensions/XEP-0085/ChatState.cs
@@ -1,4 +1,4 @@
-namespace Sharp.Xmpp.Extensions
+namespace XMPPEngineer.Extensions
{
///
/// Defines possible values for the chat state of an XMPP user.
diff --git a/Extensions/XEP-0085/ChatStateChangedEventArgs.cs b/Extensions/XEP-0085/ChatStateChangedEventArgs.cs
index 778a483f..6ed9b96b 100644
--- a/Extensions/XEP-0085/ChatStateChangedEventArgs.cs
+++ b/Extensions/XEP-0085/ChatStateChangedEventArgs.cs
@@ -1,6 +1,6 @@
using System;
-namespace Sharp.Xmpp.Extensions
+namespace XMPPEngineer.Extensions
{
///
/// Provides data for the ChatStateChanged event.
diff --git a/Extensions/XEP-0085/ChatStateNotifications.cs b/Extensions/XEP-0085/ChatStateNotifications.cs
index c74adb42..49f9faa3 100644
--- a/Extensions/XEP-0085/ChatStateNotifications.cs
+++ b/Extensions/XEP-0085/ChatStateNotifications.cs
@@ -1,8 +1,8 @@
-using Sharp.Xmpp.Im;
+using XMPPEngineer.Im;
using System;
using System.Collections.Generic;
-namespace Sharp.Xmpp.Extensions
+namespace XMPPEngineer.Extensions
{
///
/// Implements the 'Chat States Notifications' extension as defined in XEP-0085.
diff --git a/Extensions/XEP-0092/SoftwareVersion.cs b/Extensions/XEP-0092/SoftwareVersion.cs
index 27dc603d..d8951c5c 100644
--- a/Extensions/XEP-0092/SoftwareVersion.cs
+++ b/Extensions/XEP-0092/SoftwareVersion.cs
@@ -1,10 +1,10 @@
-using Sharp.Xmpp.Core;
-using Sharp.Xmpp.Im;
+using XMPPEngineer.Core;
+using XMPPEngineer.Im;
using System;
using System.Collections.Generic;
using System.Reflection;
-namespace Sharp.Xmpp.Extensions
+namespace XMPPEngineer.Extensions
{
///
/// Implements the 'Software Version' extension as defined in XEP-0092.
@@ -134,7 +134,7 @@ public SoftwareVersion(XmppIm im)
Attribute attr = Assembly.GetExecutingAssembly().
GetCustomAttribute(typeof(AssemblyProductAttribute));
string name = attr != null ? ((AssemblyProductAttribute)attr).Product :
- "Sharp.Xmpp";
+ "XMPPEngineer";
string version = Assembly.GetExecutingAssembly().GetName().
Version.ToString();
Version = new VersionInformation(name, version,
diff --git a/Extensions/XEP-0092/VersionInformation.cs b/Extensions/XEP-0092/VersionInformation.cs
index d04d3aa2..c6f4766c 100644
--- a/Extensions/XEP-0092/VersionInformation.cs
+++ b/Extensions/XEP-0092/VersionInformation.cs
@@ -1,6 +1,6 @@
using System;
-namespace Sharp.Xmpp.Extensions
+namespace XMPPEngineer.Extensions
{
///
/// Provides information about the software application associated with an
diff --git a/Extensions/XEP-0095/InitiationResult.cs b/Extensions/XEP-0095/InitiationResult.cs
index 9478d272..3aef9d02 100644
--- a/Extensions/XEP-0095/InitiationResult.cs
+++ b/Extensions/XEP-0095/InitiationResult.cs
@@ -1,7 +1,7 @@
using System;
using System.Xml;
-namespace Sharp.Xmpp.Extensions
+namespace XMPPEngineer.Extensions
{
///
/// Represents the result of a stream initiation.
diff --git a/Extensions/XEP-0095/StreamInitiation.cs b/Extensions/XEP-0095/StreamInitiation.cs
index 2bfe9d60..911fffa7 100644
--- a/Extensions/XEP-0095/StreamInitiation.cs
+++ b/Extensions/XEP-0095/StreamInitiation.cs
@@ -1,12 +1,12 @@
-using Sharp.Xmpp.Core;
-using Sharp.Xmpp.Extensions.Dataforms;
-using Sharp.Xmpp.Im;
+using XMPPEngineer.Core;
+using XMPPEngineer.Extensions.Dataforms;
+using XMPPEngineer.Im;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Xml;
-namespace Sharp.Xmpp.Extensions
+namespace XMPPEngineer.Extensions
{
///
/// Implements the 'Stream Initiation' extension as defined in XEP-0095.
diff --git a/Extensions/XEP-0096/BytesTransferredEventArgs.cs b/Extensions/XEP-0096/BytesTransferredEventArgs.cs
index 41b35ff8..1d04dfb2 100644
--- a/Extensions/XEP-0096/BytesTransferredEventArgs.cs
+++ b/Extensions/XEP-0096/BytesTransferredEventArgs.cs
@@ -1,6 +1,6 @@
using System;
-namespace Sharp.Xmpp.Extensions
+namespace XMPPEngineer.Extensions
{
///
/// Provides data for the 'BytesTransferred' event which is raised by
diff --git a/Extensions/XEP-0096/FileMetaData.cs b/Extensions/XEP-0096/FileMetaData.cs
index 5ce742c8..18a12871 100644
--- a/Extensions/XEP-0096/FileMetaData.cs
+++ b/Extensions/XEP-0096/FileMetaData.cs
@@ -1,6 +1,6 @@
using System;
-namespace Sharp.Xmpp.Extensions
+namespace XMPPEngineer.Extensions
{
///
/// Represents meta-data of a file.
diff --git a/Extensions/XEP-0096/FileTransfer.cs b/Extensions/XEP-0096/FileTransfer.cs
index 70fb87c4..99d24de9 100644
--- a/Extensions/XEP-0096/FileTransfer.cs
+++ b/Extensions/XEP-0096/FileTransfer.cs
@@ -1,6 +1,6 @@
using System;
-namespace Sharp.Xmpp.Extensions
+namespace XMPPEngineer.Extensions
{
///
/// Represents an on-going file-transfer operation.
diff --git a/Extensions/XEP-0096/FileTransferAbortedEventArgs.cs b/Extensions/XEP-0096/FileTransferAbortedEventArgs.cs
index 1828c7b9..c91794f7 100644
--- a/Extensions/XEP-0096/FileTransferAbortedEventArgs.cs
+++ b/Extensions/XEP-0096/FileTransferAbortedEventArgs.cs
@@ -1,6 +1,6 @@
using System;
-namespace Sharp.Xmpp.Extensions
+namespace XMPPEngineer.Extensions
{
///
/// Provides data for the 'FileTransferAborted' event.
diff --git a/Extensions/XEP-0096/FileTransferProgressEventArgs.cs b/Extensions/XEP-0096/FileTransferProgressEventArgs.cs
index 3248d133..7da8562a 100644
--- a/Extensions/XEP-0096/FileTransferProgressEventArgs.cs
+++ b/Extensions/XEP-0096/FileTransferProgressEventArgs.cs
@@ -1,6 +1,6 @@
using System;
-namespace Sharp.Xmpp.Extensions
+namespace XMPPEngineer.Extensions
{
///
/// Provides data for the 'FileTransferProgress' event.
diff --git a/Extensions/XEP-0096/FileTransferRequest.cs b/Extensions/XEP-0096/FileTransferRequest.cs
index e07f02b0..5b6b3d56 100644
--- a/Extensions/XEP-0096/FileTransferRequest.cs
+++ b/Extensions/XEP-0096/FileTransferRequest.cs
@@ -1,4 +1,4 @@
-namespace Sharp.Xmpp.Extensions
+namespace XMPPEngineer.Extensions
{
///
/// Represents a request for a file-transfer.
diff --git a/Extensions/XEP-0096/IDataStream.cs b/Extensions/XEP-0096/IDataStream.cs
index 901149c9..75a8fc9e 100644
--- a/Extensions/XEP-0096/IDataStream.cs
+++ b/Extensions/XEP-0096/IDataStream.cs
@@ -1,6 +1,6 @@
using System;
-namespace Sharp.Xmpp.Extensions
+namespace XMPPEngineer.Extensions
{
///
/// Represents an XMPP extension that implements a data-stream for transferring
diff --git a/Extensions/XEP-0096/SIFileTransfer.cs b/Extensions/XEP-0096/SIFileTransfer.cs
index d1fb9805..f11b1a6a 100644
--- a/Extensions/XEP-0096/SIFileTransfer.cs
+++ b/Extensions/XEP-0096/SIFileTransfer.cs
@@ -1,6 +1,6 @@
-using Sharp.Xmpp.Core;
-using Sharp.Xmpp.Extensions.Dataforms;
-using Sharp.Xmpp.Im;
+using XMPPEngineer.Core;
+using XMPPEngineer.Extensions.Dataforms;
+using XMPPEngineer.Im;
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
@@ -8,7 +8,7 @@
using System.Linq;
using System.Xml;
-namespace Sharp.Xmpp.Extensions
+namespace XMPPEngineer.Extensions
{
///
/// Implements the 'SI File Transfer' extension as defined in XEP-0096.
diff --git a/Extensions/XEP-0096/SISession.cs b/Extensions/XEP-0096/SISession.cs
index 311ccdc8..3d22e223 100644
--- a/Extensions/XEP-0096/SISession.cs
+++ b/Extensions/XEP-0096/SISession.cs
@@ -1,7 +1,7 @@
using System;
using System.IO;
-namespace Sharp.Xmpp.Extensions
+namespace XMPPEngineer.Extensions
{
///
/// Represents an SI session as is negotiated during stream initiation.
diff --git a/Extensions/XEP-0096/TransferAbortedEventArgs.cs b/Extensions/XEP-0096/TransferAbortedEventArgs.cs
index e47c22a1..6e486ab8 100644
--- a/Extensions/XEP-0096/TransferAbortedEventArgs.cs
+++ b/Extensions/XEP-0096/TransferAbortedEventArgs.cs
@@ -1,6 +1,6 @@
using System;
-namespace Sharp.Xmpp.Extensions
+namespace XMPPEngineer.Extensions
{
///
/// Provides data for the 'TransferAborted' event which is raised by
diff --git a/Extensions/XEP-0107/Mood.cs b/Extensions/XEP-0107/Mood.cs
index 6de0f4ca..5f8edf7f 100644
--- a/Extensions/XEP-0107/Mood.cs
+++ b/Extensions/XEP-0107/Mood.cs
@@ -1,4 +1,4 @@
-namespace Sharp.Xmpp.Extensions
+namespace XMPPEngineer.Extensions
{
///
/// Defines possible values for the mood of an XMPP user.
diff --git a/Extensions/XEP-0107/MoodChangedEventArgs.cs b/Extensions/XEP-0107/MoodChangedEventArgs.cs
index 47bbc6f4..4ece0664 100644
--- a/Extensions/XEP-0107/MoodChangedEventArgs.cs
+++ b/Extensions/XEP-0107/MoodChangedEventArgs.cs
@@ -1,6 +1,6 @@
using System;
-namespace Sharp.Xmpp.Extensions
+namespace XMPPEngineer.Extensions
{
///
/// Provides data for the MoodChanged event.
diff --git a/Extensions/XEP-0107/UserMood.cs b/Extensions/XEP-0107/UserMood.cs
index 494c6200..183bd869 100644
--- a/Extensions/XEP-0107/UserMood.cs
+++ b/Extensions/XEP-0107/UserMood.cs
@@ -1,10 +1,10 @@
-using Sharp.Xmpp.Im;
+using XMPPEngineer.Im;
using System;
using System.Collections.Generic;
using System.Text;
using System.Xml;
-namespace Sharp.Xmpp.Extensions
+namespace XMPPEngineer.Extensions
{
///
/// Implements the 'User Mood' extension as defined in XEP-0107.
diff --git a/Extensions/XEP-0108/ActivityChangedEventArgs.cs b/Extensions/XEP-0108/ActivityChangedEventArgs.cs
index b25b8dca..9fe02c7b 100644
--- a/Extensions/XEP-0108/ActivityChangedEventArgs.cs
+++ b/Extensions/XEP-0108/ActivityChangedEventArgs.cs
@@ -1,6 +1,6 @@
using System;
-namespace Sharp.Xmpp.Extensions
+namespace XMPPEngineer.Extensions
{
///
/// Provides data for the ActivityChanged event.
diff --git a/Extensions/XEP-0108/GeneralActivity.cs b/Extensions/XEP-0108/GeneralActivity.cs
index b18d29bb..dfe7975c 100644
--- a/Extensions/XEP-0108/GeneralActivity.cs
+++ b/Extensions/XEP-0108/GeneralActivity.cs
@@ -1,4 +1,4 @@
-namespace Sharp.Xmpp.Extensions
+namespace XMPPEngineer.Extensions
{
///
/// Defines possible values for the general activity of an XMPP user.
diff --git a/Extensions/XEP-0108/SpecificActivity.cs b/Extensions/XEP-0108/SpecificActivity.cs
index 2c55b87f..67462c70 100644
--- a/Extensions/XEP-0108/SpecificActivity.cs
+++ b/Extensions/XEP-0108/SpecificActivity.cs
@@ -1,4 +1,4 @@
-namespace Sharp.Xmpp.Extensions
+namespace XMPPEngineer.Extensions
{
///
/// Defines possible values for more specific activities of an XMPP user.
diff --git a/Extensions/XEP-0108/UserActivity.cs b/Extensions/XEP-0108/UserActivity.cs
index 1727dde4..0f4d51a5 100644
--- a/Extensions/XEP-0108/UserActivity.cs
+++ b/Extensions/XEP-0108/UserActivity.cs
@@ -1,10 +1,10 @@
-using Sharp.Xmpp.Im;
+using XMPPEngineer.Im;
using System;
using System.Collections.Generic;
using System.Text;
using System.Xml;
-namespace Sharp.Xmpp.Extensions
+namespace XMPPEngineer.Extensions
{
///
/// Implements the 'User Activity' extension as defined in XEP-0108.
diff --git a/Extensions/XEP-0115/EntityCapabilities.cs b/Extensions/XEP-0115/EntityCapabilities.cs
index c883ceb7..319e3401 100644
--- a/Extensions/XEP-0115/EntityCapabilities.cs
+++ b/Extensions/XEP-0115/EntityCapabilities.cs
@@ -1,11 +1,11 @@
-using Sharp.Xmpp.Im;
+using XMPPEngineer.Im;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Security.Cryptography;
using System.Text;
-namespace Sharp.Xmpp.Extensions
+namespace XMPPEngineer.Extensions
{
///
/// Implements the 'Entity Capabilities' extension as defined in XEP-0092.
@@ -38,7 +38,7 @@ private string nodeUri
get
{
// FIXME: Move this to a resource file or to assembly metadata?
- return "Sharp.Xmpp";
+ return "XMPPEngineer";
}
}
diff --git a/Extensions/XEP-0118/TuneEventArgs.cs b/Extensions/XEP-0118/TuneEventArgs.cs
index 539aac7d..9def76ab 100644
--- a/Extensions/XEP-0118/TuneEventArgs.cs
+++ b/Extensions/XEP-0118/TuneEventArgs.cs
@@ -1,6 +1,6 @@
using System;
-namespace Sharp.Xmpp.Extensions
+namespace XMPPEngineer.Extensions
{
///
/// Provides data for the Tune event.
diff --git a/Extensions/XEP-0118/TuneInformation.cs b/Extensions/XEP-0118/TuneInformation.cs
index 1f4ae16d..7a08dbef 100644
--- a/Extensions/XEP-0118/TuneInformation.cs
+++ b/Extensions/XEP-0118/TuneInformation.cs
@@ -1,6 +1,6 @@
using System;
-namespace Sharp.Xmpp.Extensions
+namespace XMPPEngineer.Extensions
{
///
/// Provides information about the music to which a user is listening.
diff --git a/Extensions/XEP-0118/UserTune.cs b/Extensions/XEP-0118/UserTune.cs
index 840d79b8..2cffd631 100644
--- a/Extensions/XEP-0118/UserTune.cs
+++ b/Extensions/XEP-0118/UserTune.cs
@@ -1,9 +1,9 @@
-using Sharp.Xmpp.Im;
+using XMPPEngineer.Im;
using System;
using System.Collections.Generic;
using System.Xml;
-namespace Sharp.Xmpp.Extensions
+namespace XMPPEngineer.Extensions
{
///
/// Implements the 'User Tune' extension as defined in XEP-0118.
diff --git a/Extensions/XEP-0153/vCardAvatars.cs b/Extensions/XEP-0153/vCardAvatars.cs
index d0c95261..4e16ac32 100644
--- a/Extensions/XEP-0153/vCardAvatars.cs
+++ b/Extensions/XEP-0153/vCardAvatars.cs
@@ -1,5 +1,5 @@
-using Sharp.Xmpp.Core;
-using Sharp.Xmpp.Im;
+using XMPPEngineer.Core;
+using XMPPEngineer.Im;
using System;
using System.Collections.Generic;
using System.IO;
@@ -8,7 +8,7 @@
using System.Xml;
using System.Xml.Linq;
-namespace Sharp.Xmpp.Extensions
+namespace XMPPEngineer.Extensions
{
///
/// Implements the 'vCard based Avatars' extension as defined in XEP-0153.
@@ -103,7 +103,7 @@ public void SetAvatar(Stream stream)
if (iq.Type == IqType.Result)
{
// Result must contain a 'feature' element.
- im.SendPresence(new Sharp.Xmpp.Im.Presence(null, null, PresenceType.Available, null, null, Xml.Element("x", "vcard-temp:x:update").Child(Xml.Element("photo").Text(hash))));
+ im.SendPresence(new XMPPEngineer.Im.Presence(null, null, PresenceType.Available, null, null, Xml.Element("x", "vcard-temp:x:update").Child(Xml.Element("photo").Text(hash))));
}
});
}
diff --git a/Extensions/XEP-0163/Pep.cs b/Extensions/XEP-0163/Pep.cs
index 9639da32..e3404472 100644
--- a/Extensions/XEP-0163/Pep.cs
+++ b/Extensions/XEP-0163/Pep.cs
@@ -1,10 +1,10 @@
-using Sharp.Xmpp.Core;
-using Sharp.Xmpp.Im;
+using XMPPEngineer.Core;
+using XMPPEngineer.Im;
using System;
using System.Collections.Generic;
using System.Xml;
-namespace Sharp.Xmpp.Extensions
+namespace XMPPEngineer.Extensions
{
///
/// Implements the 'Personal Eventing Protocol' extension as defined in XEP-0163.
diff --git a/Extensions/XEP-0191/BlockingCommand.cs b/Extensions/XEP-0191/BlockingCommand.cs
index 0ec8d3b1..586effb6 100644
--- a/Extensions/XEP-0191/BlockingCommand.cs
+++ b/Extensions/XEP-0191/BlockingCommand.cs
@@ -1,10 +1,10 @@
-using Sharp.Xmpp.Core;
-using Sharp.Xmpp.Im;
+using XMPPEngineer.Core;
+using XMPPEngineer.Im;
using System;
using System.Collections.Generic;
using System.Xml;
-namespace Sharp.Xmpp.Extensions
+namespace XMPPEngineer.Extensions
{
///
/// Implements the 'Blocking Command' extension as defined in XEP-0191.
diff --git a/Extensions/XEP-0199/Ping.cs b/Extensions/XEP-0199/Ping.cs
index 3911d5dc..108a7f61 100644
--- a/Extensions/XEP-0199/Ping.cs
+++ b/Extensions/XEP-0199/Ping.cs
@@ -1,9 +1,9 @@
-using Sharp.Xmpp.Core;
-using Sharp.Xmpp.Im;
+using XMPPEngineer.Core;
+using XMPPEngineer.Im;
using System;
using System.Collections.Generic;
-namespace Sharp.Xmpp.Extensions
+namespace XMPPEngineer.Extensions
{
///
/// Implements the 'Ping' extension as defined in XEP-0199.
diff --git a/Extensions/XEP-0202/EntityTime.cs b/Extensions/XEP-0202/EntityTime.cs
index 9a2050cd..404c1190 100644
--- a/Extensions/XEP-0202/EntityTime.cs
+++ b/Extensions/XEP-0202/EntityTime.cs
@@ -1,9 +1,9 @@
-using Sharp.Xmpp.Core;
-using Sharp.Xmpp.Im;
+using XMPPEngineer.Core;
+using XMPPEngineer.Im;
using System;
using System.Collections.Generic;
-namespace Sharp.Xmpp.Extensions
+namespace XMPPEngineer.Extensions
{
///
/// Implements the 'Entity Time' extension as defined in XEP-0202.
diff --git a/Extensions/XEP-0224/Attention.cs b/Extensions/XEP-0224/Attention.cs
index e333040f..a04c0308 100644
--- a/Extensions/XEP-0224/Attention.cs
+++ b/Extensions/XEP-0224/Attention.cs
@@ -1,8 +1,8 @@
-using Sharp.Xmpp.Im;
+using XMPPEngineer.Im;
using System;
using System.Collections.Generic;
-namespace Sharp.Xmpp.Extensions
+namespace XMPPEngineer.Extensions
{
///
/// Implements the 'Attention' extension as defined in XEP-0224.
diff --git a/Extensions/XEP-0231/BitsOfBinary.cs b/Extensions/XEP-0231/BitsOfBinary.cs
index b3c51ec8..d22f57ee 100644
--- a/Extensions/XEP-0231/BitsOfBinary.cs
+++ b/Extensions/XEP-0231/BitsOfBinary.cs
@@ -1,9 +1,9 @@
-using Sharp.Xmpp.Core;
-using Sharp.Xmpp.Im;
+using XMPPEngineer.Core;
+using XMPPEngineer.Im;
using System;
using System.Collections.Generic;
-namespace Sharp.Xmpp.Extensions
+namespace XMPPEngineer.Extensions
{
///
/// Implements the 'Bits of Binary' extension as defined in XEP-0231.
diff --git a/Extensions/XEP-0231/BobData.cs b/Extensions/XEP-0231/BobData.cs
index 0e93a06a..ab8150bb 100644
--- a/Extensions/XEP-0231/BobData.cs
+++ b/Extensions/XEP-0231/BobData.cs
@@ -3,7 +3,7 @@
using System.Text;
using System.Xml;
-namespace Sharp.Xmpp.Extensions
+namespace XMPPEngineer.Extensions
{
///
/// Represents a piece of binary data in the context of the 'Bits of Binary'
diff --git a/Extensions/XEP-0279/ServerIpCheck.cs b/Extensions/XEP-0279/ServerIpCheck.cs
index c542791d..0f1b976b 100644
--- a/Extensions/XEP-0279/ServerIpCheck.cs
+++ b/Extensions/XEP-0279/ServerIpCheck.cs
@@ -1,10 +1,10 @@
-using Sharp.Xmpp.Core;
-using Sharp.Xmpp.Im;
+using XMPPEngineer.Core;
+using XMPPEngineer.Im;
using System;
using System.Collections.Generic;
using System.Net;
-namespace Sharp.Xmpp.Extensions
+namespace XMPPEngineer.Extensions
{
///
/// Implements the 'Server IP Check' extension as defined in XEP-0279.
diff --git a/Extensions/XEP-0280/MessageCarbons.cs b/Extensions/XEP-0280/MessageCarbons.cs
index 3f5f958a..b7dad301 100644
--- a/Extensions/XEP-0280/MessageCarbons.cs
+++ b/Extensions/XEP-0280/MessageCarbons.cs
@@ -1,9 +1,9 @@
-using Sharp.Xmpp.Core;
-using Sharp.Xmpp.Im;
+using XMPPEngineer.Core;
+using XMPPEngineer.Im;
using System;
using System.Collections.Generic;
-namespace Sharp.Xmpp.Extensions
+namespace XMPPEngineer.Extensions
{
internal class MessageCarbons : XmppExtension
{
diff --git a/Extensions/XmppExtension.cs b/Extensions/XmppExtension.cs
index b35faae6..b5d010de 100644
--- a/Extensions/XmppExtension.cs
+++ b/Extensions/XmppExtension.cs
@@ -1,7 +1,7 @@
-using Sharp.Xmpp.Im;
+using XMPPEngineer.Im;
using System.Collections.Generic;
-namespace Sharp.Xmpp.Extensions
+namespace XMPPEngineer.Extensions
{
///
/// The base class from which all implementations of XMPP extensions must
diff --git a/Extensions/vCardAvatars.cs b/Extensions/vCardAvatars.cs
index 3fcc4700..c0ec3f48 100644
--- a/Extensions/vCardAvatars.cs
+++ b/Extensions/vCardAvatars.cs
@@ -1,5 +1,7 @@
-using S22.Xmpp.Core;
-using S22.Xmpp.Im;
+using XMPPEngineer;
+using XMPPEngineer.Core;
+using XMPPEngineer.Im;
+using XMPPEngineer.Extensions;
using System;
using System.Collections.Generic;
using System.IO;
@@ -99,7 +101,7 @@ public void SetAvatar(Stream stream)
if (iq.Type == IqType.Result) {
// Result must contain a 'feature' element.
- im.SendPresence(new S22.Xmpp.Im.Presence(null, null, PresenceType.Available, null, null, Xml.Element("x", "vcard-temp:x:update").Child(Xml.Element("photo").Text(hash))));
+ im.SendPresence(new XMPPEngineer.Im.Presence(null, null, PresenceType.Available, null, null, Xml.Element("x", "vcard-temp:x:update").Child(Xml.Element("photo").Text(hash))));
}
});
diff --git a/Im/Availability.cs b/Im/Availability.cs
index 2b981301..7510c797 100644
--- a/Im/Availability.cs
+++ b/Im/Availability.cs
@@ -1,4 +1,4 @@
-namespace Sharp.Xmpp.Im
+namespace XMPPEngineer.Im
{
///
/// Defines the possible values for a user's availability status.
diff --git a/Im/ErrorEventArgs.cs b/Im/ErrorEventArgs.cs
index dfe5b76a..8350e792 100644
--- a/Im/ErrorEventArgs.cs
+++ b/Im/ErrorEventArgs.cs
@@ -1,6 +1,6 @@
using System;
-namespace Sharp.Xmpp.Im
+namespace XMPPEngineer.Im
{
///
/// Provides data for the Error event.
diff --git a/Im/GroupPrivacyRule.cs b/Im/GroupPrivacyRule.cs
index e525e759..49d7da33 100644
--- a/Im/GroupPrivacyRule.cs
+++ b/Im/GroupPrivacyRule.cs
@@ -1,6 +1,6 @@
using System;
-namespace Sharp.Xmpp.Im
+namespace XMPPEngineer.Im
{
///
/// Represents a privacy rule pertaining to a group.
diff --git a/Im/JidPrivacyRule.cs b/Im/JidPrivacyRule.cs
index d0ffcfcc..9c631364 100644
--- a/Im/JidPrivacyRule.cs
+++ b/Im/JidPrivacyRule.cs
@@ -1,6 +1,6 @@
using System;
-namespace Sharp.Xmpp.Im
+namespace XMPPEngineer.Im
{
///
/// Represents a privacy rule pertaining to a JID.
diff --git a/Im/Message.cs b/Im/Message.cs
index b4ea7232..59ca8ac1 100644
--- a/Im/Message.cs
+++ b/Im/Message.cs
@@ -2,15 +2,18 @@
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
+using System.Text;
using System.Xml;
-namespace Sharp.Xmpp.Im
+namespace XMPPEngineer.Im
{
///
/// Represents a Message stanza as defined in XMPP:IM.
///
public class Message : Core.Message
{
+ private List addresses;
+
///
/// The type of the message stanza.
///
@@ -152,6 +155,71 @@ public string Body
}
}
+ ///
+ /// The addresses of the message.
+ ///
+ public List Addresses
+ {
+ get
+ {
+ XmlElement bare = GetBare("addresses");
+ if (bare != null)
+ {
+ if (addresses == null)
+ {
+ addresses = new List();
+
+ foreach (XmlElement child in bare.ChildNodes)
+ {
+ string v = child.GetAttributeNode("jid").Value;
+ if (!String.IsNullOrWhiteSpace(v))
+ addresses.Add(new Jid(v));
+ }
+ }
+ }
+
+ return addresses;
+ }
+
+ set
+ {
+ XmlElement bare = GetBare("addresses");
+ if (bare != null)
+ {
+ if (value == null)
+ element.RemoveChild(bare);
+ else
+ {
+ StringBuilder sb = new StringBuilder();
+ foreach (Jid jid in value)
+ {
+ sb.Append(jid.ToString());
+ }
+ bare.InnerXml = sb.ToString();
+ //bare.InnerText = value;
+ }
+
+ }
+ else
+ {
+ if (value != null)
+ {
+ System.Text.StringBuilder sb = new StringBuilder();
+ foreach (Jid jid in value)
+ {
+ sb.Append(String.Format("", jid.ToString()));
+ }
+
+ XmlElement addressXml = Xml.Element("addresses");
+ addressXml.InnerXml = sb.ToString();
+ addressXml.SetAttribute("xmlns", "http://jabber.org/protocol/address");
+
+ element.Child(addressXml);
+ }
+ }
+ }
+ }
+
///
/// A dictionary of alternate forms of the message subjects. The keys of the
/// dictionary denote ISO 2 language codes.
@@ -172,58 +240,73 @@ public IDictionary AlternateBodies
private set;
}
- ///
- /// Initializes a new instance of the Message class.
- ///
- /// The JID of the intended recipient.
- /// The content of the message.
- /// The subject of the message.
- /// The conversation thread this message belongs to.
- /// The type of the message. Can be one of the values from
- /// the MessagType enumeration.
- /// The language of the XML character data of
- /// the stanza.
- /// The to parameter is null.
- /// The body parameter is the empty string.
- public Message(Jid to, string body = null, string subject = null, string thread = null,
- MessageType type = MessageType.Normal, CultureInfo language = null)
+ ///
+ /// A dictionary of alternate forms of the message addresses. The keys of the
+ /// dictionary denote ISO 2 language codes.
+ ///
+ public IDictionary AlternateAddresses
+ {
+ get;
+ private set;
+ }
+
+ ///
+ /// Initializes a new instance of the Message class.
+ ///
+ /// The JID of the intended recipient.
+ /// The content of the message.
+ /// The subject of the message.
+ /// The XEP-0033 of the message.
+ /// The conversation thread this message belongs to.
+ /// The type of the message. Can be one of the values from
+ /// the MessagType enumeration.
+ /// The language of the XML character data of
+ /// the stanza.
+ /// The to parameter is null.
+ /// The body parameter is the empty string.
+ public Message(Jid to, string body = null, string subject = null, List additionalAddresses = null,
+ string thread = null, MessageType type = MessageType.Normal, CultureInfo language = null)
: base(to, null, null, null, language)
{
to.ThrowIfNull("to");
AlternateSubjects = new XmlDictionary(element, "subject", "xml:lang");
AlternateBodies = new XmlDictionary(element, "body", "xml:lang");
+ AlternateAddresses = new XmlDictionary(element, "addresses", "xml:lang");
Type = type;
Body = body;
Subject = subject;
Thread = thread;
+ Addresses = additionalAddresses;
}
- ///
- /// Initializes a new instance of the Message class.
- ///
- /// The JID of the intended recipient.
- /// A dictionary of message bodies. The dictionary
- /// keys denote the languages of the message bodies and must be valid
- /// ISO 2 letter language codes.
- /// A dictionary of message subjects. The dictionary
- /// keys denote the languages of the message subjects and must be valid
- /// ISO 2 letter language codes.
- /// The conversation thread this message belongs to.
- /// The type of the message. Can be one of the values from
- /// the MessagType enumeration.
- /// The language of the XML character data of
- /// the stanza.
- /// The to parametr or the bodies
- /// parameter is null.
- public Message(Jid to, IDictionary bodies,
- IDictionary subjects = null, string thread = null,
- MessageType type = MessageType.Normal, CultureInfo language = null)
+ ///
+ /// Initializes a new instance of the Message class.
+ ///
+ /// The JID of the intended recipient.
+ /// A dictionary of message bodies. The dictionary
+ /// keys denote the languages of the message bodies and must be valid
+ /// ISO 2 letter language codes.
+ /// A dictionary of message subjects. The dictionary
+ /// keys denote the languages of the message subjects and must be valid
+ /// ISO 2 letter language codes.
+ /// The XEP-0033 of the message.
+ /// The conversation thread this message belongs to.
+ /// The type of the message. Can be one of the values from
+ /// the MessagType enumeration.
+ /// The language of the XML character data of
+ /// the stanza.
+ /// The to parametr or the bodies
+ /// parameter is null.
+ public Message(Jid to, IDictionary bodies,
+ IDictionary subjects = null, List additionalAddresses = null,
+ string thread = null, MessageType type = MessageType.Normal, CultureInfo language = null)
: base(to, null, null, null, language)
{
to.ThrowIfNull("to");
bodies.ThrowIfNull("bodies");
AlternateSubjects = new XmlDictionary(element, "subject", "xml:lang");
AlternateBodies = new XmlDictionary(element, "body", "xml:lang");
+ AlternateAddresses = new XmlDictionary(element, "addresses", "xml:lang");
Type = type;
foreach (var pair in bodies)
AlternateBodies.Add(pair.Key, pair.Value);
@@ -233,8 +316,65 @@ public Message(Jid to, IDictionary bodies,
AlternateSubjects.Add(pair.Key, pair.Value);
}
Thread = thread;
+ Addresses = additionalAddresses;
}
+ ///
+ /// Initializes a new instance of the Message class.
+ ///
+ /// The JID of the intended recipient.
+ /// The content of the message.
+ /// The tag name the others items below will be wrapped in - they will have the appropriate namespace assigned.
+ /// A dictionary of additional message elements after body. The dictionary
+ /// keys denote the namespace of the message bodies. The element name should be the same for all items but you can have multiple -
+ /// each new element will have the namespace associated with it.
+ /// A dictionary of message subjects. The dictionary
+ /// keys denote the languages of the message subjects and must be valid
+ /// ISO 2 letter language codes.
+ /// The conversation thread this message belongs to.
+ /// The type of the message. Can be one of the values from
+ /// the MessagType enumeration.
+ /// The language of the XML character data of
+ /// the stanza.
+ /// The to parametr or the bodies
+ /// parameter is null.
+ public Message(Jid to, String body, string othertagname, IDictionary others,
+ IDictionary subjects = null, List additionalAddresses = null,
+ string thread = null, MessageType type = MessageType.Normal, CultureInfo language = null)
+ : base(to, null, null, null, language)
+ {
+ to.ThrowIfNull("to");
+ others.ThrowIfNull("bodies");
+ AlternateSubjects = new XmlDictionary(element, "subject", "xml:lang");
+ Body = body;
+ AlternateBodies = new XmlDictionary(element, othertagname, "xmlns");
+ AlternateAddresses = new XmlDictionary(element, "addresses", "xml:lang");
+ Type = type;
+ foreach (var pair in others)
+ AlternateBodies.Add(pair.Key, pair.Value);
+ if (subjects != null)
+ {
+ foreach (var pair in subjects)
+ AlternateSubjects.Add(pair.Key, pair.Value);
+ }
+ Thread = thread;
+ Addresses = additionalAddresses;
+ }
+
+ ///
+ /// Initializes a new instance of the Message class from the specified
+ /// instance.
+ ///
+ /// The message element
+ /// The Data parameter is null.
+ public Message(XmlElement data)
+ {
+
+ Data.ThrowIfNull("data");
+ type = ParseType(data.GetAttribute("type"));
+ element = data;
+ }
+
///
/// Initializes a new instance of the Message class from the specified
/// instance.
@@ -251,6 +391,7 @@ internal Message(Core.Message message)
element = message.Data;
AlternateSubjects = new XmlDictionary(element, "subject", "xml:lang");
AlternateBodies = new XmlDictionary(element, "body", "xml:lang");
+ AlternateAddresses = new XmlDictionary(element, "addresses", "xml:lang");
}
///
diff --git a/Im/MessageEventArgs.cs b/Im/MessageEventArgs.cs
index c8891a1a..50972884 100644
--- a/Im/MessageEventArgs.cs
+++ b/Im/MessageEventArgs.cs
@@ -1,6 +1,6 @@
using System;
-namespace Sharp.Xmpp.Im
+namespace XMPPEngineer.Im
{
///
/// Provides data for the Message event.
@@ -37,5 +37,15 @@ public MessageEventArgs(Jid jid, Message message)
Jid = jid;
Message = message;
}
+
+ ///
+ /// Initializes a new instance of the MessageEventArgs class for bodyless messages.
+ ///
+ /// The message parameter is null.
+ public MessageEventArgs(Message message)
+ {
+ message.ThrowIfNull("message");
+ Message = message;
+ }
}
}
\ No newline at end of file
diff --git a/Im/MessageType.cs b/Im/MessageType.cs
index ee280c50..ea496938 100644
--- a/Im/MessageType.cs
+++ b/Im/MessageType.cs
@@ -1,4 +1,4 @@
-namespace Sharp.Xmpp.Im
+namespace XMPPEngineer.Im
{
///
/// Defines the possible types for Message stanzas.
diff --git a/Im/Presence.cs b/Im/Presence.cs
index 7b45a991..bb7e224d 100644
--- a/Im/Presence.cs
+++ b/Im/Presence.cs
@@ -2,7 +2,7 @@
using System.Globalization;
using System.Xml;
-namespace Sharp.Xmpp.Im
+namespace XMPPEngineer.Im
{
///
/// Represents a Presence XML stanza as defined in XMPP:IM.
diff --git a/Im/PresenceType.cs b/Im/PresenceType.cs
index c49cd0e7..831728d2 100644
--- a/Im/PresenceType.cs
+++ b/Im/PresenceType.cs
@@ -1,4 +1,4 @@
-namespace Sharp.Xmpp.Im
+namespace XMPPEngineer.Im
{
///
/// Defines the possible types for Presence stanzas.
diff --git a/Im/PrivacyGranularity.cs b/Im/PrivacyGranularity.cs
index a5a9f7ec..005879f7 100644
--- a/Im/PrivacyGranularity.cs
+++ b/Im/PrivacyGranularity.cs
@@ -1,6 +1,6 @@
using System;
-namespace Sharp.Xmpp.Im
+namespace XMPPEngineer.Im
{
///
/// Defines the possible values for specifying more granular control over
diff --git a/Im/PrivacyList.cs b/Im/PrivacyList.cs
index 8eb8d494..5e258eac 100644
--- a/Im/PrivacyList.cs
+++ b/Im/PrivacyList.cs
@@ -2,7 +2,7 @@
using System.Collections;
using System.Collections.Generic;
-namespace Sharp.Xmpp.Im
+namespace XMPPEngineer.Im
{
///
/// Represents an XMPP privacy list.
diff --git a/Im/PrivacyRule.cs b/Im/PrivacyRule.cs
index 98d2e13d..caebeac1 100644
--- a/Im/PrivacyRule.cs
+++ b/Im/PrivacyRule.cs
@@ -1,4 +1,4 @@
-namespace Sharp.Xmpp.Im
+namespace XMPPEngineer.Im
{
///
/// Represents a generic privacy rule.
diff --git a/Im/Roster.cs b/Im/Roster.cs
index 32c27bb6..98c5c2bf 100644
--- a/Im/Roster.cs
+++ b/Im/Roster.cs
@@ -1,7 +1,7 @@
using System.Collections;
using System.Collections.Generic;
-namespace Sharp.Xmpp.Im
+namespace XMPPEngineer.Im
{
///
/// Represents the user's roster.
diff --git a/Im/RosterItem.cs b/Im/RosterItem.cs
index 927a54d9..df7a8052 100644
--- a/Im/RosterItem.cs
+++ b/Im/RosterItem.cs
@@ -1,7 +1,7 @@
using System;
using System.Collections.Generic;
-namespace Sharp.Xmpp.Im
+namespace XMPPEngineer.Im
{
///
/// Represents a roster item.
diff --git a/Im/RosterUpdatedEventArgs.cs b/Im/RosterUpdatedEventArgs.cs
index ac94f63a..fe10beb5 100644
--- a/Im/RosterUpdatedEventArgs.cs
+++ b/Im/RosterUpdatedEventArgs.cs
@@ -1,6 +1,6 @@
using System;
-namespace Sharp.Xmpp.Im
+namespace XMPPEngineer.Im
{
///
/// Provides data for the RosterUpdated Event.
diff --git a/Im/Status.cs b/Im/Status.cs
index 034500fe..532a45cd 100644
--- a/Im/Status.cs
+++ b/Im/Status.cs
@@ -3,7 +3,7 @@
using System.Globalization;
using System.Linq;
-namespace Sharp.Xmpp.Im
+namespace XMPPEngineer.Im
{
///
/// Provides status information for a contact.
diff --git a/Im/StatusEventArgs.cs b/Im/StatusEventArgs.cs
index e5c30344..b0a4d35e 100644
--- a/Im/StatusEventArgs.cs
+++ b/Im/StatusEventArgs.cs
@@ -1,6 +1,6 @@
using System;
-namespace Sharp.Xmpp.Im
+namespace XMPPEngineer.Im
{
///
/// Provides data for the Status event.
diff --git a/Im/SubscriptionApprovedEventArgs.cs b/Im/SubscriptionApprovedEventArgs.cs
index 867fe8e7..ded31be6 100644
--- a/Im/SubscriptionApprovedEventArgs.cs
+++ b/Im/SubscriptionApprovedEventArgs.cs
@@ -1,6 +1,6 @@
using System;
-namespace Sharp.Xmpp.Im
+namespace XMPPEngineer.Im
{
///
/// Provides data for the SubscriptionApproved Event.
diff --git a/Im/SubscriptionPrivacyRule.cs b/Im/SubscriptionPrivacyRule.cs
index cde0bd00..ce94a307 100644
--- a/Im/SubscriptionPrivacyRule.cs
+++ b/Im/SubscriptionPrivacyRule.cs
@@ -1,4 +1,4 @@
-namespace Sharp.Xmpp.Im
+namespace XMPPEngineer.Im
{
///
/// Represents a privacy rule pertaining to a subscription state.
diff --git a/Im/SubscriptionRefusedEventArgs.cs b/Im/SubscriptionRefusedEventArgs.cs
index 468ff0db..ef23425e 100644
--- a/Im/SubscriptionRefusedEventArgs.cs
+++ b/Im/SubscriptionRefusedEventArgs.cs
@@ -1,6 +1,6 @@
using System;
-namespace Sharp.Xmpp.Im
+namespace XMPPEngineer.Im
{
///
/// Provides data for the SubscriptionRefused Event.
diff --git a/Im/SubscriptionRequest.cs b/Im/SubscriptionRequest.cs
index d4085dc9..baabb147 100644
--- a/Im/SubscriptionRequest.cs
+++ b/Im/SubscriptionRequest.cs
@@ -1,4 +1,4 @@
-namespace Sharp.Xmpp.Im
+namespace XMPPEngineer.Im
{
///
/// Represents a request for subscription.
diff --git a/Im/SubscriptionRequestEventArgs.cs b/Im/SubscriptionRequestEventArgs.cs
index 849800bf..348a5bc7 100644
--- a/Im/SubscriptionRequestEventArgs.cs
+++ b/Im/SubscriptionRequestEventArgs.cs
@@ -1,6 +1,6 @@
using System;
-namespace Sharp.Xmpp.Im
+namespace XMPPEngineer.Im
{
///
/// Provides data for the SubscriptionRequest Event.
diff --git a/Im/SubscriptionState.cs b/Im/SubscriptionState.cs
index bf51c798..7a1536a5 100644
--- a/Im/SubscriptionState.cs
+++ b/Im/SubscriptionState.cs
@@ -1,4 +1,4 @@
-namespace Sharp.Xmpp.Im
+namespace XMPPEngineer.Im
{
///
/// Defines the possible values for the subscription state of a roster item.
diff --git a/Im/UnsubscribedEventArgs.cs b/Im/UnsubscribedEventArgs.cs
index 166bfc20..6da5c5b9 100644
--- a/Im/UnsubscribedEventArgs.cs
+++ b/Im/UnsubscribedEventArgs.cs
@@ -1,6 +1,6 @@
using System;
-namespace Sharp.Xmpp.Im
+namespace XMPPEngineer.Im
{
///
/// Provides data for the Unsubscribed Event.
diff --git a/Im/XmlDictionary.cs b/Im/XmlDictionary.cs
index 5f810cb4..8fcc7ee3 100644
--- a/Im/XmlDictionary.cs
+++ b/Im/XmlDictionary.cs
@@ -3,7 +3,7 @@
using System.Collections.Generic;
using System.Xml;
-namespace Sharp.Xmpp.Im
+namespace XMPPEngineer.Im
{
///
/// An XML-backed dictionary.
diff --git a/Im/XmppIm.cs b/Im/XmppIm.cs
index 388226b1..ace871e0 100644
--- a/Im/XmppIm.cs
+++ b/Im/XmppIm.cs
@@ -1,5 +1,5 @@
-using Sharp.Xmpp.Core;
-using Sharp.Xmpp.Extensions;
+using XMPPEngineer.Core;
+using XMPPEngineer.Extensions;
using System;
using System.Collections.Generic;
using System.Globalization;
@@ -10,7 +10,7 @@
using System.Security.Authentication;
using System.Xml;
-namespace Sharp.Xmpp.Im
+namespace XMPPEngineer.Im
{
///
/// Implements the basic instant messaging (IM) and presence functionality.
@@ -28,6 +28,8 @@ public class XmppIm : IDisposable
///
private bool disposed;
+ bool retrieveRoster = true;
+
///
/// The set of loaded extensions.
///
@@ -143,6 +145,22 @@ public RemoteCertificateValidationCallback Validate
}
}
+ ///
+ /// If false the connection will not automatically retrieve the rooster
+ ///
+ public bool RetrieveRoster
+ {
+ get
+ {
+ return retrieveRoster;
+ }
+
+ set
+ {
+ retrieveRoster = value;
+ }
+ }
+
///
/// Determines whether the session with the server is TLS/SSL encrypted.
///
@@ -250,6 +268,16 @@ public CustomIqRequestDelegate CustomIqDelegate
///
public event EventHandler Message;
+ ///
+ /// The event that is raised when stream management is enabled.
+ ///
+ public event EventHandler StreamManagementEnabled;
+
+ ///
+ /// The event that is raised when a stream is resumed.
+ ///
+ public event EventHandler StreamResumed;
+
///
/// The event that is raised when a subscription request made by the JID
/// associated with this instance has been approved.
@@ -299,11 +327,36 @@ public CustomIqRequestDelegate CustomIqDelegate
///