public override List <Field> ProcessReadoutRequest(ReadoutType Types, DateTime From, DateTime To) { String Path = this.resource; EditableTreeNode Node = this.Parent; CoapServer Server = null; CoapFolder Folder; while (Node != null) { if ((Folder = Node as CoapFolder) != null) { Path = Folder.Folder + "/" + Path; } else if ((Server = Node as CoapServer) != null) { break; } Node = Node.Parent; } if (Server == null) { throw new Exception("No CoAP Server node found."); } CoapEndpoint Endpoint = Server.Endpoint; CoapResponse Response = Endpoint.GET(true, Server.Host, Server.Port, Path, this.query, 20000); return(this.ParseContent(Response.Response, Types, From, To)); }
/// <summary> /// Represents a registration on an observable resource. /// </summary> /// <param name="Client">UDP Client on which the request was received.</param> /// <param name="Endpoint">CoAP Endpoint managing the resource.</param> /// <param name="Request">Request message.</param> internal ObservationRegistration(ClientBase Client, CoapEndpoint Endpoint, CoapMessage Request) { this.client = Client; this.endpoint = Endpoint; this.request = Request; }
/// <summary> /// <see cref="IDisposable.Dispose"/> /// </summary> public void Dispose() { if (this.coapEndpoint != null) { if (this.state == Lwm2mState.Operation) { this.Deregister(); } foreach (Lwm2mObject Object in this.objects.Values) { this.coapEndpoint.Unregister(Object); foreach (Lwm2mObjectInstance Instance in Object.Instances) { this.coapEndpoint.Unregister(Instance); foreach (Lwm2mResource Resource in Instance.Resources) { this.coapEndpoint.Unregister(Resource); } } } this.coapEndpoint.Unregister(this); this.coapEndpoint.Unregister(this.bsResource); this.coapEndpoint = null; this.objects.Clear(); } }
/// <summary> /// Class implementing an LWM2M client, as defined in: /// http://www.openmobilealliance.org/release/LightweightM2M/V1_0-20170208-A/OMA-TS-LightweightM2M-V1_0-20170208-A.pdf /// </summary> /// <param name="ClientName">Client name.</param> /// <param name="CoapEndpoint">CoAP endpoint to use for LWM2M communication.</param> /// <param name="Objects">Objects</param> public Lwm2mClient(string ClientName, CoapEndpoint CoapEndpoint, params Lwm2mObject[] Objects) : base("/") { this.coapEndpoint = CoapEndpoint; this.serverReferences = ServerReferences; this.clientName = ClientName; this.state = Lwm2mState.Bootstrap; this.bsResource = new BootstreapResource(this); this.coapEndpoint.Register(this); this.coapEndpoint.Register(this.bsResource); foreach (Lwm2mObject Object in Objects) { if (Object.Id < 0) { throw new ArgumentException("Invalid object ID.", nameof(Object)); } if (this.objects.ContainsKey(Object.Id)) { throw new ArgumentException("An object with ID " + Object.Id + " is already registered.", nameof(Object)); } this.objects[Object.Id] = Object; Object.Client = this; this.coapEndpoint.Register(Object); Object.AfterRegister(); } }
/// <summary> /// Event arguments for CoAP response callbacks. /// </summary> /// <param name="Client">UDP Client.</param> /// <param name="Endpoint">CoAP Endpoint.</param> /// <param name="Message">CoAP message.</param> /// <param name="Resource">CoAP resource if relevant.</param> internal CoapMessageEventArgs(ClientBase Client, CoapEndpoint Endpoint, CoapMessage Message, CoapResource Resource) { this.client = Client; this.endpoint = Endpoint; this.message = Message; this.resource = Resource; }
/// <summary> /// <see cref="Clayster.Library.Internet.LineListeners.ILineListenable.LineListenerError"/> /// </summary> public void LineListenerError(string s) { CoapEndpoint Endpoint = this.Endpoint; if (Endpoint != null) { Endpoint.LineListenerError(s); } }
/// <summary> /// <see cref="Clayster.Library.Internet.LineListeners.ILineListenable.LineListenerDataRead"/> /// </summary> public void LineListenerDataRead(string Id, byte[] Data) { CoapEndpoint Endpoint = this.Endpoint; if (Endpoint != null) { Endpoint.LineListenerDataRead(Id, Data); } }
/// <summary> /// <see cref="Clayster.Library.Internet.LineListeners.ILineListenable.LineListenerRowRead"/> /// </summary> public void LineListenerRowRead(string Id, string Row) { CoapEndpoint Endpoint = this.Endpoint; if (Endpoint != null) { Endpoint.LineListenerRowRead(Id, Row); } }
/// <summary> /// <see cref="Clayster.Library.Internet.LineListeners.ILineListenable.UnregisterLineListener"/> /// </summary> public void UnregisterLineListener(ILineListener Listener) { CoapEndpoint Endpoint = this.Endpoint; if (Endpoint != null) { Endpoint.UnregisterLineListener(Listener); } }
/// <summary> /// Returns a response to the caller. /// </summary> /// <param name="Code">CoAP message code.</param> /// <param name="Payload">Optional payload.</param> /// <param name="Block2Nr">Block index to transmit.</param> /// <param name="BlockSize">Block size, in case the <paramref name="Payload"/> needs to be divided into blocks.</param> /// <param name="Options">Optional options.</param> internal void Respond(CoapCode Code, byte[] Payload, int Block2Nr, int BlockSize, params CoapOption[] Options) { this.endpoint.Transmit(this.client, this.remoteEndpoint, this.client.IsEncrypted, this.responded ? (ushort?)null : this.request.MessageId, this.ResponseType, Code, this.request.Token, false, Payload, Block2Nr, BlockSize, this.resource, null, null, null, null, CoapEndpoint.Merge(Options, this.additionalResponseOptions)); this.responded = true; }
/// <summary> /// CoAP response to return to a received request. /// </summary> /// <param name="Client">Client receiving the response.</param> /// <param name="Endpoint">CoAP Endpoint.</param> /// <param name="RemoteEndpoint">Remote endpoint.</param> /// <param name="Request">Request.</param> /// <param name="Notifications">How notifications are sent, if at all.</param> /// <param name="Resource">CoAP resource.</param> /// <param name="AdditionalResponseOptions">Additional response options.</param> internal CoapResponse(ClientBase Client, CoapEndpoint Endpoint, IPEndPoint RemoteEndpoint, CoapMessage Request, Notifications Notifications, CoapResource Resource, params CoapOption[] AdditionalResponseOptions) { this.client = Client; this.endpoint = Endpoint; this.remoteEndpoint = RemoteEndpoint; this.request = Request; this.notifications = Notifications; this.resource = Resource; this.additionalResponseOptions = AdditionalResponseOptions; }
/// <summary> /// Returns a response to the caller. /// </summary> /// <param name="Code">CoAP message code.</param> /// <param name="Payload">Optional payload to be encoded.</param> /// <param name="BlockSize">Block size, in case the <paramref name="Payload"/> needs to be divided into blocks.</param> /// <param name="Options">Optional options.</param> public void Respond(CoapCode Code, object Payload, int BlockSize, params CoapOption[] Options) { byte[] Data = CoapEndpoint.Encode(Payload, out int ContentFormat); if (!CoapEndpoint.HasOption(Options, 12)) { Options = CoapEndpoint.Merge(Options, new CoapOptionContentFormat((ulong)ContentFormat)); } this.Respond(Code, Data, BlockSize, Options); }
public void TestCleanup() { if (this.client != null) { ulong[] Tokens = this.client.GetActiveTokens(); ushort[] MessageIDs = this.client.GetActiveMessageIDs(); this.client.Dispose(); this.client = null; Assert.AreEqual(0, Tokens.Length, "There are tokens that have not been unregistered properly."); Assert.AreEqual(0, MessageIDs.Length, "There are message IDs that have not been unregistered properly."); } }
private void Cleanup(ref CoapEndpoint Client) { if (Client != null) { ulong[] Tokens = Client.GetActiveTokens(); ushort[] MessageIDs = Client.GetActiveMessageIDs(); Client.Dispose(); Client = null; Assert.AreEqual(0, Tokens.Length, "There are tokens that have not been unregistered properly."); Assert.AreEqual(0, MessageIDs.Length, "There are message IDs that have not been unregistered properly."); } }
public async Task TestInitialize() { this.coapClient = new CoapEndpoint(new int[] { 5783 }, new int[] { 5784 }, null, null, false, false, new TextWriterSniffer(Console.Out, BinaryPresentationMethod.Hexadecimal)); this.lwm2mClient = new Lwm2mClient("Lwm2mTestClient", this.coapClient, new Lwm2mSecurityObject(), new Lwm2mServerObject(), new Lwm2mAccessControlObject(), new Lwm2mDeviceObject("Waher Data AB", "Unit Test", Environment.MachineName, Environment.OSVersion.VersionString, "PC", Environment.OSVersion.Platform.ToString(), Environment.Version.ToString())); await this.lwm2mClient.LoadBootstrapInfo(); }
/// <summary> /// Decodes the payload of the message. /// </summary> /// <returns>Decoded payload.</returns> public object Decode() { if (this.payload == null) { return(null); } else if (!this.contentFormat.HasValue) { return(this.payload); } else { return(CoapEndpoint.Decode((int)this.contentFormat.Value, this.payload, this.baseUri)); } }
internal ObservationRegistration RegisterSubscription(ClientBase Client, CoapEndpoint Endpoint, CoapMessage Message) { ObservationRegistration Result; string Key = Message.From.ToString() + " " + Message.Token.ToString(); Result = new ObservationRegistration(Client, Endpoint, Message); lock (this.registrations) { this.registrations[Key] = Result; this.registeredMessages = null; } return(Result); }
public CoapEndpoint GetEndpoint(string MulticastAddress) { lock (this.synchObject) { ILineListener[] LineListeners = null; if (this.recycle) { this.recycle = false; if (this.endpoint != null) { LineListeners = this.endpoint.LineListeners; this.endpoint.Dispose(); this.endpoint = null; } } if (this.endpoint == null) { if (string.IsNullOrEmpty(MulticastAddress)) { this.endpoint = new CoapEndpoint(this.port, this.ttl); } else { this.endpoint = new CoapEndpoint(this.port, this.ttl, MulticastAddress); } User User = this.User; if (User != null) { this.endpoint.RegisterResource(new CoapTopologyBridge(User)); } if (LineListeners != null) { foreach (ILineListener LL in LineListeners) { this.endpoint.RegisterLineListener(LL); } } } return(this.endpoint); } }
public void TestCleanup() { if (this.lwm2mClient != null) { this.lwm2mClient.Dispose(); this.lwm2mClient = null; } if (this.coapClient != null) { CoapResource[] Resources = this.coapClient.GetRegisteredResources(); this.coapClient.Dispose(); this.coapClient = null; Assert.AreEqual(1, Resources.Length, "There are resources still registered on the CoAP client."); } }
public async Task TestSendMulticastMessagToExplicitMulticastEndpoint() { // Arrange var mockClientEndpoint = new Mock <MockEndpoint> { CallBase = true }; mockClientEndpoint .Setup(e => e.SendAsync(It.IsAny <CoapPacket>(), It.IsAny <CancellationToken>())) .CallBase() .Verifiable("Message was not sent via multicast endpoint"); var destEndpoint = new CoapEndpoint { IsMulticast = true }; var message = new CoapMessage { IsMulticast = true, Type = CoapMessageType.NonConfirmable, Code = CoapMessageCode.Get, Options = new System.Collections.Generic.List <CoapOption> { new Options.ContentFormat(Options.ContentFormatType.ApplicationLinkFormat) }, Payload = Encoding.UTF8.GetBytes("</.well-known/core>") }; // Ack using (var client = new CoapClient(mockClientEndpoint.Object)) { var ct = new CancellationTokenSource(MaxTaskTimeout); await client.SendAsync(message, destEndpoint, ct.Token); } // Assert Mock.Verify(mockClientEndpoint); }
internal string GetUri() { string Host = null; int? Port = null; string Path = null; if (!(this.options is null)) { foreach (CoapOption Option in this.options) { switch (Option.OptionNumber) { case 3: Host = ((CoapOptionUriHost)Option).Value; break; case 7: Port = (int)((CoapOptionUriPort)Option).Value; break; case 11: if (Path is null) { Path = "/"; } else { Path += "/"; } Path += ((CoapOptionUriPath)Option).Value; break; } } } return(CoapEndpoint.GetUri(Host, Port, Path, null)); }
public void TestSendMulticastMessagtoNonMulticastEndpointThrowsCoapClientException() { // Arrange var mockClientEndpoint = new Mock <MockEndpoint> { CallBase = true }; var destEndpoint = new CoapEndpoint { IsMulticast = false }; var message = new CoapMessage { IsMulticast = true, Type = CoapMessageType.NonConfirmable, Code = CoapMessageCode.Get, Options = new System.Collections.Generic.List <CoapOption> { new Options.ContentFormat(Options.ContentFormatType.ApplicationLinkFormat) }, Payload = Encoding.UTF8.GetBytes("</.well-known/core>") }; // Ack AsyncTestDelegate action = async() => { using (var client = new CoapClient(mockClientEndpoint.Object)) { var ct = new CancellationTokenSource(MaxTaskTimeout); await client.SendAsync(message, destEndpoint, ct.Token); } }; // Assert Assert.ThrowsAsync <CoapClientException>(action); }
public static int Main (string[] args) { Log.Register (new ConsoleOutEventLog (80)); Log.Information ("Initializing application..."); HttpSocketClient.RegisterHttpProxyUse (false, false); // Don't look for proxies. DB.BackupConnectionString = "Data Source=sensor.db;Version=3;"; DB.BackupProviderName = "Clayster.Library.Data.Providers.SQLiteServer.SQLiteServerProvider"; db = DB.GetDatabaseProxy ("TheSensor"); Console.CancelKeyPress += (object sender, ConsoleCancelEventArgs e) => { e.Cancel = true; executionLed.Low (); }; // Initializing hardware and retrieving current sensor values try { tmp102.Configure (false, TexasInstrumentsTMP102.FaultQueue.ConsecutiveFaults_6, TexasInstrumentsTMP102.AlertPolarity.AlertActiveLow, TexasInstrumentsTMP102.ThermostatMode.ComparatorMode, false, TexasInstrumentsTMP102.ConversionRate.Hz_1, false); temp = (short)tmp102.ReadTemperatureRegister (); temperatureC = temp / 256.0; for (int i = 0; i < 10; i++) tempAvgWindow [i] = temp; sumTemp = temp * 10; } catch (Exception ex) { Log.Exception (ex); sumTemp = 0; temperatureC = 0; errorLed.High (); } try { adc.Configure (true, false, false, false, false, false); light = adc.ReadRegistersBinary () [0]; lightPercent = (100.0 * light) / 0x0fff; for (int i = 0; i < 10; i++) lightAvgWindow [i] = light; sumLight = light * 10; } catch (Exception ex) { Log.Exception (ex); sumLight = 0; lightPercent = 0; errorLed.High (); } // Loading historical Sensor Values Log.Information ("Loading Minute Values."); perMinute.AddRange (Record.LoadRecords (Rank.Minute)); Log.Information ("Loading Hour Values."); perHour.AddRange (Record.LoadRecords (Rank.Hour)); Log.Information ("Loading Day Values."); perDay.AddRange (Record.LoadRecords (Rank.Day)); Log.Information ("Loading Month Values."); perMonth.AddRange (Record.LoadRecords (Rank.Month)); // Resuming average calculations int Pos = perSecond.Count; DateTime CurrentTime = DateTime.Now; DateTime Timestamp; while (Pos-- > 0) { Record Rec = perSecond [Pos]; Timestamp = Rec.Timestamp; if (Timestamp.Minute == CurrentTime.Minute && Timestamp.Hour == CurrentTime.Hour && Timestamp.Date == CurrentTime.Date) { sumSeconds += Rec; nrSeconds++; } else break; } Pos = perMinute.Count; while (Pos-- > 0) { Record Rec = perMinute [Pos]; Timestamp = Rec.Timestamp; if (Timestamp.Hour == CurrentTime.Hour && Timestamp.Date == CurrentTime.Date) { sumMinutes += Rec; nrMinutes++; } else break; } Pos = perHour.Count; while (Pos-- > 0) { Record Rec = perHour [Pos]; Timestamp = Rec.Timestamp; if (Timestamp.Date == CurrentTime.Date) { sumHours += Rec; nrHours++; } else break; } Pos = perDay.Count; while (Pos-- > 0) { Record Rec = perDay [Pos]; Timestamp = Rec.Timestamp; if (Timestamp.Month == CurrentTime.Month && Timestamp.Year == CurrentTime.Year) { sumDays += Rec; nrDays++; } else break; } // Sampling of new Sensor Values Timer Timer = new Timer (SampleSensorValues, null, 1000 - DateTime.Now.Millisecond, 1000); // Every second. // HTTP Interface HttpServer HttpServer = new HttpServer (80, 10, true, true, 1); Log.Information ("HTTP Server receiving requests on port " + HttpServer.Port.ToString ()); HttpServer.RegisterAuthenticationMethod (new DigestAuthentication ("The Sensor Realm", GetDigestUserPasswordHash)); HttpServer.RegisterAuthenticationMethod (new SessionAuthentication ()); credentials = LoginCredentials.LoadCredentials (); if (credentials == null) { credentials = new LoginCredentials (); credentials.UserName = "******"; credentials.PasswordHash = CalcHash ("Admin", "Password"); credentials.SaveNew (); } HttpServer.Register ("/", HttpGetRoot, HttpPostRoot, false); // Synchronous, no authentication HttpServer.Register ("/html", HttpGetHtml, false); // Synchronous, no authentication HttpServer.Register ("/historygraph", HttpGetHistoryGraph, false); // Synchronous, no authentication HttpServer.Register ("/credentials", HttpGetCredentials, HttpPostCredentials, false); // Synchronous, no authentication HttpServer.Register ("/xml", HttpGetXml, true); // Synchronous, http authentication HttpServer.Register ("/json", HttpGetJson, true); // Synchronous, http authentication HttpServer.Register ("/turtle", HttpGetTurtle, true); // Synchronous, http authentication HttpServer.Register ("/rdf", HttpGetRdf, true); // Synchronous, http authentication HttpServer.Register ("/event/xml", HttpGetEventXml, true, false); // Asynchronous, http authentication HttpServer.Register ("/event/json", HttpGetEventJson, true, false); // Asynchronous, http authentication HttpServer.Register ("/event/turtle", HttpGetEventTurtle, true, false); // Asynchronous, http authentication HttpServer.Register ("/event/rdf", HttpGetEventRdf, true, false); // Asynchronous, http authentication // HTTPS interface // Certificate must be a valid P12 (PFX) certificate file containing a private key. // X509Certificate2 Certificate = new X509Certificate2 ("Certificate.pfx", "PASSWORD"); // HttpServer HttpsServer = new HttpServer (443, 10, true, true, 1, true, false, Certificate); // // HttpsServer.RegisterAuthenticationMethod (new DigestAuthentication ("The Sensor Realm", GetDigestUserPasswordHash)); // HttpsServer.RegisterAuthenticationMethod (new SessionAuthentication ()); // // foreach (IHttpServerResource Resource in HttpServer.GetResources()) // HttpsServer.Register (Resource); // // Log.Information ("HTTPS Server receiving requests on port " + HttpsServer.Port.ToString ()); // CoAP Interface CoapEndpoint CoapEndpoint = new CoapEndpoint (); Log.Information ("CoAP endpoint receiving requests on port " + CoapEndpoint.Port.ToString ()); //CoapEndpoint.RegisterLineListener (new ConsoleOutLineListenerSink (BinaryFormat.Hexadecimal, true)); CoapEndpoint.RegisterResource ("temp/txt", "Current Temperature, as text.", CoapBlockSize.BlockLimit_64Bytes, false, 30, true, (Request, Payload) => { return FieldNumeric.Format (temperatureC, "C", 1); }); motionTxt = CoapEndpoint.RegisterResource ("motion/txt", "Motion detection, as text.", CoapBlockSize.BlockLimit_64Bytes, false, 10, true, (Request, Payload) => { return motionDetected ? "1" : "0"; }); CoapEndpoint.RegisterResource ("light/txt", "Current Light Density, as text.", CoapBlockSize.BlockLimit_64Bytes, false, 2, true, (Request, Payload) => { return FieldNumeric.Format (lightPercent, "%", 1); }); foreach (CoapBlockSize BlockSize in Enum.GetValues(typeof(CoapBlockSize))) { if (BlockSize == CoapBlockSize.BlockLimit_Datagram) continue; string Bytes = (1 << (4 + (int)BlockSize)).ToString (); CoapEndpoint.RegisterResource ("xml/" + Bytes, "Complete sensor readout, in XML. Control content using query parmeters. Block size=" + Bytes + " bytes.", BlockSize, false, 30, false, CoapGetXml); CoapEndpoint.RegisterResource ("json/" + Bytes, "Complete sensor readout, in JSON. Control content using query parmeters. Block size=" + Bytes + " bytes.", BlockSize, false, 30, false, CoapGetJson); CoapEndpoint.RegisterResource ("turtle/" + Bytes, "Complete sensor readout, in TURTLE. Control content using query parmeters. Block size=" + Bytes + " bytes.", BlockSize, false, 30, false, CoapGetTurtle); CoapEndpoint.RegisterResource ("rdf/" + Bytes, "Complete sensor readout, in RDF. Control content using query parmeters. Block size=" + Bytes + " bytes.", BlockSize, false, 30, false, CoapGetRdf); } // MQTT mqttThread = new Thread (MqttThread); mqttThread.Name = "MQTT"; mqttThread.Priority = ThreadPriority.BelowNormal; mqttThread.Start (); // Main loop Log.Information ("Initialization complete. Application started..."); try { while (executionLed.Value) { System.Threading.Thread.Sleep (1000); } } catch (Exception ex) { Log.Exception (ex); executionLed.Low (); } finally { Log.Information ("Terminating application."); Log.Flush (); Log.Terminate (); Timer.Dispose (); HttpServer.Dispose (); //HttpsServer.Dispose (); CoapEndpoint.Dispose (); if (mqttThread != null) { mqttThread.Abort (); mqttThread = null; } executionLed.Dispose (); measurementLed.Dispose (); errorLed.Dispose (); networkLed.Dispose (); motion.Dispose (); i2cBus.Dispose (); } return 0; }
private static void MonitorCoap () { CoapEndpoint Endpoint = new CoapEndpoint (); //Endpoint.RegisterLineListener (new ConsoleOutLineListenerSink (BinaryFormat.Hexadecimal)); CoapObserver LightObserver = new CoapObserver (Endpoint, true, "192.168.0.15", CoapEndpoint.DefaultCoapPort, "light/txt", string.Empty, 2 * 5); CoapObserver MotionObserver = new CoapObserver (Endpoint, true, "192.168.0.15", CoapEndpoint.DefaultCoapPort, "motion/txt", string.Empty, 10 * 5); bool HasLightValue = false; bool HasMotionValue = false; LightObserver.OnDataReceived += (o, e) => { string s = e.Response as string; double d; if (!string.IsNullOrEmpty (s) && s.EndsWith (" %") && XmlUtilities.TryParseDouble (s.Substring (0, s.Length - 2), out d)) { lightPercent = d; if (!HasLightValue) { HasLightValue = true; if (HasMotionValue) hasValues = true; } CheckControlRules (); } }; MotionObserver.OnDataReceived += (o, e) => { string s = e.Response as string; bool b; if (!string.IsNullOrEmpty (s) && XmlUtilities.TryParseBoolean (s, out b)) { motion = b; if (!HasMotionValue) { HasMotionValue = true; if (HasLightValue) hasValues = true; } CheckControlRules (); } }; try { WaitHandle[] Handles = new WaitHandle[]{ updateLeds, updateAlarm }; while (executing) { try { switch (WaitHandle.WaitAny (Handles, 1000)) { case 0: // Update LEDS int i; lock (synchObject) { i = lastLedMask; } Endpoint.StartPOST (true, "192.168.0.23", CoapEndpoint.DefaultCoapPort, "do/txt", string.Empty, i.ToString (), CoapBlockSize.BlockLimit_64Bytes, null, null); break; case 1: // Update Alarm bool b; lock (synchObject) { b = lastAlarm.Value; } Endpoint.StartPOST (true, "192.168.0.23", CoapEndpoint.DefaultCoapPort, "alarm/txt", string.Empty, b ? "1" : "0", CoapBlockSize.BlockLimit_64Bytes, null, null); if (b) { Thread T = new Thread (SendAlarmMail); T.Priority = ThreadPriority.BelowNormal; T.Name = "SendAlarmMail"; T.Start (); } break; default: // Timeout CheckSubscriptions (30); break; } } catch (ThreadAbortException) { // Don't log. Exception will be automatically re-raised. } catch (Exception ex) { Log.Exception (ex); } } } finally { LightObserver.Dispose (); MotionObserver.Dispose (); Endpoint.Dispose (); } }
protected virtual void SetupClientServer() { this.server = new CoapEndpoint(new int[] { CoapEndpoint.DefaultCoapPort }, null, null, null, false, true, new TextWriterSniffer(Console.Out, BinaryPresentationMethod.Hexadecimal)); this.client = new CoapEndpoint(new int[] { CoapEndpoint.DefaultCoapPort + 2 }, null, null, null, true, false); this.clientCredentials = null; }
public void TestInitialize() { this.client = new CoapEndpoint(new int[] { CoapEndpoint.DefaultCoapPort }, new int[] { CoapEndpoint.DefaultCoapsPort }, null, null, false, false, new TextWriterSniffer(Console.Out, BinaryPresentationMethod.Hexadecimal)); }
/// <summary> /// Event arguments for CoAP response callbacks. /// </summary> /// <param name="Client">UDP Client.</param> /// <param name="Endpoint">CoAP Endpoint.</param> /// <param name="Ok">If the request was successful or not.</param> /// <param name="State">State object passed to the original request.</param> /// <param name="Message">Response message.</param> /// <param name="Resource">Resource</param> internal CoapResponseEventArgs(ClientBase Client, CoapEndpoint Endpoint, bool Ok, object State, CoapMessage Message, CoapResource Resource) : base(Client, Endpoint, Message, Resource) { this.ok = Ok; this.state = State; }
public static int Main (string[] args) { Log.Register (new ConsoleOutEventLog (80)); Log.Information ("Initializing application..."); HttpSocketClient.RegisterHttpProxyUse (false, false); // Don't look for proxies. DB.BackupConnectionString = "Data Source=actuator.db;Version=3;"; DB.BackupProviderName = "Clayster.Library.Data.Providers.SQLiteServer.SQLiteServerProvider"; db = DB.GetDatabaseProxy ("TheActuator"); Console.CancelKeyPress += (object sender, ConsoleCancelEventArgs e) => { e.Cancel = true; executionLed.Low (); }; // HTTP Interface HttpServer HttpServer = new HttpServer (80, 10, true, true, 1); int i; Log.Information ("HTTP Server receiving requests on port " + HttpServer.Port.ToString ()); HttpServer.RegisterAuthenticationMethod (new DigestAuthentication ("The Actuator Realm", GetDigestUserPasswordHash)); HttpServer.RegisterAuthenticationMethod (new SessionAuthentication ()); credentials = LoginCredentials.LoadCredentials (); if (credentials == null) { credentials = new LoginCredentials (); credentials.UserName = "******"; credentials.PasswordHash = CalcHash ("Admin", "Password"); credentials.SaveNew (); } state = State.LoadState (); if (state == null) { state = new State (); state.SaveNew (); } else { for (i = 0; i < 8; i++) digitalOutputs [i].Value = state.GetDO (i + 1); if (state.Alarm) AlarmOn (); else AlarmOff (); } WebServiceAPI wsApi; HttpServer.Register ("/", HttpGetRoot, HttpPostRoot, false); // Synchronous, no authentication HttpServer.Register ("/credentials", HttpGetCredentials, HttpPostCredentials, false); // Synchronous, no authentication HttpServer.Register ("/set", HttpGetSet, HttpPostSet, true); // Synchronous, http authentication HttpServer.Register ("/xml", HttpGetXml, true); // Synchronous, http authentication HttpServer.Register ("/json", HttpGetJson, true); // Synchronous, http authentication HttpServer.Register ("/turtle", HttpGetTurtle, true); // Synchronous, http authentication HttpServer.Register ("/rdf", HttpGetRdf, true); // Synchronous, http authentication HttpServer.Register (wsApi = new WebServiceAPI (), true); // HTTPS interface // Certificate must be a valid P12 (PFX) certificate file containing a private key. // X509Certificate2 Certificate = new X509Certificate2 ("Certificate.pfx", "PASSWORD"); // HttpServer HttpsServer = new HttpServer (443, 10, true, true, 1, true, false, Certificate); // // HttpsServer.RegisterAuthenticationMethod (new DigestAuthentication ("The Actuator Realm", GetDigestUserPasswordHash)); // // foreach (IHttpServerResource Resource in HttpServer.GetResources()) // HttpsServer.Register (Resource); // // Log.Information ("HTTPS Server receiving requests on port " + HttpsServer.Port.ToString ()); // CoAP Interface CoapEndpoint CoapEndpoint = new CoapEndpoint (); Log.Information ("CoAP endpoint receiving requests on port " + CoapEndpoint.Port.ToString ()); //CoapEndpoint.RegisterLineListener (new ConsoleOutLineListenerSink (BinaryFormat.Hexadecimal, true)); for (i = 1; i <= 8; i++) { CoapEndpoint.RegisterResource ("do" + i.ToString () + "/txt", "Digital Output " + i.ToString () + ", as text.", CoapBlockSize.BlockLimit_64Bytes, false, 30, false, CoapGetDigitalOutputTxt, CoapSetDigitalOutputTxt); } CoapEndpoint.RegisterResource ("do/txt", "Digital Outputs, as a number 0-255 as text.", CoapBlockSize.BlockLimit_64Bytes, false, 30, false, CoapGetDigitalOutputsTxt, CoapSetDigitalOutputsTxt); CoapEndpoint.RegisterResource ("alarm/txt", "Alarm Output " + i.ToString () + ", as text.", CoapBlockSize.BlockLimit_64Bytes, false, 30, false, CoapGetAlarmOutputTxt, CoapSetAlarmOutputTxt); foreach (CoapBlockSize BlockSize in Enum.GetValues(typeof(CoapBlockSize))) { if (BlockSize == CoapBlockSize.BlockLimit_Datagram) continue; string Bytes = (1 << (4 + (int)BlockSize)).ToString (); CoapEndpoint.RegisterResource ("xml/" + Bytes, "Complete sensor readout, in XML. Control content using query parmeters. Block size=" + Bytes + " bytes.", BlockSize, false, 30, false, CoapGetXml); CoapEndpoint.RegisterResource ("json/" + Bytes, "Complete sensor readout, in JSON. Control content using query parmeters. Block size=" + Bytes + " bytes.", BlockSize, false, 30, false, CoapGetJson); CoapEndpoint.RegisterResource ("turtle/" + Bytes, "Complete sensor readout, in TURTLE. Control content using query parmeters. Block size=" + Bytes + " bytes.", BlockSize, false, 30, false, CoapGetTurtle); CoapEndpoint.RegisterResource ("rdf/" + Bytes, "Complete sensor readout, in RDF. Control content using query parmeters. Block size=" + Bytes + " bytes.", BlockSize, false, 30, false, CoapGetRdf); } // MQTT MqttClient MqttClient = new MqttClient ("iot.eclipse.org", MqttClient.DefaultPort, "LearningIoTActuator", string.Empty, false); //MqttClient.RegisterLineListener (new ConsoleOutLineListenerSink (BinaryFormat.Hexadecimal)); MqttClient.Open (); MqttClient.CONNECT (20, true); MqttClient.PUBLISH ("Clayster/LearningIoT/Actuator/ao", state.Alarm ? "1" : "0", MqttQoS.QoS1_Acknowledged, true); MqttClient.PUBLISH ("Clayster/LearningIoT/Actuator/do", wsApi.GetDigitalOutputs ().ToString (), MqttQoS.QoS1_Acknowledged, true); for (i = 1; i <= 8; i++) MqttClient.PUBLISH ("Clayster/LearningIoT/Actuator/do" + i.ToString (), wsApi.GetDigitalOutput (i) ? "1" : "0", MqttQoS.QoS1_Acknowledged, true); MqttClient.SUBSCRIBE (new KeyValuePair<string, MqttQoS> ("Clayster/LearningIoT/Actuator/#", MqttQoS.QoS1_Acknowledged)); MqttClient.OnDataPublished += OnMqttDataPublished; Log.Information ("Receiving commands via MQTT from Clayster/LearningIoT/Actuator @ ", EventLevel.Minor, MqttClient.Host + ":" + MqttClient.PortNumber.ToString ()); // Main loop Log.Information ("Initialization complete. Application started..."); try { while (executionLed.Value) { System.Threading.Thread.Sleep (1000); RemoveOldSessions (); } } catch (Exception ex) { Log.Exception (ex); executionLed.Low (); } finally { Log.Information ("Terminating application."); Log.Flush (); Log.Terminate (); HttpServer.Dispose (); //HttpsServer.Dispose (); if (MqttClient != null) MqttClient.Dispose (); executionLed.Dispose (); foreach (DigitalOutput Output in digitalOutputs) Output.Dispose (); if (alarmThread != null) { alarmThread.Abort (); alarmThread = null; } } return 0; }
/// <summary> /// Stops the gateway. /// </summary> public static void Stop() { IDisposable Disposable; Log.Informational("Server shutting down."); /* * if (databaseProvider != null) * File.WriteAllText(appDataFolder + "Stop.xml", databaseProvider.ExportXml(true).Result); */ if (gatewayRunning != null) { gatewayRunning.Release(); gatewayRunning.Dispose(); gatewayRunning = null; } if (ibbClient != null) { ibbClient.Dispose(); ibbClient = null; } if (httpxServer != null) { httpxServer.Dispose(); httpxServer = null; } if (provisioningClient != null) { provisioningClient.Dispose(); provisioningClient = null; } if (thingRegistryClient != null) { thingRegistryClient.Dispose(); thingRegistryClient = null; } if (concentratorServer != null) { concentratorServer.Dispose(); concentratorServer = null; } if (xmppClient != null) { using (ManualResetEvent OfflineSent = new ManualResetEvent(false)) { xmppClient.SetPresence(Availability.Offline, string.Empty, (sender, e) => OfflineSent.Set()); OfflineSent.WaitOne(1000); } foreach (ISniffer Sniffer in xmppClient.Sniffers) { XmppClient.Remove(Sniffer); Disposable = Sniffer as IDisposable; if (Disposable != null) { Disposable.Dispose(); } } xmppClient.Dispose(); xmppClient = null; } if (connectionTimer != null) { connectionTimer.Dispose(); connectionTimer = null; } if (coapEndpoint != null) { coapEndpoint.Dispose(); coapEndpoint = null; } if (webServer != null) { foreach (ISniffer Sniffer in webServer.Sniffers) { webServer.Remove(Sniffer); Disposable = Sniffer as IDisposable; if (Disposable != null) { Disposable.Dispose(); } } webServer.Dispose(); webServer = null; } clientEvents = null; }
/// <summary> /// Starts the gateway. /// </summary> /// <param name="ConsoleOutput">If console output is permitted.</param> public static bool Start(bool ConsoleOutput) { gatewayRunning = new Semaphore(1, 1, "Waher.IoTGateway.Running"); if (!gatewayRunning.WaitOne(1000)) { return(false); // Is running in another process. } Semaphore StartingServer = new Semaphore(1, 1, "Waher.IoTGateway.Starting"); if (!StartingServer.WaitOne(1000)) { gatewayRunning.Release(); gatewayRunning.Dispose(); gatewayRunning = null; StartingServer.Dispose(); return(false); // Being started in another process. } try { Initialize(); appDataFolder = Environment.GetFolderPath(Environment.SpecialFolder.CommonApplicationData); if (!appDataFolder.EndsWith(new string(Path.DirectorySeparatorChar, 1))) { appDataFolder += Path.DirectorySeparatorChar; } appDataFolder += "IoT Gateway" + Path.DirectorySeparatorChar; Log.Register(new XmlFileEventSink("XML File Event Sink", appDataFolder + "Events" + Path.DirectorySeparatorChar + "Event Log %YEAR%-%MONTH%-%DAY%T%HOUR%.xml", appDataFolder + "Transforms" + Path.DirectorySeparatorChar + "EventXmlToHtml.xslt", 7)); Log.Informational("Server starting up."); beforeUninstallCommandNr = Gateway.RegisterServiceCommand(BeforeUninstall); rootFolder = appDataFolder + "Root" + Path.DirectorySeparatorChar; if (!Directory.Exists(rootFolder)) { appDataFolder = string.Empty; rootFolder = "Root" + Path.DirectorySeparatorChar; } Types.SetModuleParameter("AppData", appDataFolder); Types.SetModuleParameter("Root", rootFolder); scheduler = new Scheduler(); rnd = RandomNumberGenerator.Create(); Task.Run(() => CodeContent.GraphViz.Init()); XmlDocument Config = new XmlDocument(); string GatewayConfigFileName = appDataFolder + "Gateway.config"; if (!File.Exists(GatewayConfigFileName)) { GatewayConfigFileName = "Gateway.config"; } Config.Load(GatewayConfigFileName); XSL.Validate("Gateway.config", Config, "GatewayConfiguration", "http://waher.se/Schema/GatewayConfiguration.xsd", XSL.LoadSchema(typeof(Gateway).Namespace + ".Schema.GatewayConfiguration.xsd", typeof(Gateway).Assembly)); domain = Config.DocumentElement["Domain"].InnerText; XmlElement DatabaseConfig = Config.DocumentElement["Database"]; if (!CommonTypes.TryParse(DatabaseConfig.Attributes["encrypted"].Value, out bool Encrypted)) { Encrypted = true; } databaseProvider = new FilesProvider(appDataFolder + DatabaseConfig.Attributes["folder"].Value, DatabaseConfig.Attributes["defaultCollectionName"].Value, int.Parse(DatabaseConfig.Attributes["blockSize"].Value), int.Parse(DatabaseConfig.Attributes["blocksInCache"].Value), int.Parse(DatabaseConfig.Attributes["blobBlockSize"].Value), Encoding.UTF8, int.Parse(DatabaseConfig.Attributes["timeoutMs"].Value), Encrypted, false); Database.Register(databaseProvider); PersistedEventLog PersistedEventLog = new PersistedEventLog(7, new TimeSpan(4, 15, 0)); Log.Register(PersistedEventLog); PersistedEventLog.Queue(new Event(EventType.Informational, "Server starting up.", string.Empty, string.Empty, string.Empty, EventLevel.Minor, string.Empty, string.Empty, string.Empty)); xmppConfigFileName = Config.DocumentElement["XmppClient"].Attributes["configFileName"].Value; if (!File.Exists(xmppConfigFileName)) { xmppConfigFileName = appDataFolder + xmppConfigFileName; } if (ConsoleOutput) { xmppConfiguration = SimpleXmppConfiguration.GetConfigUsingSimpleConsoleDialog(xmppConfigFileName, Guid.NewGuid().ToString().Replace("-", string.Empty), // Default user name. Guid.NewGuid().ToString().Replace("-", string.Empty), // Default password. FormSignatureKey, FormSignatureSecret, typeof(Gateway).Assembly); } else if (File.Exists(xmppConfigFileName)) { xmppConfiguration = new SimpleXmppConfiguration(xmppConfigFileName); RuntimeSettings.Set("XMPP.CONFIG", xmppConfiguration.ExportSimpleXmppConfiguration()); } else { string XmppConfig = RuntimeSettings.Get("XMPP.CONFIG", string.Empty); XmlDocument Doc = new XmlDocument(); Doc.LoadXml(XmppConfig); xmppConfiguration = new SimpleXmppConfiguration(Doc); } xmppClient = xmppConfiguration.GetClient("en", typeof(Gateway).Assembly, false); xmppClient.AllowRegistration(FormSignatureKey, FormSignatureSecret); xmppClient.OnValidateSender += XmppClient_OnValidateSender; Types.SetModuleParameter("XMPP", xmppClient); if (xmppConfiguration.Sniffer) { ISniffer Sniffer; if (ConsoleOutput) { Sniffer = new ConsoleOutSniffer(BinaryPresentationMethod.ByteCount, LineEnding.PadWithSpaces); xmppClient.Add(Sniffer); } Sniffer = new XmlFileSniffer(appDataFolder + "XMPP" + Path.DirectorySeparatorChar + "XMPP Log %YEAR%-%MONTH%-%DAY%T%HOUR%.xml", appDataFolder + "Transforms" + Path.DirectorySeparatorChar + "SnifferXmlToHtml.xslt", 7, BinaryPresentationMethod.ByteCount); xmppClient.Add(Sniffer); } if (!string.IsNullOrEmpty(xmppConfiguration.Events)) { Log.Register(new XmppEventSink("XMPP Event Sink", xmppClient, xmppConfiguration.Events, false)); } if (!string.IsNullOrEmpty(xmppConfiguration.ThingRegistry)) { thingRegistryClient = new ThingRegistryClient(xmppClient, xmppConfiguration.ThingRegistry); thingRegistryClient.Claimed += ThingRegistryClient_Claimed; thingRegistryClient.Disowned += ThingRegistryClient_Disowned; thingRegistryClient.Removed += ThingRegistryClient_Removed; } if (!string.IsNullOrEmpty(xmppConfiguration.Provisioning)) { provisioningClient = new ProvisioningClient(xmppClient, xmppConfiguration.Provisioning); } DateTime Now = DateTime.Now; int MsToNext = 60000 - (Now.Second * 1000 + Now.Millisecond); connectionTimer = new Timer(CheckConnection, null, MsToNext, 60000); xmppClient.OnStateChanged += XmppClient_OnStateChanged; xmppClient.OnPresenceSubscribe += XmppClient_OnPresenceSubscribe; xmppClient.OnPresenceUnsubscribe += XmppClient_OnPresenceUnsubscribe; xmppClient.OnRosterItemUpdated += XmppClient_OnRosterItemUpdated; ibbClient = new Networking.XMPP.InBandBytestreams.IbbClient(xmppClient, MaxChunkSize); Types.SetModuleParameter("IBB", ibbClient); socksProxy = new Networking.XMPP.P2P.SOCKS5.Socks5Proxy(xmppClient); Types.SetModuleParameter("SOCKS5", socksProxy); string CertificateLocalFileName = Config.DocumentElement["Certificate"].Attributes["configFileName"].Value; string CertificateFileName; string CertificateXml; string CertificatePassword; byte[] CertificateRaw; try { CertificateRaw = Convert.FromBase64String(RuntimeSettings.Get("CERTIFICATE.BASE64", string.Empty)); CertificatePassword = RuntimeSettings.Get("CERTIFICATE.PWD", string.Empty); certificate = new X509Certificate2(CertificateRaw, CertificatePassword); } catch (Exception) { certificate = null; } if (File.Exists(CertificateFileName = appDataFolder + CertificateLocalFileName)) { CertificateXml = File.ReadAllText(CertificateFileName); } else if (File.Exists(CertificateFileName = CertificateLocalFileName) && certificate == null) { CertificateXml = File.ReadAllText(CertificateFileName); } else { CertificateFileName = null; CertificateXml = null; } if (CertificateXml != null) { XmlDocument CertificateConfig = new XmlDocument(); CertificateConfig.LoadXml(CertificateXml); XSL.Validate(CertificateLocalFileName, CertificateConfig, "CertificateConfiguration", "http://waher.se/Schema/CertificateConfiguration.xsd", XSL.LoadSchema(typeof(Gateway).Namespace + ".Schema.CertificateConfiguration.xsd", typeof(Gateway).Assembly)); CertificateLocalFileName = CertificateConfig.DocumentElement["FileName"].InnerText; if (File.Exists(appDataFolder + CertificateLocalFileName)) { CertificateLocalFileName = appDataFolder + CertificateLocalFileName; } CertificateRaw = File.ReadAllBytes(CertificateLocalFileName); CertificatePassword = CertificateConfig.DocumentElement["Password"].InnerText; certificate = new X509Certificate2(CertificateRaw, CertificatePassword); RuntimeSettings.Set("CERTIFICATE.BASE64", Convert.ToBase64String(CertificateRaw)); RuntimeSettings.Set("CERTIFICATE.PWD", CertificatePassword); if (CertificateLocalFileName != "certificate.pfx" || CertificatePassword != "testexamplecom") { try { File.Delete(CertificateLocalFileName); } catch (Exception) { Log.Warning("Unable to delete " + CertificateLocalFileName + " after importing it into the encrypted database."); } try { File.Delete(CertificateFileName); } catch (Exception) { Log.Warning("Unable to delete " + CertificateFileName + " after importing it into the encrypted database."); } } } foreach (XmlNode N in Config.DocumentElement["Ports"].ChildNodes) { if (N.LocalName == "Port") { XmlElement E = (XmlElement)N; string Protocol = XML.Attribute(E, "protocol"); if (!string.IsNullOrEmpty(Protocol) && int.TryParse(E.InnerText, out int Port)) { ports.AddLast(new KeyValuePair <string, int>(Protocol, Port)); } } } webServer = new HttpServer(GetConfigPorts("HTTP"), GetConfigPorts("HTTPS"), certificate); Types.SetModuleParameter("HTTP", webServer); StringBuilder sb = new StringBuilder(); foreach (int Port in webServer.OpenPorts) { sb.AppendLine(Port.ToString()); } try { File.WriteAllText(appDataFolder + "Ports.txt", sb.ToString()); } catch (Exception ex) { Log.Critical(ex); } HttpFolderResource HttpFolderResource; HttpxProxy HttpxProxy; webServer.Register(new HttpFolderResource("/Graphics", "Graphics", false, false, true, false)); // TODO: Add authentication mechanisms for PUT & DELETE. webServer.Register(new HttpFolderResource("/highlight", "Highlight", false, false, true, false)); // Syntax highlighting library, provided by http://highlightjs.org webServer.Register(HttpFolderResource = new HttpFolderResource(string.Empty, rootFolder, false, false, true, true)); // TODO: Add authentication mechanisms for PUT & DELETE. webServer.Register(HttpxProxy = new HttpxProxy("/HttpxProxy", xmppClient, MaxChunkSize)); webServer.Register("/", (req, resp) => { throw new TemporaryRedirectException(Config.DocumentElement["DefaultPage"].InnerText); }); webServer.Register(clientEvents = new ClientEvents()); HttpFolderResource.AllowTypeConversion(); MarkdownToHtmlConverter.EmojiSource = Emoji1_24x24; XmlElement FileFolders = Config.DocumentElement["FileFolders"]; if (FileFolders != null) { foreach (XmlNode N in FileFolders.ChildNodes) { if (N is XmlElement E && E.LocalName == "FileFolder") { string WebFolder = XML.Attribute(E, "webFolder"); string FolderPath = XML.Attribute(E, "folderPath"); webServer.Register(new HttpFolderResource(WebFolder, FolderPath, false, false, true, true)); } } } httpxServer = new HttpxServer(xmppClient, webServer, MaxChunkSize); Types.SetModuleParameter("HTTPX", HttpxProxy); Types.SetModuleParameter("HTTPXS", httpxServer); HttpxProxy.IbbClient = ibbClient; httpxServer.IbbClient = ibbClient; HttpxProxy.Socks5Proxy = socksProxy; httpxServer.Socks5Proxy = socksProxy; if (xmppConfiguration.Sniffer) { ISniffer Sniffer; Sniffer = new XmlFileSniffer(appDataFolder + "HTTP" + Path.DirectorySeparatorChar + "HTTP Log %YEAR%-%MONTH%-%DAY%T%HOUR%.xml", appDataFolder + "Transforms" + Path.DirectorySeparatorChar + "SnifferXmlToHtml.xslt", 7, BinaryPresentationMethod.ByteCount); webServer.Add(Sniffer); } coapEndpoint = new CoapEndpoint(); Types.SetModuleParameter("CoAP", coapEndpoint); concentratorServer = new ConcentratorServer(xmppClient, provisioningClient, new MeteringTopology()); Types.SetModuleParameter("Concentrator", concentratorServer); Types.SetModuleParameter("Sensor", concentratorServer.SensorServer); Types.SetModuleParameter("Control", concentratorServer.ControlServer); } catch (Exception ex) { Log.Critical(ex); gatewayRunning.Release(); gatewayRunning.Dispose(); gatewayRunning = null; StartingServer.Release(); StartingServer.Dispose(); ExceptionDispatchInfo.Capture(ex).Throw(); } Task.Run(async() => { try { try { string BinaryFolder = AppDomain.CurrentDomain.BaseDirectory; string[] LanguageFiles = Directory.GetFiles(BinaryFolder, "*.lng", SearchOption.AllDirectories); string FileName; if (LanguageFiles.Length > 0) { XmlSchema Schema = XSL.LoadSchema(Translator.SchemaResource, typeof(Translator).Assembly); foreach (string LanguageFile in LanguageFiles) { try { FileName = LanguageFile; if (FileName.StartsWith(BinaryFolder)) { FileName = FileName.Substring(BinaryFolder.Length); } DateTime LastWriteTime = File.GetLastWriteTime(LanguageFile); DateTime LastImportedTime = await RuntimeSettings.GetAsync(FileName, DateTime.MinValue); if (LastWriteTime > LastImportedTime) { Log.Informational("Importing language file.", FileName); string Xml = File.ReadAllText(LanguageFile); XmlDocument Doc = new XmlDocument(); Doc.LoadXml(Xml); XSL.Validate(FileName, Doc, Translator.SchemaRoot, Translator.SchemaNamespace, Schema); using (XmlReader r = new XmlNodeReader(Doc)) { await Translator.ImportAsync(r); } RuntimeSettings.Set(FileName, LastWriteTime); } } catch (Exception ex) { Log.Critical(ex, LanguageFile); } } } Types.StartAllModules(int.MaxValue); } finally { StartingServer.Release(); StartingServer.Dispose(); } } catch (Exception ex) { Log.Critical(ex); } finally { xmppClient.Connect(); } }); return(true); }
private async void Init() { try { Log.Informational("Starting application."); Types.Initialize( typeof(FilesProvider).GetTypeInfo().Assembly, typeof(RuntimeSettings).GetTypeInfo().Assembly, typeof(IContentEncoder).GetTypeInfo().Assembly, typeof(ICoapContentFormat).GetTypeInfo().Assembly, typeof(IDtlsCredentials).GetTypeInfo().Assembly, typeof(App).GetTypeInfo().Assembly); db = new FilesProvider(Windows.Storage.ApplicationData.Current.LocalFolder.Path + Path.DirectorySeparatorChar + "Data", "Default", 8192, 1000, 8192, Encoding.UTF8, 10000); Database.Register(db); await db.RepairIfInproperShutdown(null); await db.Start(); DeviceInformationCollection Devices = await UsbSerial.listAvailableDevicesAsync(); DeviceInformation DeviceInfo = this.FindDevice(Devices, "Arduino", "USB Serial Device"); if (DeviceInfo is null) { Log.Error("Unable to find Arduino device."); } else { Log.Informational("Connecting to " + DeviceInfo.Name); this.arduinoUsb = new UsbSerial(DeviceInfo); this.arduinoUsb.ConnectionEstablished += () => Log.Informational("USB connection established."); this.arduino = new RemoteDevice(this.arduinoUsb); this.arduino.DeviceReady += () => { Log.Informational("Device ready."); this.arduino.pinMode(13, PinMode.OUTPUT); // Onboard LED. this.arduino.digitalWrite(13, PinState.HIGH); this.arduino.pinMode(8, PinMode.INPUT); // PIR sensor (motion detection). PinState Pin8 = this.arduino.digitalRead(8); this.lastMotion = Pin8 == PinState.HIGH; MainPage.Instance.DigitalPinUpdated(8, Pin8); this.arduino.pinMode(9, PinMode.OUTPUT); // Relay. this.arduino.digitalWrite(9, 0); // Relay set to 0 this.arduino.pinMode("A0", PinMode.ANALOG); // Light sensor. MainPage.Instance.AnalogPinUpdated("A0", this.arduino.analogRead("A0")); this.sampleTimer = new Timer(this.SampleValues, null, 1000 - DateTime.Now.Millisecond, 1000); }; this.arduino.AnalogPinUpdated += (pin, value) => { MainPage.Instance.AnalogPinUpdated(pin, value); }; this.arduino.DigitalPinUpdated += (pin, value) => { MainPage.Instance.DigitalPinUpdated(pin, value); if (pin == 8) { this.lastMotion = (value == PinState.HIGH); this.motionResource?.TriggerAll(); this.momentaryResource?.TriggerAll(); } }; this.arduinoUsb.ConnectionFailed += message => { Log.Error("USB connection failed: " + message); }; this.arduinoUsb.ConnectionLost += message => { Log.Error("USB connection lost: " + message); }; this.arduinoUsb.begin(57600, SerialConfig.SERIAL_8N1); } this.deviceId = await RuntimeSettings.GetAsync("DeviceId", string.Empty); if (string.IsNullOrEmpty(this.deviceId)) { this.deviceId = Guid.NewGuid().ToString().Replace("-", string.Empty); await RuntimeSettings.SetAsync("DeviceId", this.deviceId); } Log.Informational("Device ID: " + this.deviceId); /************************************************************************************ * To create an unencrypted CoAP Endpoint on the default CoAP port: * * this.coapEndpoint = new CoapEndpoint(); * * To create an unencrypted CoAP Endpoint on the default CoAP port, * with a sniffer that outputs communication to the window: * * this.coapEndpoint = new CoapEndpoint(new LogSniffer()); * * To create a DTLS encrypted CoAP endpoint, on the default CoAPS port, using * the users defined in the IUserSource users: * * this.coapEndpoint = new CoapEndpoint(CoapEndpoint.DefaultCoapsPort, this.users); * * To create a CoAP endpoint, that listens to both the default CoAP port, for * unencrypted communication, and the default CoAPS port, for encrypted, * authenticated and authorized communication, using * the users defined in the IUserSource users. Only users having the given * privilege (if not empty) will be authorized to access resources on the endpoint: * * this.coapEndpoint = new CoapEndpoint(new int[] { CoapEndpoint.DefaultCoapPort }, * new int[] { CoapEndpoint.DefaultCoapsPort }, this.users, "PRIVILEGE", false, false); * ************************************************************************************/ this.coapEndpoint = new CoapEndpoint(new int[] { CoapEndpoint.DefaultCoapPort }, new int[] { CoapEndpoint.DefaultCoapsPort }, this.users, string.Empty, false, false); this.lightResource = this.coapEndpoint.Register("/Light", (req, resp) => { string s; if (this.lastLight.HasValue) { s = ToString(this.lastLight.Value, 2) + " %"; } else { s = "-"; } resp.Respond(CoapCode.Content, s, 64); }, Notifications.Unacknowledged, "Light, in %.", null, null, new int[] { PlainText.ContentFormatCode }); this.lightResource?.TriggerAll(new TimeSpan(0, 0, 5)); this.motionResource = this.coapEndpoint.Register("/Motion", (req, resp) => { string s; if (this.lastMotion.HasValue) { s = this.lastMotion.Value ? "true" : "false"; } else { s = "-"; } resp.Respond(CoapCode.Content, s, 64); }, Notifications.Acknowledged, "Motion detector.", null, null, new int[] { PlainText.ContentFormatCode }); this.motionResource?.TriggerAll(new TimeSpan(0, 1, 0)); this.momentaryResource = this.coapEndpoint.Register("/Momentary", (req, resp) => { if (req.IsAcceptable(Xml.ContentFormatCode)) { this.ReturnMomentaryAsXml(req, resp); } else if (req.IsAcceptable(Json.ContentFormatCode)) { this.ReturnMomentaryAsJson(req, resp); } else if (req.IsAcceptable(PlainText.ContentFormatCode)) { this.ReturnMomentaryAsPlainText(req, resp); } else if (req.Accept.HasValue) { throw new CoapException(CoapCode.NotAcceptable); } else { this.ReturnMomentaryAsPlainText(req, resp); } }, Notifications.Acknowledged, "Momentary values.", null, null, new int[] { Xml.ContentFormatCode, Json.ContentFormatCode, PlainText.ContentFormatCode }); this.momentaryResource?.TriggerAll(new TimeSpan(0, 0, 5)); } catch (Exception ex) { Log.Emergency(ex); MessageDialog Dialog = new MessageDialog(ex.Message, "Error"); await MainPage.Instance.Dispatcher.RunAsync(CoreDispatcherPriority.Normal, async() => await Dialog.ShowAsync()); } }
private async void Init() { try { Log.Informational("Starting application."); Types.Initialize( typeof(FilesProvider).GetTypeInfo().Assembly, typeof(RuntimeSettings).GetTypeInfo().Assembly, typeof(IContentEncoder).GetTypeInfo().Assembly, typeof(ICoapContentFormat).GetTypeInfo().Assembly, typeof(IDtlsCredentials).GetTypeInfo().Assembly, typeof(Lwm2mClient).GetTypeInfo().Assembly, typeof(App).GetTypeInfo().Assembly); db = new FilesProvider(Windows.Storage.ApplicationData.Current.LocalFolder.Path + Path.DirectorySeparatorChar + "Data", "Default", 8192, 1000, 8192, Encoding.UTF8, 10000); Database.Register(db); await db.RepairIfInproperShutdown(null); await db.Start(); #if GPIO gpio = GpioController.GetDefault(); if (gpio != null) { if (gpio.TryOpenPin(gpioOutputPin, GpioSharingMode.Exclusive, out this.gpioPin, out GpioOpenStatus Status) && Status == GpioOpenStatus.PinOpened) { if (this.gpioPin.IsDriveModeSupported(GpioPinDriveMode.Output)) { this.gpioPin.SetDriveMode(GpioPinDriveMode.Output); this.output = await RuntimeSettings.GetAsync("Actuator.Output", false); this.gpioPin.Write(this.output.Value ? GpioPinValue.High : GpioPinValue.Low); this.digitalOutput0?.Set(this.output.Value); this.actuation0?.Set(this.output.Value); await MainPage.Instance.OutputSet(this.output.Value); Log.Informational("Setting Control Parameter.", string.Empty, "Startup", new KeyValuePair <string, object>("Output", this.output.Value)); } else { Log.Error("Output mode not supported for GPIO pin " + gpioOutputPin.ToString()); } } else { Log.Error("Unable to get access to GPIO pin " + gpioOutputPin.ToString()); } } #else DeviceInformationCollection Devices = await UsbSerial.listAvailableDevicesAsync(); DeviceInformation DeviceInfo = this.FindDevice(Devices, "Arduino", "USB Serial Device"); if (DeviceInfo is null) { Log.Error("Unable to find Arduino device."); } else { Log.Informational("Connecting to " + DeviceInfo.Name); this.arduinoUsb = new UsbSerial(DeviceInfo); this.arduinoUsb.ConnectionEstablished += () => Log.Informational("USB connection established."); this.arduino = new RemoteDevice(this.arduinoUsb); this.arduino.DeviceReady += async() => { try { Log.Informational("Device ready."); this.arduino.pinMode(13, PinMode.OUTPUT); // Onboard LED. this.arduino.digitalWrite(13, PinState.HIGH); this.arduino.pinMode(8, PinMode.INPUT); // PIR sensor (motion detection). this.arduino.pinMode(9, PinMode.OUTPUT); // Relay. this.output = await RuntimeSettings.GetAsync("Actuator.Output", false); this.arduino.digitalWrite(9, this.output.Value ? PinState.HIGH : PinState.LOW); this.digitalOutput0?.Set(this.output.Value); this.actuation0?.Set(this.output.Value); await MainPage.Instance.OutputSet(this.output.Value); Log.Informational("Setting Control Parameter.", string.Empty, "Startup", new KeyValuePair <string, object>("Output", this.output.Value)); this.arduino.pinMode("A0", PinMode.ANALOG); // Light sensor. } catch (Exception ex) { Log.Critical(ex); } }; this.arduinoUsb.ConnectionFailed += message => { Log.Error("USB connection failed: " + message); }; this.arduinoUsb.ConnectionLost += message => { Log.Error("USB connection lost: " + message); }; this.arduinoUsb.begin(57600, SerialConfig.SERIAL_8N1); } #endif this.deviceId = await RuntimeSettings.GetAsync("DeviceId", string.Empty); if (string.IsNullOrEmpty(this.deviceId)) { this.deviceId = Guid.NewGuid().ToString().Replace("-", string.Empty); await RuntimeSettings.SetAsync("DeviceId", this.deviceId); } Log.Informational("Device ID: " + this.deviceId); /************************************************************************************ * To create an unencrypted CoAP Endpoint on the default CoAP port: * * this.coapEndpoint = new CoapEndpoint(); * * To create an unencrypted CoAP Endpoint on the default CoAP port, * with a sniffer that outputs communication to the window: * * this.coapEndpoint = new CoapEndpoint(new LogSniffer()); * * To create a DTLS encrypted CoAP endpoint, on the default CoAPS port, using * the users defined in the IUserSource users: * * this.coapEndpoint = new CoapEndpoint(CoapEndpoint.DefaultCoapsPort, this.users); * * To create a CoAP endpoint, that listens to both the default CoAP port, for * unencrypted communication, and the default CoAPS port, for encrypted, * authenticated and authorized communication, using * the users defined in the IUserSource users. Only users having the given * privilege (if not empty) will be authorized to access resources on the endpoint: * * this.coapEndpoint = new CoapEndpoint(new int[] { CoapEndpoint.DefaultCoapPort }, * new int[] { CoapEndpoint.DefaultCoapsPort }, this.users, "PRIVILEGE", false, false); * ************************************************************************************/ this.coapEndpoint = new CoapEndpoint(new int[] { CoapEndpoint.DefaultCoapPort }, new int[] { CoapEndpoint.DefaultCoapsPort }, this.users, string.Empty, false, false); this.outputResource = this.coapEndpoint.Register("/Output", (req, resp) => { string s; if (this.output.HasValue) { s = this.output.Value ? "true" : "false"; } else { s = "-"; } resp.Respond(CoapCode.Content, s, 64); }, async(req, resp) => { try { string s = req.Decode() as string; if (s is null && req.Payload != null) { s = Encoding.UTF8.GetString(req.Payload); } if (s is null || !CommonTypes.TryParse(s, out bool Output)) { resp.RST(CoapCode.BadRequest); } else { resp.Respond(CoapCode.Changed); await this.SetOutput(Output, req.From.ToString()); } } catch (Exception ex) { Log.Critical(ex); } }, Notifications.Acknowledged, "Digital Output.", null, null,
private async void Init() { try { Log.Informational("Starting application."); Types.Initialize( typeof(FilesProvider).GetTypeInfo().Assembly, typeof(RuntimeSettings).GetTypeInfo().Assembly, typeof(IContentEncoder).GetTypeInfo().Assembly, typeof(ICoapContentFormat).GetTypeInfo().Assembly, typeof(IDtlsCredentials).GetTypeInfo().Assembly, typeof(Lwm2mClient).GetTypeInfo().Assembly, typeof(App).GetTypeInfo().Assembly); Database.Register(new FilesProvider(Windows.Storage.ApplicationData.Current.LocalFolder.Path + Path.DirectorySeparatorChar + "Data", "Default", 8192, 1000, 8192, Encoding.UTF8, 10000)); #if GPIO gpio = GpioController.GetDefault(); if (gpio != null) { if (gpio.TryOpenPin(gpioOutputPin, GpioSharingMode.Exclusive, out this.gpioPin, out GpioOpenStatus Status) && Status == GpioOpenStatus.PinOpened) { if (this.gpioPin.IsDriveModeSupported(GpioPinDriveMode.Output)) { this.gpioPin.SetDriveMode(GpioPinDriveMode.Output); this.output = await RuntimeSettings.GetAsync("Actuator.Output", false); this.gpioPin.Write(this.output.Value ? GpioPinValue.High : GpioPinValue.Low); this.digitalOutput0?.Set(this.output.Value); this.actuation0?.Set(this.output.Value); await MainPage.Instance.OutputSet(this.output.Value); Log.Informational("Setting Control Parameter.", string.Empty, "Startup", new KeyValuePair <string, object>("Output", this.output.Value)); } else { Log.Error("Output mode not supported for GPIO pin " + gpioOutputPin.ToString()); } } else { Log.Error("Unable to get access to GPIO pin " + gpioOutputPin.ToString()); } } #else DeviceInformationCollection Devices = await UsbSerial.listAvailableDevicesAsync(); foreach (DeviceInformation DeviceInfo in Devices) { if (DeviceInfo.IsEnabled && DeviceInfo.Name.StartsWith("Arduino")) { Log.Informational("Connecting to " + DeviceInfo.Name); this.arduinoUsb = new UsbSerial(DeviceInfo); this.arduinoUsb.ConnectionEstablished += () => Log.Informational("USB connection established."); this.arduino = new RemoteDevice(this.arduinoUsb); this.arduino.DeviceReady += async() => { try { Log.Informational("Device ready."); this.arduino.pinMode(13, PinMode.OUTPUT); // Onboard LED. this.arduino.digitalWrite(13, PinState.HIGH); this.arduino.pinMode(8, PinMode.INPUT); // PIR sensor (motion detection). this.arduino.pinMode(9, PinMode.OUTPUT); // Relay. this.output = await RuntimeSettings.GetAsync("Actuator.Output", false); this.arduino.digitalWrite(9, this.output.Value ? PinState.HIGH : PinState.LOW); this.digitalOutput0?.Set(this.output.Value); this.actuation0?.Set(this.output.Value); await MainPage.Instance.OutputSet(this.output.Value); Log.Informational("Setting Control Parameter.", string.Empty, "Startup", new KeyValuePair <string, object>("Output", this.output.Value)); this.arduino.pinMode("A0", PinMode.ANALOG); // Light sensor. } catch (Exception ex) { Log.Critical(ex); } }; this.arduinoUsb.ConnectionFailed += message => { Log.Error("USB connection failed: " + message); }; this.arduinoUsb.ConnectionLost += message => { Log.Error("USB connection lost: " + message); }; this.arduinoUsb.begin(57600, SerialConfig.SERIAL_8N1); break; } } #endif this.deviceId = await RuntimeSettings.GetAsync("DeviceId", string.Empty); if (string.IsNullOrEmpty(this.deviceId)) { this.deviceId = Guid.NewGuid().ToString().Replace("-", string.Empty); await RuntimeSettings.SetAsync("DeviceId", this.deviceId); } Log.Informational("Device ID: " + this.deviceId); /************************************************************************************ * To create an unencrypted CoAP Endpoint on the default CoAP port: * * this.coapEndpoint = new CoapEndpoint(); * * To create an unencrypted CoAP Endpoint on the default CoAP port, * with a sniffer that outputs communication to the window: * * this.coapEndpoint = new CoapEndpoint(new LogSniffer()); * * To create a DTLS encrypted CoAP endpoint, on the default CoAPS port, using * the users defined in the IUserSource users: * * this.coapEndpoint = new CoapEndpoint(CoapEndpoint.DefaultCoapsPort, this.users); * * To create a CoAP endpoint, that listens to both the default CoAP port, for * unencrypted communication, and the default CoAPS port, for encrypted, * authenticated and authorized communication, using * the users defined in the IUserSource users. Only users having the given * privilege (if not empty) will be authorized to access resources on the endpoint: * * this.coapEndpoint = new CoapEndpoint(new int[] { CoapEndpoint.DefaultCoapPort }, * new int[] { CoapEndpoint.DefaultCoapsPort }, this.users, "PRIVILEGE", false, false); * ************************************************************************************/ this.coapEndpoint = new CoapEndpoint(new int[] { CoapEndpoint.DefaultCoapPort }, new int[] { CoapEndpoint.DefaultCoapsPort }, this.users, string.Empty, false, false); this.outputResource = this.coapEndpoint.Register("/Output", (req, resp) => { string s; if (this.output.HasValue) { s = this.output.Value ? "true" : "false"; } else { s = "-"; } resp.Respond(CoapCode.Content, s, 64); }, async(req, resp) => { try { string s = req.Decode() as string; if (s == null && req.Payload != null) { s = Encoding.UTF8.GetString(req.Payload); } if (s == null || !CommonTypes.TryParse(s, out bool Output)) { resp.RST(CoapCode.BadRequest); } else { resp.Respond(CoapCode.Changed); await this.SetOutput(Output, req.From.ToString()); } } catch (Exception ex) { Log.Critical(ex); } }, Notifications.Acknowledged, "Digital Output.", null, null, new int[] { PlainText.ContentFormatCode }); this.outputResource?.TriggerAll(new TimeSpan(0, 1, 0)); this.lwm2mClient = new Lwm2mClient("MIoT:Actuator:" + this.deviceId, this.coapEndpoint, new Lwm2mSecurityObject(), new Lwm2mServerObject(), new Lwm2mAccessControlObject(), new Lwm2mDeviceObject("Waher Data AB", "ActuatorLwm2m", this.deviceId, "1.0", "Actuator", "1.0", "1.0"), new DigitalOutput(this.digitalOutput0 = new DigitalOutputInstance(0, this.output.HasValue && this.output.Value, "Relay")), new Actuation(this.actuation0 = new ActuationInstance(0, this.output.HasValue && this.output.Value, "Relay"))); this.digitalOutput0.OnRemoteUpdate += async(Sender, e) => { try { await this.SetOutput(((DigitalOutputInstance)Sender).Value, e.Request.From.ToString()); } catch (Exception ex) { Log.Critical(ex); } }; this.actuation0.OnRemoteUpdate += async(Sender, e) => { try { await this.SetOutput(((ActuationInstance)Sender).Value, e.Request.From.ToString()); } catch (Exception ex) { Log.Critical(ex); } }; await this.lwm2mClient.LoadBootstrapInfo(); this.lwm2mClient.OnStateChanged += (sender, e) => { Log.Informational("LWM2M state changed to " + this.lwm2mClient.State.ToString() + "."); }; this.lwm2mClient.OnBootstrapCompleted += (sender, e) => { Log.Informational("Bootstrap procedure completed."); }; this.lwm2mClient.OnBootstrapFailed += (sender, e) => { Log.Error("Bootstrap procedure failed."); this.coapEndpoint.ScheduleEvent(async(P) => { try { await this.RequestBootstrap(); } catch (Exception ex) { Log.Critical(ex); } }, DateTime.Now.AddMinutes(15), null); }; this.lwm2mClient.OnRegistrationSuccessful += (sender, e) => { Log.Informational("Server registration completed."); }; this.lwm2mClient.OnRegistrationFailed += (sender, e) => { Log.Error("Server registration failed."); }; this.lwm2mClient.OnDeregistrationSuccessful += (sender, e) => { Log.Informational("Server deregistration completed."); }; this.lwm2mClient.OnDeregistrationFailed += (sender, e) => { Log.Error("Server deregistration failed."); }; this.lwm2mClient.OnRebootRequest += async(sender, e) => { Log.Warning("Reboot is requested."); try { await this.RequestBootstrap(); } catch (Exception ex) { Log.Critical(ex); } }; await this.RequestBootstrap(); } catch (Exception ex) { Log.Emergency(ex); MessageDialog Dialog = new MessageDialog(ex.Message, "Error"); await MainPage.Instance.Dispatcher.RunAsync(CoreDispatcherPriority.Normal, async() => await Dialog.ShowAsync()); } }