/// <summary>
        /// Determines whether a control operation can be performed, partially performed or be rejected.
        /// </summary>
        /// <param name="From">JID from which the request was made.</param>
        /// <param name="Callback">Callback method to call, when the response is available.</param>
        /// <param name="State">State object to pass on to the response callback.</param>
        /// <param name="ServiceToken">Optional service token provided in the request.</param>
        /// <param name="DeviceToken">Optional device token provided in the request.</param>
        /// <param name="UserToken">Optional user token provided in the request.</param>
        /// <param name="Parameters">Control parameters to control.</param>
        /// <param name="NodeReferenes">Any node references in the request. Can be null, if none.</param>
        public void CanControl(string From, CanControlCallback Callback, object State, string ServiceToken, string DeviceToken, string UserToken, string[] Parameters, NodeReference[] NodeReferences)
        {
            string BareJid = XmppClient.StripResource(From);

            if (BareJid == this.address)
            {
                if (Callback != null)
                {
                    CanControlEventArgs e = new CanControlEventArgs(BareJid, true, Parameters, NodeReferences, State);

                    try
                    {
                        Callback(e);
                    } catch (Exception ex)
                    {
                        Log.Exception(ex);
                    }
                }
            }
            else
            {
                StringBuilder sb = new StringBuilder();
                XmlWriter     w  = XmlWriter.Create(sb, XmlUtilities.GetXmlWriterSettings(false, true, true));

                w.WriteStartElement("canControl", "urn:xmpp:iot:provisioning");
                w.WriteAttributeString("jid", BareJid);

                if (!string.IsNullOrEmpty(ServiceToken))
                {
                    w.WriteAttributeString("serviceToken", ServiceToken);
                    this.UpdateTokenSource(ServiceToken, From);
                }

                if (!string.IsNullOrEmpty(DeviceToken))
                {
                    w.WriteAttributeString("deviceToken", DeviceToken);
                    this.UpdateTokenSource(DeviceToken, From);
                }

                if (!string.IsNullOrEmpty(UserToken))
                {
                    w.WriteAttributeString("userToken", UserToken);
                    this.UpdateTokenSource(UserToken, From);
                }

                if (NodeReferences != null && NodeReferences.Length > 0)
                {
                    foreach (NodeReference Node in NodeReferences)
                    {
                        w.WriteStartElement("node");
                        w.WriteAttributeString("nodeId", Node.NodeId);

                        if (!string.IsNullOrEmpty(Node.SourceId))
                        {
                            w.WriteAttributeString("sourceId", Node.SourceId);
                        }

                        if (!string.IsNullOrEmpty(Node.CacheType))
                        {
                            w.WriteAttributeString("cacheType", Node.CacheType);
                        }

                        w.WriteEndElement();
                    }
                }

                if (Parameters != null && Parameters.Length > 0)
                {
                    foreach (string Parameter in Parameters)
                    {
                        w.WriteStartElement("parameter");
                        w.WriteAttributeString("name", Parameter);
                        w.WriteEndElement();
                    }
                }

                w.WriteEndElement();

                w.Flush();
                string      Xml   = sb.ToString();
                string      Hash  = this.CalcHash(Xml);
                StanzaError Error = null;
                XmlNodeList Response;

                if ((Response = this.GetCachedResponse(Hash)) != null)
                {
                    this.CanControlResponse(this.client, string.Empty, Response, ref Error, new object[] {
                        Callback,
                        State,
                        null,
                        Parameters,
                        NodeReferences
                    });
                }
                else
                {
                    this.client.IqGet(Xml, this.address, this.CanControlResponse, new object[] {
                        Callback,
                        State,
                        Hash,
                        Parameters,
                        NodeReferences
                    }, "Can Control?");
                }
            }
        }
        private void CanControlResponse(XmppClient Client, string Type, XmlNodeList Response, ref StanzaError Error, object State)
        {
            object[]           P        = (object[])State;
            CanControlCallback Callback = (CanControlCallback)P [0];
            object             State2   = (object)P [1];
            string             Hash     = (string)P [2];

            string[]        Parameters     = (string[])P [3];
            NodeReference[] NodeReferences = (NodeReference[])P [4];
            bool            CanControl     = false;
            string          Jid            = string.Empty;
            XmlElement      E;

            if (Error != null)
            {
                Error = null;
            }
            else if (Response != null)
            {
                if (Hash != null)
                {
                    this.AddToCache(Hash, Response);
                }

                foreach (XmlNode N in Response)
                {
                    if (N.LocalName == "canControlResponse" && (E = N as XmlElement) != null)
                    {
                        CanControl = XmlUtilities.GetAttribute(E, "result", false);

                        List <NodeReference> Nodes;
                        List <string>        ParameterNames;

                        ReadoutRequest.ParseNodesAndFieldNames(E, out Nodes, out ParameterNames);

                        if (Nodes == null)
                        {
                            NodeReferences = null;
                        }
                        else
                        {
                            NodeReferences = Nodes.ToArray();
                        }

                        if (ParameterNames == null)
                        {
                            Parameters = null;
                        }
                        else
                        {
                            Parameters = ParameterNames.ToArray();
                        }
                        break;
                    }
                }
            }

            CanControlEventArgs e = new CanControlEventArgs(Jid, CanControl, Parameters, NodeReferences, State2);

            if (Callback != null)
            {
                try
                {
                    Callback(e);
                } catch (Exception ex)
                {
                    Log.Exception(ex);
                }
            }
        }
