2using System.Collections.Generic;
3using System.Reflection;
4using System.Threading.Tasks;
27 public const string XmppNamespace =
"http://lab.tagroot.io/Schema/ComSim/XMPP.xsd";
32 public const string XmppSchema =
"TAG.Simulator.XMPP.Schema.ComSimXmpp.xsd";
38 private string domain;
41 private string userName;
42 private string apiKey;
43 private string secret;
44 private bool alwaysConnected;
45 private bool allowCramMD5;
46 private bool allowDigestMD5;
47 private bool allowEncryption;
48 private bool allowPlain;
49 private bool allowScramSHA1;
50 private bool allowScramSHA256;
51 private bool requestRosterOnStartup;
52 private bool trustServer;
53 private bool isOnline =
false;
105 public string Host => this.host;
116 public override Task
FromXml(XmlElement Definition)
122 this.alwaysConnected =
XML.
Attribute(Definition,
"alwaysConnected",
false);
124 if (Definition.HasAttribute(
"port"))
129 this.allowCramMD5 =
XML.
Attribute(Definition,
"allowCramMD5",
false);
130 this.allowDigestMD5 =
XML.
Attribute(Definition,
"allowDigestMD5",
false);
131 this.allowEncryption =
XML.
Attribute(Definition,
"allowEncryption",
true);
132 this.allowPlain =
XML.
Attribute(Definition,
"allowPlain",
false);
133 this.allowScramSHA1 =
XML.
Attribute(Definition,
"allowScramSHA1",
true);
134 this.allowScramSHA256 =
XML.
Attribute(Definition,
"allowScramSHA256",
true);
135 this.requestRosterOnStartup =
XML.
Attribute(Definition,
"requestRosterOnStartup",
true);
136 this.trustServer =
XML.
Attribute(Definition,
"trustServer",
false);
138 return base.FromXml(Definition);
146 if (this.port.HasValue)
147 this.host = this.domain;
161 this.host = this.domain;
166 await base.Initialize();
181 Result.domain = this.domain;
182 Result.host = this.host;
183 Result.port = this.port;
185 Result.apiKey = this.apiKey;
186 Result.secret = this.secret;
187 Result.alwaysConnected = this.alwaysConnected;
188 Result.allowCramMD5 = this.allowCramMD5;
189 Result.allowDigestMD5 = this.allowDigestMD5;
190 Result.allowEncryption = this.allowEncryption;
191 Result.allowPlain = this.allowPlain;
192 Result.allowScramSHA1 = this.allowScramSHA1;
193 Result.allowScramSHA256 = this.allowScramSHA256;
194 Result.requestRosterOnStartup = this.requestRosterOnStartup;
195 Result.trustServer = this.trustServer;
197 return Task.FromResult<
Actor>(Result);
219 if (this.sniffer is
null)
220 this.client =
new XmppClient(this.xmppCredentials,
"en", typeof(
XmppActor).GetTypeInfo().Assembly);
222 this.client =
new XmppClient(this.xmppCredentials,
"en", typeof(
XmppActor).GetTypeInfo().Assembly, this.sniffer);
224 this.client.OnStateChanged += this.Client_OnStateChanged;
225 this.client.OnChatMessage += this.Client_OnChatMessage;
226 this.client.OnConnectionError += this.Client_OnConnectionError;
227 this.client.OnError += this.Client_OnError;
228 this.client.OnErrorMessage += this.Client_OnErrorMessage;
229 this.client.OnGroupChatMessage += this.Client_OnGroupChatMessage;
230 this.client.OnHeadlineMessage += this.Client_OnHeadlineMessage;
231 this.client.OnNormalMessage += this.Client_OnNormalMessage;
232 this.client.OnPresence += this.Client_OnPresence;
233 this.client.OnPresenceSubscribe += this.Client_OnPresenceSubscribe;
234 this.client.OnRosterItemAdded += this.Client_OnRosterItemAdded;
235 this.client.OnRosterItemRemoved += this.Client_OnRosterItemRemoved;
236 this.client.OnRosterItemUpdated += this.Client_OnRosterItemUpdated;
237 this.client.CustomPresenceXml += this.Client_CustomPresenceXml;
240 int c = this.
N.ToString().Length;
241 int Nr0 = c - InstanceIndexSuffix.Length;
244 InstanceIndexSuffix =
new string(
'0', Nr0) + InstanceIndexSuffix;
253 if (Node is Extensions.IXmppExtension Extension)
255 object ExtensionObj = await Extension.Add(
this, this.Client);
257 if (!
string.IsNullOrEmpty(Extension.Id))
258 this.
Model.
Variables[Extension.Id + InstanceIndexSuffix] = ExtensionObj;
263 if (this.alwaysConnected)
265 await this.client.
Connect(this.domain);
277 throw new Exception(
"Unable to create account for " + this.userName +
"@" + this.domain);
285 if (this.client.
TryGetTag(
"CutomPresenceXML", out
object Obj) &&
291 return Task.CompletedTask;
294 private Task Client_OnRosterItemUpdated(
object Sender,
RosterItem Item)
297 new KeyValuePair<string, object>(
"Item", Item),
298 new KeyValuePair<string, object>(
"Client", this.client));
300 return Task.CompletedTask;
303 private Task Client_OnRosterItemRemoved(
object Sender,
RosterItem Item)
306 new KeyValuePair<string, object>(
"Item", Item),
307 new KeyValuePair<string, object>(
"Client", this.client));
309 return Task.CompletedTask;
312 private Task Client_OnRosterItemAdded(
object Sender,
RosterItem Item)
315 new KeyValuePair<string, object>(
"Item", Item),
316 new KeyValuePair<string, object>(
"Client", this.client));
318 return Task.CompletedTask;
324 new KeyValuePair<string, object>(
"e", e),
325 new KeyValuePair<string, object>(
"Client",
this.client)))
330 return Task.CompletedTask;
336 new KeyValuePair<string, object>(
"e", e),
337 new KeyValuePair<string, object>(
"Client", this.client));
339 return Task.CompletedTask;
345 new KeyValuePair<string, object>(
"e", e),
346 new KeyValuePair<string, object>(
"Client", this.client));
348 return Task.CompletedTask;
354 new KeyValuePair<string, object>(
"e", e),
355 new KeyValuePair<string, object>(
"Client", this.client));
357 return Task.CompletedTask;
363 new KeyValuePair<string, object>(
"e", e),
364 new KeyValuePair<string, object>(
"Client", this.client));
366 return Task.CompletedTask;
372 new KeyValuePair<string, object>(
"e", e),
373 new KeyValuePair<string, object>(
"Client", this.client));
375 return Task.CompletedTask;
378 private Task Client_OnError(
object Sender, Exception Exception)
381 new KeyValuePair<string, object>(
"Exception", Exception),
382 new KeyValuePair<string, object>(
"Client", this.client));
384 return Task.CompletedTask;
387 private Task Client_OnConnectionError(
object Sender, Exception Exception)
390 new KeyValuePair<string, object>(
"Exception", Exception),
391 new KeyValuePair<string, object>(
"Client", this.client));
393 return Task.CompletedTask;
399 new KeyValuePair<string, object>(
"e", e),
400 new KeyValuePair<string, object>(
"Client", this.client));
402 return Task.CompletedTask;
405 private Task Client_OnStateChanged(
object Sender,
XmppState NewState)
410 this.isOnline =
true;
412 if (this.credentials is
null)
417 UserName = this.userName,
419 PasswordHashMethod = this.client.PasswordHashMethod
428 this.isOnline =
false;
433 new KeyValuePair<string, object>(
"NewState", NewState),
434 new KeyValuePair<string, object>(
"Client", this.client));
436 return Task.CompletedTask;
454 throw new Exception(
"Unable to connect " + this.userName +
"@" + this.domain);
464 if (!(this.client is
null))
470 if (!(this.sniffer is
null))
472 if (this.sniffer is IDisposable Disposable)
473 Disposable.Dispose();
489 if (!(this.credentials is
null) &&
string.IsNullOrEmpty(this.credentials.
PasswordHash))
492 this.credentials =
null;
497 Account = this.userName,
498 AllowCramMD5 = this.allowCramMD5,
499 AllowDigestMD5 = this.allowDigestMD5,
500 AllowEncryption = this.allowEncryption,
501 AllowPlain = this.allowPlain,
502 AllowRegistration =
false,
503 AllowScramSHA1 = this.allowScramSHA1,
504 AllowScramSHA256 = this.allowScramSHA256,
506 Port = this.port.Value,
507 RequestRosterOnStartup = this.requestRosterOnStartup,
511 if (this.credentials is
null)
513 Result.AllowRegistration =
true;
514 Result.FormSignatureKey = await this.
Model.
GetKey(this.apiKey,
string.Empty);
515 Result.FormSignatureSecret = await this.
Model.
GetKey(this.secret,
string.Empty);
537 UserName = this.userName,
Root node of a simulation model
async Task< string > GetKey(string KeyName, string LookupValue)
Gets a key from the database. If it does not exist, it prompts the user for input.
Variables Variables
Model variables.
byte[] GetRandomBytes(int NrBytes)
Gets an array of random bytes.
ISniffer GetSniffer(string Actor)
Gets a sniffer, if sniffer output is desired.
bool ExternalEvent(IExternalEventsNode Source, string Name, params KeyValuePair< string, object >[] Arguments)
Method called when an external event has been received.
Abstract base class for actors
string InstanceId
ID of actor instance.
int InstanceIndex
Actor instance index.
int N
Number of actors of this type specified.
string PasswordHash
Password hash
string PasswordHashMethod
Password hash method
Object used in simulation activities.
Abstract base class for XMPP actors.
override async Task Initialize()
Initialized the node before simulation.
override Task< Actor > CreateInstanceAsync(int InstanceIndex, string InstanceId)
Creates an instance of the actor.
override object ActivityObject
Returns the object that will be used by the actor for actions during an activity.
XmppActor(ISimulationNode Parent, Model Model, int InstanceIndex, string InstanceId)
Abstract base class for XMPP actors.
abstract XmppActor CreateInstanceObject(int InstanceIndex, string InstanceId)
Creates an instance object of the XMPP actor, and initializes it.
XmppClient Client
XMPP Client
const string XmppSchema
TAG.Simulator.XMPP.Schema.ComSimXmpp.xsd
override async Task InitializeInstance()
Initializes an instance of an actor.
bool IsOnline
If instance is online.
const string XmppNamespace
http://lab.tagroot.io/Schema/ComSim/XMPP.xsd
XmppActor(ISimulationNode Parent, Model Model)
Abstract base class for XMPP actors.
virtual async Task< XmppCredentials > GetInstanceCredentials()
Gets XMPP credentials for the instance.
override async Task StartInstance()
Starts an instance of an actor.
override string SchemaResource
Points to the embedded XML Schema resource defining the semantics of the XML namespace.
bool TrustServer
If server is to be trusted, regardless of state of certificate.
override Task FromXml(XmlElement Definition)
Sets properties and attributes of class in accordance with XML definition.
override async Task FinalizeInstance()
Finalizes an instance of an actor.
override string Namespace
XML Namespace where the element is defined.
Abstract base class for handler nodes
abstract void RegisterHandlers(IActor Actor, XmppClient Client)
Registers handlers on the XMPP Client.
Helps with common XML-related tasks.
static string Attribute(XmlElement E, string Name)
Gets the value of an XML attribute.
DNS resolver, as defined in:
static Task< SRV > LookupServiceEndpoint(string DomainName, string ServiceName, string Protocol)
Looks up a service endpoint for a domain. If multiple are available, an appropriate one is selected a...
string TargetHost
Target Host
Event Argument for custom presence XML events.
StringBuilder Stanza
Stanza being built.
Event arguments for message events.
Event arguments for presence events.
async Task Accept()
Accepts a subscription or unsubscription request.
Maintains information about an item in the roster.
Manages an XMPP client connection. Implements XMPP, as defined in https://tools.ietf....
async Task< int > WaitStateAsync(int Timeout, params XmppState[] States)
Waits for one of the states in States to occur.
async Task DisposeAsync()
Closes the connection and disposes of all resources.
string PasswordHash
Hash value of password. Depends on method used to authenticate user.
Task Connect()
Connects the client.
bool TryGetTag(string TagName, out object Tag)
Tries to get a tag from the client. Tags can be used to attached application specific objects to the ...
Class containing credentials for an XMPP client connection.
bool AllowRegistration
If the client is allowed to register for a new account, if the account was not found.
Static interface for database persistence. In order to work, a database provider has to be assigned t...
static async Task Delete(object Object)
Deletes an object in the database.
static async Task Insert(object Object)
Inserts an object into the default collection of the database.
This filter selects objects that conform to all child-filters provided.
This filter selects objects that have a named field equal to a given value.
Basic interface for simulator nodes. Implementing this interface allows classes with default contruct...
ISimulationNode Parent
Parent node in the simulation model.
Basic interface for simulator nodes. Implementing this interface allows classes with default contruct...
Interface for sniffers. Sniffers can be added to ICommunicationLayer classes to eavesdrop on communic...
XmppState
State of XMPP connection.