/// <summary>
        /// Add an observer for the given observable resource
        /// </summary>
        /// <param name="coapReq">A request message from client that is requesting resource observation</param>
        public void AddResourceObserver(CoAPRequest coapReq)
        {
            if (coapReq == null)
            {
                throw new ArgumentNullException("CoAP message requesting for observation is NULL");
            }
            if (!coapReq.IsObservable())
            {
                throw new ArgumentException("CoAP message requesting for observation is not marked as observable");
            }
            string observableURL = coapReq.GetURL().Trim().ToLower();

            //First, add this URL as an observable resource
            this.AddObservableResource(observableURL);

            //Now, add this observer for the given observable resource
            this._observableListSync.WaitOne();
            bool      observerAlreadyExists = false;
            ArrayList observers             = (ArrayList)this._observers[observableURL];

            for (int count = 0; count < observers.Count; count++)
            {
                CoAPRequest storedObserver = (CoAPRequest)observers[count];
                if (storedObserver.ID.Value == coapReq.ID.Value)
                {
                    observerAlreadyExists = true;
                    break;
                }
            }
            if (!observerAlreadyExists)
            {
                observers.Add(coapReq);
            }
            this._observableListSync.Set();
        }
        /// <summary>
        /// Send the CoAP message to client
        /// </summary>
        /// <param name="coapMsg">The CoAP message to send</param>
        /// <returns>Number of bytes sent</returns>
        public override int Send(AbstractCoAPMessage coapMsg)
        {
            if (coapMsg == null)
            {
                throw new ArgumentNullException("Message is NULL");
            }
            if (this._socket == null)
            {
                throw new InvalidOperationException("CoAP server not yet started");
            }

            int bytesSent = 0;

            try
            {
                //We do not want server to die when a socket send error occurs...
                //just clean all settings specific to the remote client and
                //keep going
                byte[] coapBytes = coapMsg.ToByteStream();
                bytesSent = this._socket.SendTo(coapBytes, coapMsg.RemoteSender);
                if (coapMsg.MessageType.Value == CoAPMessageType.CON)
                {
                    //confirmable message...need to wait for a response
                    coapMsg.DispatchDateTime = DateTime.Now;
                    this._msgPendingAckQ.AddToWaitQ(coapMsg);
                }
            }
            catch (Exception e)
            {
                this._msgPendingAckQ.RemoveFromWaitQ(coapMsg.ID.Value);
                if (coapMsg.GetType() == typeof(CoAPRequest))
                {
                    CoAPRequest coapReq = (CoAPRequest)coapMsg;
                    this._observers.RemoveResourceObserver(coapReq.GetURL(), coapReq.Token.Value);
                }
                else if (coapMsg.GetType() == typeof(CoAPResponse))
                {
                    CoAPResponse coapResp = (CoAPResponse)coapMsg;
                    this._observers.RemoveResourceObserver(coapResp);
                }
                this.HandleError(e, coapMsg);
            }

            return(bytesSent);
        }
Beispiel #3
0
        /// <summary>
        /// Called when a CoAP request is received...we will only support CON requests
        /// of type GET... the path is sensors/temp
        /// </summary>
        /// <param name="coapReq">CoAPRequest object</param>
        static void OnCoAPRequestReceived(CoAPRequest coapReq)
        {
            string reqPath = (coapReq.GetPath() != null) ? coapReq.GetPath().ToLower() : "";

            /*We have skipped error handling in code below to just focus on observe option*/
            if (coapReq.MessageType.Value == CoAPMessageType.CON && coapReq.Code.Value == CoAPMessageCode.GET)
            {
                if (!coapReq.IsObservable() /*Does the request have "Observe" option*/)
                {
                    /*Request is not to observe...we do not support anything no-observable*/
                    CoAPResponse resp = new CoAPResponse(CoAPMessageType.ACK,
                                                         CoAPMessageCode.NOT_IMPLEMENTED,
                                                         coapReq /*Copy all necessary values from request in the response*/);
                    coapServer.Send(resp);
                }
                else if (!coapServer.ObserversList.IsResourceBeingObserved(coapReq.GetURL()) /*do we support observation on this path*/)
                {
                    //Observation is not supported on this path..just to tell you how to check
                    CoAPResponse resp = new CoAPResponse(CoAPMessageType.ACK,
                                                         CoAPMessageCode.NOT_FOUND,
                                                         coapReq /*Copy all necessary values from request in the response*/);
                    coapServer.Send(resp);
                }
                else
                {
                    //This is a request to observe this resource...register this client
                    coapServer.ObserversList.AddResourceObserver(coapReq);

                    /*Request contains observe option and path is correct*/
                    CoAPResponse resp = new CoAPResponse(CoAPMessageType.ACK,
                                                         CoAPMessageCode.EMPTY,
                                                         coapReq /*Copy all necessary values from request in the response*/);

                    //send it..tell client we registered it's request to observe
                    coapServer.Send(resp);
                }
            }
        }
        /// <summary>
        /// Based on the token value, find which resource was being observed
        /// </summary>
        /// <param name="token">The CoAP token that is used for req/resp matching</param>
        /// <returns>The URL of the resource being observed</returns>
        protected string FindResourceBeingObserved(CoAPToken token)
        {
            if (token == null || token.Value == null)
            {
                throw new ArgumentNullException("Invalid token");
            }

            bool        observerFound       = false;
            string      observedResourceURL = null;
            CoAPRequest observerEntry       = null;

            this._observableListSync.WaitOne();

            foreach (string observedResURL in this._observers.Keys)
            {
                ArrayList observers = (ArrayList)this._observers[observedResURL];
                foreach (CoAPRequest req in observers)
                {
                    if (AbstractByteUtils.AreByteArraysEqual(req.Token.Value, token.Value))
                    {
                        observerFound = true;
                        observerEntry = req;
                        break;
                    }
                }
                if (observerFound)
                {
                    break;
                }
            }
            this._observableListSync.Set();

            if (observerFound && observerEntry != null)
            {
                observedResourceURL = observerEntry.GetURL();
            }
            return(observedResourceURL);
        }