Example #3
0
        /// <summary>
        /// Checks if a control operation can be performed.
        /// </summary>
        /// <param name="RequestFromBareJid">Readout request came from this bare JID.</param>
        /// <param name="Nodes">Any nodes included in the request.</param>
        /// <param name="ParameterNames">And parameter names included in the request. If null, all parameter names are requested.</param>
        /// <param name="ServiceTokens">Any service tokens provided.</param>
        /// <param name="DeviceTokens">Any device tokens provided.</param>
        /// <param name="UserTokens">Any user tokens provided.</param>
        /// <param name="Callback">Method to call when result is received.</param>
        /// <param name="State">State object to pass on to the callback method.</param>
        public void CanControl(string RequestFromBareJid, IEnumerable <ThingReference> Nodes, IEnumerable <string> ParameterNames,
                               string[] ServiceTokens, string[] DeviceTokens, string[] UserTokens, CanControlCallback Callback, object State)
        {
            if ((!string.IsNullOrEmpty(this.ownerJid) && string.Compare(RequestFromBareJid, this.ownerJid, true) == 0) ||
                string.Compare(RequestFromBareJid, this.provisioningServerAddress, true) == 0)
            {
                if (Callback != null)
                {
                    try
                    {
                        ThingReference[] Nodes2 = Nodes as ThingReference[];
                        if (Nodes2 == null && Nodes != null)
                        {
                            List <ThingReference> List = new List <ThingReference>();
                            List.AddRange(Nodes);
                            Nodes2 = List.ToArray();
                        }

                        string[] ParameterNames2 = ParameterNames as string[];
                        if (ParameterNames2 == null && ParameterNames != null)
                        {
                            List <string> List = new List <string>();
                            List.AddRange(ParameterNames);
                            ParameterNames2 = List.ToArray();
                        }

                        IqResultEventArgs           e0 = new IqResultEventArgs(null, string.Empty, this.client.FullJID, this.provisioningServerAddress, true, State);
                        CanControlResponseEventArgs e  = new CanControlResponseEventArgs(e0, State, RequestFromBareJid, true, Nodes2, ParameterNames2);

                        Callback(this.client, e);
                    }
                    catch (Exception ex)
                    {
                        Log.Critical(ex);
                    }
                }

                return;
            }

            StringBuilder Xml = new StringBuilder();

            Xml.Append("<canControl xmlns='");
            Xml.Append(NamespaceProvisioningDevice);
            Xml.Append("' jid='");
            Xml.Append(XML.Encode(RequestFromBareJid));

            this.AppendTokens(Xml, "st", ServiceTokens);
            this.AppendTokens(Xml, "dt", DeviceTokens);
            this.AppendTokens(Xml, "ut", UserTokens);

            if (Nodes == null && ParameterNames == null)
            {
                Xml.Append("'/>");
            }
            else
            {
                Xml.Append("'>");

                if (Nodes != null)
                {
                    foreach (ThingReference Node in Nodes)
                    {
                        Xml.Append("<nd id='");
                        Xml.Append(XML.Encode(Node.NodeId));

                        if (!string.IsNullOrEmpty(Node.SourceId))
                        {
                            Xml.Append("' src='");
                            Xml.Append(XML.Encode(Node.SourceId));
                        }

                        if (!string.IsNullOrEmpty(Node.Partition))
                        {
                            Xml.Append("' pt='");
                            Xml.Append(XML.Encode(Node.Partition));
                        }

                        Xml.Append("'/>");
                    }
                }

                if (ParameterNames != null)
                {
                    foreach (string ParameterName in ParameterNames)
                    {
                        Xml.Append("<parameter name='");
                        Xml.Append(XML.Encode(ParameterName));
                        Xml.Append("'/>");
                    }
                }

                Xml.Append("</canControl>");
            }

            this.CachedIqGet(Xml.ToString(), (sender, e) =>
            {
                XmlElement E = e.FirstElement;
                List <ThingReference> Nodes2  = null;
                List <string> ParameterNames2 = null;
                string Jid = string.Empty;
                string NodeId;
                string SourceId;
                string Partition;
                bool CanControl;

                if (e.Ok && E.LocalName == "canControlResponse" && E.NamespaceURI == NamespaceProvisioningDevice)
                {
                    CanControl = XML.Attribute(E, "result", false);

                    foreach (XmlAttribute Attr in E.Attributes)
                    {
                        if (Attr.Name == "jid")
                        {
                            Jid = Attr.Value;
                        }
                    }

                    foreach (XmlNode N in E.ChildNodes)
                    {
                        switch (N.LocalName)
                        {
                        case "nd":
                            if (Nodes2 == null)
                            {
                                Nodes2 = new List <ThingReference>();
                            }

                            E         = (XmlElement)N;
                            NodeId    = XML.Attribute(E, "id");
                            SourceId  = XML.Attribute(E, "src");
                            Partition = XML.Attribute(E, "pt");

                            Nodes2.Add(new ThingReference(NodeId, SourceId, Partition));
                            break;

                        case "parameter":
                            if (ParameterNames2 == null)
                            {
                                ParameterNames2 = new List <string>();
                            }

                            ParameterNames2.Add(XML.Attribute((XmlElement)N, "name"));
                            break;
                        }
                    }
                }
                else
                {
                    CanControl = false;
                }

                CanControlResponseEventArgs e2 = new CanControlResponseEventArgs(e, State, Jid, CanControl,
                                                                                 Nodes2?.ToArray(), ParameterNames2?.ToArray());

                try
                {
                    Callback(this, e2);
                }
                catch (Exception ex)
                {
                    Log.Critical(ex);
                }
            }, null);
        }