/// <summary> /// Gets the control form from a controller. /// </summary> /// <param name="Jid">JID of controller.</param> /// <param name="Nodes">Node references</param> /// <param name="ServiceToken">Service token.</param> /// <param name="DeviceToken">Device token.</param> /// <param name="UserToken">User token.</param> /// <param name="Callback">Callback method.</param> /// <param name="State">State object to pass on to callback method.</param> public void GetForm(string Jid, NodeReference[] Nodes, string ServiceToken, string DeviceToken, string UserToken, ControlFormCallback Callback, object State) { StringBuilder sb = new StringBuilder(); XmlWriter w = XmlWriter.Create(sb, XmlUtilities.GetXmlWriterSettings(false, true, true)); w.WriteStartElement("getForm", "urn:xmpp:iot:control"); if (!string.IsNullOrEmpty(ServiceToken)) { w.WriteAttributeString("serviceToken", ServiceToken); } if (!string.IsNullOrEmpty(DeviceToken)) { w.WriteAttributeString("deviceToken", DeviceToken); } if (!string.IsNullOrEmpty(UserToken)) { w.WriteAttributeString("userToken", UserToken); } ProvisioningServer.WriteNodes(w, Nodes); w.WriteEndElement(); w.Flush(); client.IqGet(sb.ToString(), Jid, this.GetFormResponse, new ControlFormEventArgs(State, Callback), "Get Control Form"); }
/// <summary> /// Sets a string-valued control parameter /// </summary> /// <param name="Jid">JID of controller</param> /// <param name="ParameterName">Parameter name.</param> /// <param name="Value">Value to set.</param> /// <param name="Nodes">Node references.</param> /// <param name="ServiceToken">Service token.</param> /// <param name="DeviceToken">Device token.</param> /// <param name="UserToken">User token.</param> public void Set(string Jid, string ParameterName, string Value, NodeReference[] Nodes, string ServiceToken, string DeviceToken, string UserToken) { StringBuilder sb = new StringBuilder(); XmlWriter w = XmlWriter.Create(sb, XmlUtilities.GetXmlWriterSettings(false, true, true)); w.WriteStartElement("set", "urn:xmpp:iot:control"); if (!string.IsNullOrEmpty(ServiceToken)) { w.WriteAttributeString("serviceToken", ServiceToken); } if (!string.IsNullOrEmpty(DeviceToken)) { w.WriteAttributeString("deviceToken", DeviceToken); } if (!string.IsNullOrEmpty(UserToken)) { w.WriteAttributeString("userToken", UserToken); } ProvisioningServer.WriteNodes(w, Nodes); w.WriteStartElement("string"); w.WriteAttributeString("name", ParameterName); w.WriteAttributeString("value", Value); w.WriteEndElement(); w.WriteEndElement(); w.Flush(); client.SendMessage(Jid, string.Empty, MessageType.Normal, sb.ToString()); }
/// <summary> /// Class handling a chat interface over XMPP, according to proto-XEP: http://htmlpreview.github.io/?https://github.com/joachimlindborg/XMPP-IoT/blob/master/xep-0000-IoT-Chat.html /// It does not support concentrators (XEP-0326). /// </summary> /// <param name="Client">XMPP Client to use for communication.</param> /// <param name="Provisioning">Optional provisioning server to use.</param> /// <param name="Sensor">XMPP Sensor interface, if any, null otherwise.</param> /// <param name="Control">XMPP Control interface, if any, null otherwise.</param> public XmppChatServer(XmppClient Client, ProvisioningServer Provisioning, XmppSensorServer Sensor, XmppControlServer Control) { this.client = Client; this.provisioning = Provisioning; this.sensor = Sensor; this.control = Control; this.client.OnMessageReceived += this.OnMessage; }
/// <summary> /// Class handling client side of sensor data requests and responses over XMPP, according to XEP-0323: http://xmpp.org/extensions/xep-0323.html /// It does not support concentrators (XEP-0326). /// </summary> /// <param name="Client">XMPP Client to use for communication.</param> /// <param name="Provisioning">Optional provisioning server to use.</param> public XmppSensorServer(XmppClient Client, ProvisioningServer Provisioning) { this.client = Client; this.provisioning = Provisioning; if (this.provisioning != null) { this.provisioning.OnClearCache += this.OnClearCache; } this.client.AddClientSpecificIqHandler("req", "urn:xmpp:iot:sensordata", this.Req, "urn:xmpp:iot:sensordata"); this.client.AddClientSpecificIqHandler("cancel", "urn:xmpp:iot:sensordata", this.Cancel); this.client.AddClientSpecificIqHandler("subscribe", "urn:xmpp:iot:events", this.Subscribe, "urn:xmpp:iot:events"); this.client.AddClientSpecificIqHandler("unsubscribe", "urn:xmpp:iot:events", this.Unsubscribe); }
/// <summary> /// Class handling control requests and responses over XMPP, according to XEP-0325: http://xmpp.org/extensions/xep-0325.html /// It does not support concentrators (XEP-0326). /// </summary> /// <param name="Client">XMPP Client to use for communication.</param> /// <param name="Provisioning">Optional provisioning server to use.</param> /// <param name="Parameters">Control parameters.</param> public XmppControlServer(XmppClient Client, ProvisioningServer Provisioning, params IControlParameter[] Parameters) { this.client = Client; this.provisioning = Provisioning; this.parameters = Parameters; foreach (IControlParameter Parameter in Parameters) { this.parameterByName [Parameter.Name] = Parameter; } this.client.AddClientSpecificIqHandler("getForm", "urn:xmpp:iot:control", this.GetForm, "urn:xmpp:iot:control"); this.client.AddClientSpecificIqHandler("set", "urn:xmpp:iot:control", this.Set); this.client.AddClientSpecificApplicationMessageHandler("set", "urn:xmpp:iot:control", this.Set); }
/// <summary> /// Sets parameters to values in a control form /// </summary> /// <param name="Jid">JID of controller</param> /// <param name="Form">XMPP Data Form.</param> /// <param name="Nodes">Node references.</param> /// <param name="ServiceToken">Service token.</param> /// <param name="DeviceToken">Device token.</param> /// <param name="UserToken">User token.</param> public void Set(string Jid, XmppDataForm Form, NodeReference[] Nodes, string ServiceToken, string DeviceToken, string UserToken) { StringBuilder sb = new StringBuilder(); XmlWriter w = XmlWriter.Create(sb, XmlUtilities.GetXmlWriterSettings(false, true, true)); w.WriteStartElement("set", "urn:xmpp:iot:control"); if (!string.IsNullOrEmpty(ServiceToken)) { w.WriteAttributeString("serviceToken", ServiceToken); } if (!string.IsNullOrEmpty(DeviceToken)) { w.WriteAttributeString("deviceToken", DeviceToken); } if (!string.IsNullOrEmpty(UserToken)) { w.WriteAttributeString("userToken", UserToken); } ProvisioningServer.WriteNodes(w, Nodes); w.WriteStartElement("x", XmppClient.NamespaceData); w.WriteAttributeString("type", "submit"); foreach (XmppDataField Field in Form.Ordered) { w.WriteStartElement("field"); w.WriteAttributeString("var", Field.Var); w.WriteAttributeString("type", XmppDataField.ToString(Field.Type)); w.WriteElementString("value", Field.Value); w.WriteEndElement(); } w.WriteEndElement(); w.WriteEndElement(); w.Flush(); client.SendMessage(Jid, string.Empty, MessageType.Normal, sb.ToString()); }
/// <summary> /// Requests sensor data /// </summary> /// <param name="Jid">JID of device.</param> /// <param name="Types">Types.</param> /// <param name="Nodes">Nodes.</param> /// <param name="FieldNames">Field names.</param> /// <param name="From">From what point in time to read.</param> /// <param name="To">To what point in time to read.</param> /// <param name="When">When to read the data.</param> /// <param name="ServiceToken">Service token.</param> /// <param name="DeviceToken">Device token.</param> /// <param name="UserToken">User token.</param> /// <param name="Callback">Callback method. May be called multiple times for each request.</param> /// <param name="State">State object to pass on to the callback method.</param> /// <param name="Timeout">Timeout, in seconds.</param> /// <returns>Sequence number of the request.</returns> public int RequestData(string Jid, ReadoutType Types, NodeReference[] Nodes, string[] FieldNames, DateTime?From, DateTime?To, DateTime?When, string ServiceToken, string DeviceToken, string UserToken, SensorDataCallback Callback, object State, int Timeout) { StringBuilder sb = new StringBuilder(); XmlWriter w = XmlWriter.Create(sb, XmlUtilities.GetXmlWriterSettings(false, true, true)); SensorDataEventArgs e = new SensorDataEventArgs(State, Callback, false, Timeout); DateTime TimeoutTP = DateTime.Now.AddSeconds(Timeout); int SeqNr; lock (this.synchObj) { do { SeqNr = this.seqNr++; } while (this.receiving.ContainsKey(SeqNr)); while (this.byTimeout.ContainsKey(TimeoutTP)) { TimeoutTP = TimeoutTP.AddTicks(gen.Next(1, 10)); } this.byTimeout [TimeoutTP] = e; e.Timeout = TimeoutTP; e.SeqNr = SeqNr; if (this.timer == null) { this.timer = new Timer(this.TimerCallback, null, 1000, 1000); } } w.WriteStartElement("req", "urn:xmpp:iot:sensordata"); w.WriteAttributeString("seqnr", SeqNr.ToString()); if (!string.IsNullOrEmpty(ServiceToken)) { w.WriteAttributeString("serviceToken", ServiceToken); } if (!string.IsNullOrEmpty(DeviceToken)) { w.WriteAttributeString("deviceToken", DeviceToken); } if (!string.IsNullOrEmpty(UserToken)) { w.WriteAttributeString("userToken", UserToken); } if (From.HasValue) { w.WriteAttributeString("from", XmlUtilities.DateTimeToString(From.Value)); } if (To.HasValue) { w.WriteAttributeString("to", XmlUtilities.DateTimeToString(To.Value)); } if (When.HasValue) { w.WriteAttributeString("when", XmlUtilities.DateTimeToString(When.Value)); } ProvisioningServer.WriteReadoutTypes(w, Types); ProvisioningServer.WriteNodes(w, Nodes); ProvisioningServer.WriteFields(w, FieldNames); w.WriteEndElement(); w.Flush(); client.IqGet(sb.ToString(), Jid, this.ReqResponse, e, "Sensor Data Request"); return(SeqNr); }
/// <summary> /// Requests to subscribe to sensor data /// </summary> /// <param name="SeqNr">Sequence number to use for subscription. Can be null, if one is to be generated.</param> /// <param name="Jid">JID of device.</param> /// <param name="Types">Types.</param> /// <param name="Nodes">Nodes.</param> /// <param name="Fields">Field names, and optional conditions.</param> /// <param name="MaxAge">Optional max age of historical data. Can be null.</param> /// <param name="MinInterval">Optional minimum interval of events. Can be null.</param> /// <param name="MaxInterval">Optional maximum interval of events. Can be null.</param> /// <param name="ImmediateRequest">If an immediate request for sensor data should be made.</param> /// <param name="ServiceToken">Service token.</param> /// <param name="DeviceToken">Device token.</param> /// <param name="UserToken">User token.</param> /// <param name="Callback">Callback method. May be called multiple times for each request.</param> /// <param name="State">State object to pass on to the callback method.</param> /// <returns>Sequence number of the request.</returns> /// <exception cref="ArgumentException">If <paramref name="MinInterval"/> is zero or negative.</exception> /// <exception cref="ArgumentException">If <paramref name="MaxInterval"/> is zero or negative.</exception> /// <exception cref="ArgumentException">If <paramref name="MaxInterval"/> is smaller than <paramref name="MinInterval"/>.</exception> /// <exception cref="ArgumentException">If <paramref name="SeqNr"/> is provided, but the sequence number is already in use.</exception> public int SubscribeData(int?SeqNr, string Jid, ReadoutType Types, NodeReference[] Nodes, FieldCondition[] Fields, Duration MaxAge, Duration MinInterval, Duration MaxInterval, bool ImmediateRequest, string ServiceToken, string DeviceToken, string UserToken, SensorDataCallback Callback, object State) { if ((object)MinInterval != null && MinInterval <= Duration.Zero) { throw new ArgumentException("MinInterval must be positive or null.", "MinInterval"); } if ((object)MaxInterval != null) { if (MaxInterval <= Duration.Zero) { throw new ArgumentException("MaxInterval must be positive or null.", "MaxInterval"); } if ((object)MinInterval != null && MinInterval > MaxInterval) { throw new ArgumentException("MaxInterval must be greater than MinInterval.", "MaxInterval"); } } StringBuilder sb = new StringBuilder(); XmlWriter w = XmlWriter.Create(sb, XmlUtilities.GetXmlWriterSettings(false, true, true)); SensorDataEventArgs e = new SensorDataEventArgs(State, Callback, true, int.MaxValue); lock (this.synchObj) { if (!SeqNr.HasValue) { do { SeqNr = this.seqNr++; } while (this.receiving.ContainsKey(SeqNr.Value)); } e.Timeout = DateTime.MaxValue; e.SeqNr = SeqNr.Value; } w.WriteStartElement("subscribe", "urn:xmpp:iot:events"); w.WriteAttributeString("seqnr", SeqNr.Value.ToString()); if (!string.IsNullOrEmpty(ServiceToken)) { w.WriteAttributeString("serviceToken", ServiceToken); } if (!string.IsNullOrEmpty(DeviceToken)) { w.WriteAttributeString("deviceToken", DeviceToken); } if (!string.IsNullOrEmpty(UserToken)) { w.WriteAttributeString("userToken", UserToken); } if ((object)MaxAge != null) { w.WriteAttributeString("maxAge", MaxAge.ToString()); } if ((object)MinInterval != null) { w.WriteAttributeString("minInterval", MinInterval.ToString()); } if ((object)MaxInterval != null) { w.WriteAttributeString("maxInterval", MaxInterval.ToString()); } if (ImmediateRequest) { w.WriteAttributeString("req", "true"); } ProvisioningServer.WriteReadoutTypes(w, Types); ProvisioningServer.WriteNodes(w, Nodes); FieldCondition.WriteFields(w, Fields); w.WriteEndElement(); w.Flush(); client.IqGet(sb.ToString(), Jid, this.ReqResponse, e, "Sensor Data Subscription"); return(SeqNr.Value); }