/// <summary>
        /// Start the server
        /// </summary>
        /// <param name="host">Hostname to use for this server (DNS/IP)</param>
        /// <param name="port">The port number to listen on</param>
        public override void Initialize(string host, int port)
        {
            this._host = (host == null || host.Trim().Length == 0) ? "unknown" : host;
            if (port <= 0)
            {
                this._port = AbstractNetworkUtils.GetDefaultCoAPPort();
            }
            else
            {
                this._port = port;
            }

            Shutdown(); //close all previous connections

            //Create the wait q
            this._msgPendingAckQ = new TimedQueue((uint)AbstractCoAPChannel.DEFAULT_ACK_TIMEOUT_SECS);
            this._msgPendingAckQ.OnResponseTimeout += new TimedQueue.TimedOutWaitingForResponse(OnTimedOutWaitingForResponse);

            //Create the separate response q
            this._separateResponseQ = new SeparateResponseQueue();

            //Create the observers list
            this._observers = new ObserversList();

            // Create a socket, bind it to the server's port and listen for client connections
            this._isDone = false;
            this.ReInitSocket();
            Thread waitForClientThread = new Thread(new ThreadStart(WaitForConnections));

            waitForClientThread.Start();
        }
Ejemplo n.º 2
0
        //public bool ExcludePort
        //{
        //    get { return __ExcludePort; }
        //    set { __ExcludePort = true; }
        //}
        #endregion

        #region Lifetime Management
        /// <summary>
        /// Initialize all basic aspects of the client channel
        /// </summary>
        /// <param name="host">The IP host</param>
        /// <param name="port">The port number</param>
        public override void Initialize(string host, int port)
        {
            Shutdown();

            //Connect to host
            IPAddress ipAddr = AbstractNetworkUtils.GetIPAddressFromHostname(host);

            //ipAddr = IPAddress.IPv6Loopback;
            this._remoteEP = new IPEndPoint(ipAddr, port);

            /*Socket serverSocket =
             * new Socket(ipAddress.AddressFamily, SocketType.Stream, ProtocolType.Tcp);
             *          ?
             *
             * Note: There's a shortcut to obtain the IP address of localhost: You can simply use IPAddress.Loopback (127.0.0.1) or IPAddress.IPv6Loopback (::1).
             */
            this._clientSocket = new Socket(CoAPSettings.Instance.AddressFamily, SocketType.Dgram, ProtocolType.Udp);
            Console.WriteLine("NEW SOCKET - handle = " + _clientSocket.Handle.ToString());
            ////this._clientSocket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, true);  <==== added by Mike

            this._clientSocket.Connect(this._remoteEP);
            //Initialize ACK Q
            this._msgPendingAckQ = new TimedQueue((UInt16)this.AckTimeout);
            this._msgPendingAckQ.OnResponseTimeout += new TimedQueue.TimedOutWaitingForResponse(OnTimedOutWaitingForResponse);
            //Start message processing thread
            this._isDone = false;
            Thread waitForClientThread = new Thread(new ThreadStart(ProcessReceivedMessages));

            waitForClientThread.Start();
        }
Ejemplo n.º 3
0
        /// <summary>
        /// Parse the CoAP message stream and extract details of the token
        /// </summary>
        /// <param name="coapMsgStream">The CoAP message stream that contains the token length and value</param>
        /// <param name="startIndex">The index to start looking for the value</param>
        /// <param name="extraInfo">Not used</param>
        /// <returns>The next index from where next set of information can be extracted from the message stream</returns>
        public int Parse(byte[] coapMsgStream, int startIndex, UInt16 extraInfo)
        {
            if (coapMsgStream == null || coapMsgStream.Length == 0 || startIndex < 0)
            {
                return(startIndex);                                                                     //do nothing
            }
            if (coapMsgStream.Length < AbstractCoAPMessage.HEADER_LENGTH)
            {
                throw new CoAPFormatException("Invalid CoAP message stream");
            }
            if (startIndex >= coapMsgStream.Length)
            {
                throw new ArgumentException("Start index beyond message stream length");
            }

            //First get the token length...its there in bits 4-7 starting from left of first byte
            this.Length = (byte)(coapMsgStream[startIndex] & 0x0F);
            if (this.Length > 0)
            {
                //Search for token value
                int tokenValueStartIndex = 4; //Token value follows after first 4 bytes
                if (coapMsgStream.Length < (4 + this.Length))
                {
                    throw new CoAPFormatException("Invalid message stream. Token not present in the stream despite non-zero length");
                }
                byte[] tokenValue = new byte[this.Length];
                Array.Copy(coapMsgStream, tokenValueStartIndex, tokenValue, 0, this.Length);
                tokenValue = AbstractNetworkUtils.FromNetworkByteOrder(tokenValue);
                this.Value = tokenValue;
            }
            //We have parsed the token length...this finishes the byte...the index should move to next byte
            return(startIndex + 1);
        }
        /// <summary>
        /// Send a CoAP message to the server. Please note, you must handle all exceptions
        /// and no event is raised.
        /// </summary>
        /// <param name="coapMsg">The CoAP message to send to server</param>
        /// <returns>Number of bytes sent</returns>
        public override int Send(AbstractCoAPMessage coapMsg)
        {
            if (coapMsg == null)
            {
                throw new ArgumentNullException("Message is NULL");
            }
            if (this._clientSocket == null)
            {
                throw new InvalidOperationException("CoAP client not yet started");
            }
            int bytesSent = 0;

            byte[] coapBytes = coapMsg.ToByteStream();
            if (coapBytes.Length > AbstractNetworkUtils.GetMaxMessageSize())
            {
                throw new UnsupportedException("Message size too large. Not supported. Try block option");
            }
            bytesSent = this._clientSocket.Send(coapBytes);
            if (coapMsg.MessageType.Value == CoAPMessageType.CON)
            {
                //confirmable message...need to wait for a response
                coapMsg.DispatchDateTime = DateTime.Now;
            }

            return(bytesSent);
        }
Ejemplo n.º 5
0
 public byte[] ToBytes(AbstractCoAPMessage coapMsg)
 {
     byte[] coapBytes = coapMsg.ToByteStream();
     if (coapBytes.Length > AbstractNetworkUtils.GetMaxMessageSize())
     {
         throw new UnsupportedException("Message size too large. Not supported. Try block option");
     }
     return(coapBytes);
 }
Ejemplo n.º 6
0
        /// <summary>
        /// Perform a session request (acquire or terminate).
        /// </summary>
        /// <param name="messageCode">CoAPMessageCode.POST for establishing a session or oAPMessageCode.DELETE for terminating a session</param>
        /// <returns>a boolean indicating success or failure of the request</returns>
        private bool SessionCall(byte messageCode)
        {
            __TimedOut = true;
            __SessionRequestSucceeded = false;
            string token = GatewaySettings.Instance.SfdpToken;
            //api.coap-test.developer.ssni.com
            string serverIP = AbstractNetworkUtils.GetIPAddressFromHostname(GatewaySettings.Instance.GatewayURI).ToString();

            __coapClient.Initialize(GatewaySettings.Instance.GatewayURI, __ServerPort);
            __coapClient.AckTimeout            = __Timeout;
            __coapClient.CoAPResponseReceived += new CoAPResponseReceivedHandler(OnCoAPSessionResponseReceived);
            __coapClient.CoAPError            += new CoAPErrorHandler(OnCoAPError);

            coapReq = new CoAPRequest(this.ConfirmableMessageType,
                                      messageCode,
                                      HdkUtils.MessageId());
            string uriToCall = "coap://" + GatewaySettings.Instance.GatewayURI + ":"
                               + __ServerPort + "/sessions?security=none";//?token="

            //+ GatewaySettings.Instance.SfdpToken;
            //+ "&security=none";

            coapReq.SetURL(uriToCall);
            byte[] zero = { 0x00 };
            coapReq.AddOption(CoAPHeaderOption.CONTENT_FORMAT, zero);
            if (messageCode != CoAPMessageCode.DELETE)
            {
                coapReq.Payload = new CoAPPayload(GatewaySettings.Instance.SfdpToken);
            }
            SetToken();

            coapReq.Options.RemoveOption(CoAPHeaderOption.URI_QUERY);  // JJK - Change in v2.0.7

            FileLogger.Write("About to send session request");
            try
            {
                FileLogger.Write(coapReq.ToString());
            }
            catch (Exception flErr)
            {
                FileLogger.Write(flErr.Message);
            }
            __coapClient.Send(coapReq);
            __Done.WaitOne(GatewaySettings.Instance.RequestTimeout);
            __Done.Reset();
            if (__TimedOut)
            {
                this.ErrorResult = "Request timed out";
                FileLogger.Write(this.ErrorResult);
            }
            __coapClient.CoAPResponseReceived -= new CoAPResponseReceivedHandler(OnCoAPSessionResponseReceived);

            return(__SessionRequestSucceeded);
        }
        /// <summary>
        /// Initialize all basic aspects of the client channel
        /// </summary>
        /// <param name="host">The IP host</param>
        /// <param name="port">The port number</param>
        public override void Initialize(string host, int port)
        {
            Shutdown();

            //Connect to host
            IPAddress ipAddr = AbstractNetworkUtils.GetIPAddressFromHostname(host);

            this._remoteEP     = new IPEndPoint(ipAddr, port);
            this._clientSocket = new Socket(CoAPSettings.Instance.AddressFamily, SocketType.Dgram, ProtocolType.Udp);
            this._clientSocket.Connect(this._remoteEP);
        }
Ejemplo n.º 8
0
 /// <summary>
 /// Creates a payload with byte stream
 /// </summary>
 /// <param name="payloadData">Payload as byte stream</param>
 public CoAPPayload(byte[] payloadData)
 {
     if (payloadData == null || payloadData.Length == 0)
     {
         throw new ArgumentNullException("Payload data cannot be NULL or empty byte stream");
     }
     if (payloadData.Length > AbstractNetworkUtils.GetMaxMessageSize() / 2)
     {
         throw new ArgumentException("Payload size cannot be more than " + AbstractNetworkUtils.GetMaxMessageSize() / 2);
     }
     this.Value = payloadData;
 }
Ejemplo n.º 9
0
 /// <summary>
 /// Creates a payload with string data
 /// </summary>
 /// <param name="payloadData">Payload data as string</param>
 public CoAPPayload(string payloadData)
 {
     if (payloadData == null || payloadData.Trim().Length == 0)
     {
         throw new ArgumentNullException("Payload data cannot be NULL or empty string");
     }
     if (payloadData.Trim().Length > AbstractNetworkUtils.GetMaxMessageSize() / 2)
     {
         throw new ArgumentException("Payload size cannot be more than " + AbstractNetworkUtils.GetMaxMessageSize() / 2);
     }
     this.Value = AbstractByteUtils.StringToByteUTF8(payloadData.Trim());
 }
Ejemplo n.º 10
0
        /// <summary>
        /// Convert this object into a byte stream. The zero-th element contains the token length
        /// Subsequent elements contain the token value in network byte order
        /// </summary>
        /// <param name="reserved">Not used now</param>
        /// <returns>byte array</returns>
        public byte[] ToStream(UInt16 reserved)
        {
            byte[] token = new byte[1 + this.Length];
            token[0] = this.Length;

            if (this.Length > 0)
            {
                byte[] tokenValue = new byte[this.Length];
                Array.Copy(this.Value, tokenValue, this.Length);
                tokenValue = AbstractNetworkUtils.ToNetworkByteOrder(tokenValue);
                Array.Copy(tokenValue, 0, token, 1, this.Length);
            }

            return(token);
        }
Ejemplo n.º 11
0
        /// <summary>
        /// Initialize all basic aspects of the client channel
        /// </summary>
        /// <param name="host">The IP host</param>
        /// <param name="port">The port number</param>
        public override void Initialize(string host, int port)
        {
            Shutdown();

            //Connect to host
            IPAddress ipAddr = AbstractNetworkUtils.GetIPAddressFromHostname(host);

            this._remoteEP     = new IPEndPoint(ipAddr, port);
            this._clientSocket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
            this._clientSocket.Connect(this._remoteEP);
            //Initialize ACK Q
            this._msgPendingAckQ = new TimedQueue((UInt16)this.AckTimeout);
            this._msgPendingAckQ.OnResponseTimeout += new TimedQueue.TimedOutWaitingForResponse(OnTimedOutWaitingForResponse);
            //Start message processing thread
            this._isDone = false;
            Thread waitForClientThread = new Thread(new ThreadStart(ProcessReceivedMessages));

            waitForClientThread.Start();
        }
Ejemplo n.º 12
0
        /// <summary>
        /// Send a CoAP message to the server
        /// </summary>
        /// <param name="coapMsg">The CoAP message to send to server</param>
        /// <returns>Number of bytes sent</returns>
        public override int Send(AbstractCoAPMessage coapMsg)
        {
            if (coapMsg == null)
            {
                throw new ArgumentNullException("Message is NULL");
            }
            if (this._clientSocket == null)
            {
                throw new InvalidOperationException("CoAP client not yet started");
            }
            int bytesSent = 0;

            try
            {
                byte[] coapBytes = coapMsg.ToByteStream();
                if (coapBytes.Length > AbstractNetworkUtils.GetMaxMessageSize())
                {
                    throw new UnsupportedException("Message size too large. Not supported. Try block option");
                }
                bytesSent = this._clientSocket.Send(coapBytes);
                if (coapMsg.MessageType.Value == CoAPMessageType.CON)
                {
                    //confirmable message...need to wait for a response
                    if (coapMsg.Timeout <= 0)
                    {
                        coapMsg.Timeout = AbstractCoAPChannel.DEFAULT_ACK_TIMEOUT_SECS;
                    }
                    coapMsg.DispatchDateTime = DateTime.Now;
                    this._msgPendingAckQ.AddToWaitQ(coapMsg);
                }
            }
            catch (Exception e)
            {
                this._msgPendingAckQ.RemoveFromWaitQ(coapMsg.ID.Value);
                this.HandleError(e, coapMsg);
            }

            return(bytesSent);
        }
Ejemplo n.º 13
0
        /// <summary>
        /// Parse the CoAP message stream and extract message Id (in network byte order)
        /// </summary>
        /// <param name="coapMsgStream">The CoAP message stream that contains the token length and value</param>
        /// <param name="startIndex">The index to start looking for the value</param>
        /// <param name="extraInfo">Not used</param>
        /// <returns>The next index from where next set of information can be extracted from the message stream</returns>
        public int Parse(byte[] coapMsgStream, int startIndex, UInt16 extraInfo)
        {
            if (coapMsgStream == null || coapMsgStream.Length == 0 || startIndex < 0)
            {
                return(startIndex);                                                                     //do nothing
            }
            if (coapMsgStream.Length < AbstractCoAPMessage.HEADER_LENGTH)
            {
                throw new CoAPFormatException("Invalid CoAP message stream");
            }
            if (startIndex >= coapMsgStream.Length)
            {
                throw new ArgumentException("Start index beyond message stream length");
            }

            //We read two bytes...
            byte[] mid = { coapMsgStream[startIndex], coapMsgStream[startIndex + 1] };
            //We received them in network byte order...fix the order based on the platform
            mid   = AbstractNetworkUtils.FromNetworkByteOrder(mid);
            Value = AbstractByteUtils.ToUInt16(mid);
            return(startIndex + 2);
        }
Ejemplo n.º 14
0
        /// <summary>
        /// Convert this option into a byte stream int network byte order
        /// </summary>
        /// <param name="previousOptionNumber">The previous option number in the sequence of options</param>
        /// <returns>byte array</returns>
        public byte[] ToStream(UInt16 previousOptionNumber)
        {
            //The option format is given below

            /*********************************************
            | 4 bits option delta | 4 bits length        |
            |  ----------------------------------------------
            |      0-2 bytes option delta extended       |
            |  ----------------------------------------------
            |      0-2 bytes option length extended      |
            |  ----------------------------------------------
            |               0-* bytes option value       |
            *********************************************/
            int streamLength = 1;
            //Get Option delta
            byte   optionDelta         = 0;
            UInt16 derivedOptionNumber = (UInt16)(this.Number - previousOptionNumber);

            byte[] optionDeltaEx = null;
            if (derivedOptionNumber <= 12)
            {
                optionDelta = (byte)derivedOptionNumber;
            }
            else if (derivedOptionNumber > 12 && derivedOptionNumber <= 255 /*Option number is single byte*/)
            {
                optionDeltaEx = new byte[1] {
                    (byte)(derivedOptionNumber - 13)
                };
                optionDelta = 13;
                streamLength++;//1 additional byte
            }
            else /*Option number is double byte*/
            {
                optionDelta   = 14;
                optionDeltaEx = AbstractByteUtils.GetBytes((UInt16)(derivedOptionNumber - 269));
                optionDeltaEx = AbstractNetworkUtils.ToNetworkByteOrder(optionDeltaEx);
                streamLength += 2; //two additional bytes
            }
            //Get option length
            byte optionLength = 0;

            byte[] optionLengthEx = null;
            if (this.Value != null)
            {
                if (this.Value.Length > 0 && this.Value.Length < 13)
                {
                    optionLength = (byte)this.Value.Length;
                }
                else if (this.Value.Length > 12 && this.Value.Length <= 255)
                {
                    optionLength   = 13;
                    optionLengthEx = new byte[1] {
                        (byte)(this.Value.Length - 13)
                    };
                    streamLength++;//1 additional byte
                }
                else if (this.Value.Length > 255)
                {
                    optionLength   = 14;
                    optionLengthEx = AbstractByteUtils.GetBytes((UInt16)(this.Value.Length - 269));
                    optionLengthEx = AbstractNetworkUtils.ToNetworkByteOrder(optionLengthEx);
                    streamLength  += 2; //two additional bytes
                }
            }
            streamLength += ((this.Value != null && !this.IsEmpty()) ? this.Value.Length : 0);
            byte[] optionStream = new byte[streamLength];
            int    count        = 0;

            optionStream[count++] = (byte)((optionDelta << 4) | (optionLength)); //header + length
            if (optionDelta == 13)                                               //delta extended
            {
                optionStream[count++] = optionDeltaEx[0];
            }
            else if (optionDelta == 14)
            {
                optionStream[count++] = optionDeltaEx[0];
                optionStream[count++] = optionDeltaEx[1];
            }
            if (optionLength == 13)
            {
                optionStream[count++] = optionLengthEx[0];
            }
            else if (optionLength == 14)
            {
                optionStream[count++] = optionLengthEx[0];
                optionStream[count++] = optionLengthEx[1];
            }
            if (this.Value != null && this.Value.Length > 0 && !this.IsEmpty())
            {
                byte[] optionValue = new byte[this.Value.Length];
                Array.Copy(this.Value, optionValue, this.Value.Length);
                if (this.NeedsByteOrdering(this.Number))
                {
                    optionValue = AbstractNetworkUtils.ToNetworkByteOrder(optionValue);
                }
                Array.Copy(optionValue, 0, optionStream, count, optionValue.Length);
            }

            return(optionStream);
        }
Ejemplo n.º 15
0
        /// <summary>
        /// This thread continuously looks for messages on the socket
        /// Once available, it will post them for handling downstream
        /// </summary>
        protected void ProcessReceivedMessages()
        {
            byte[] buffer  = null;
            int    maxSize = AbstractNetworkUtils.GetMaxMessageSize();

            while (!this._isDone)
            {
                Thread.Sleep(1000);
                try
                {
                    if (this._clientSocket.Available >= 4 /*Min size of CoAP block*/)
                    {
                        buffer = new byte[maxSize * 2];
                        int    bytesRead = this._clientSocket.Receive(buffer);
                        byte[] udpMsg    = new byte[bytesRead];
                        Array.Copy(buffer, udpMsg, bytesRead);
                        byte mType = AbstractCoAPMessage.PeekMessageType(udpMsg);

                        if ((mType == CoAPMessageType.CON ||
                             mType == CoAPMessageType.NON) && AbstractCoAPMessage.PeekIfMessageCodeIsRequestCode(udpMsg))
                        {
                            //This is a request
                            CoAPRequest coapReq = new CoAPRequest();
                            coapReq.FromByteStream(udpMsg);
                            coapReq.RemoteSender = this._remoteEP;//Setup who sent this message
                            string uriHost = ((IPEndPoint)this._remoteEP).Address.ToString();
                            UInt16 uriPort = (UInt16)((IPEndPoint)this._remoteEP).Port;

                            //setup the default values of host and port
                            //setup the default values of host and port
                            if (!coapReq.Options.HasOption(CoAPHeaderOption.URI_HOST))
                            {
                                coapReq.Options.AddOption(CoAPHeaderOption.URI_HOST, AbstractByteUtils.StringToByteUTF8(uriHost));
                            }
                            if (!coapReq.Options.HasOption(CoAPHeaderOption.URI_PORT))
                            {
                                coapReq.Options.AddOption(CoAPHeaderOption.URI_PORT, AbstractByteUtils.GetBytes(uriPort));
                            }

                            this.HandleRequestReceived(coapReq);
                        }
                        else
                        {
                            //This is a response
                            CoAPResponse coapResp = new CoAPResponse();
                            coapResp.FromByteStream(udpMsg);
                            coapResp.RemoteSender = this._remoteEP;//Setup who sent this message
                            //Remove the waiting confirmable message from the timeout queue
                            if (coapResp.MessageType.Value == CoAPMessageType.ACK ||
                                coapResp.MessageType.Value == CoAPMessageType.RST)
                            {
                                this._msgPendingAckQ.RemoveFromWaitQ(coapResp.ID.Value);
                            }
                            this.HandleResponseReceived(coapResp);
                        }
                    }
                }
                catch (SocketException se)
                {
                    //Close this client connection
                    this._isDone = true;
                    this.HandleError(se, null);
                }
                catch (ArgumentNullException argEx)
                {
                    this.HandleError(argEx, null);
                }
                catch (ArgumentException argEx)
                {
                    this.HandleError(argEx, null);
                }
                catch (CoAPFormatException fEx)
                {
                    //Invalid message..
                    this.HandleError(fEx, null);
                }
            }
        }
Ejemplo n.º 16
0
 /// <summary>
 /// Convert this object into a byte stream in network byte order
 /// </summary>
 /// <param name="reserved">Not used now</param>
 /// <returns>byte array</returns>
 public byte[] ToStream(UInt16 reserved)
 {
     byte[] mID = AbstractByteUtils.GetBytes(this.Value);
     mID = AbstractNetworkUtils.ToNetworkByteOrder(mID);
     return(mID);
 }
        /// <summary>
        /// Receive a message from the server. This will block if there
        /// are no messages. Please note, you must handle all errors (except timeout)
        /// and no error is raised.
        /// </summary>
        /// <param name="rxTimeoutMillis">
        /// The timeout value in milliseconds.The default value is 0, which indicates an infinite time-out period.
        /// Specifying -1 also indicates an infinite time-out period
        /// </param>
        /// <param name="timedOut">Is set to true on timeout</param>
        /// <returns>An instance of AbstractCoAPMessage on success, else null on error/timeout</returns>
        public AbstractCoAPMessage ReceiveMessage(int rxTimeoutMillis, ref bool timedOut)
        {
            byte[]       buffer   = null;
            int          maxSize  = AbstractNetworkUtils.GetMaxMessageSize();
            CoAPRequest  coapReq  = null;
            CoAPResponse coapResp = null;

            try
            {
                this._clientSocket.ReceiveTimeout = rxTimeoutMillis;
                buffer = new byte[maxSize * 2];
                int    bytesRead = this._clientSocket.Receive(buffer);
                byte[] udpMsg    = new byte[bytesRead];
                Array.Copy(buffer, udpMsg, bytesRead);
                byte mType = AbstractCoAPMessage.PeekMessageType(udpMsg);

                if ((mType == CoAPMessageType.CON ||
                     mType == CoAPMessageType.NON) && AbstractCoAPMessage.PeekIfMessageCodeIsRequestCode(udpMsg))
                {
                    //This is a request
                    coapReq = new CoAPRequest();
                    coapReq.FromByteStream(udpMsg);
                    coapReq.RemoteSender = this._remoteEP;//Setup who sent this message
                    string uriHost = ((IPEndPoint)this._remoteEP).Address.ToString();
                    UInt16 uriPort = (UInt16)((IPEndPoint)this._remoteEP).Port;

                    //setup the default values of host and port
                    //setup the default values of host and port
                    if (!coapReq.Options.HasOption(CoAPHeaderOption.URI_HOST))
                    {
                        coapReq.Options.AddOption(CoAPHeaderOption.URI_HOST, AbstractByteUtils.StringToByteUTF8(uriHost));
                    }
                    if (!coapReq.Options.HasOption(CoAPHeaderOption.URI_PORT))
                    {
                        coapReq.Options.AddOption(CoAPHeaderOption.URI_PORT, AbstractByteUtils.GetBytes(uriPort));
                    }

                    return(coapReq);
                }
                else
                {
                    //This is a response
                    coapResp = new CoAPResponse();
                    coapResp.FromByteStream(udpMsg);
                    coapResp.RemoteSender = this._remoteEP;//Setup who sent this message

                    return(coapResp);
                }
            }
            catch (SocketException se)
            {
                if (se.ErrorCode == (int)SocketError.TimedOut)
                {
                    timedOut = true;
                }
                else
                {
                    throw se;
                }
            }
            return(null);
        }
Ejemplo n.º 18
0
        /// <summary>
        /// This is the thread where the socket server will accept client connections and process
        /// </summary>
        protected void WaitForConnections()
        {
            EndPoint sender = null;

            byte[]    buffer        = null;
            ArrayList previousBytes = new ArrayList();
            int       bytesRead     = 0;
            byte      mType         = 0;
            UInt16    mId           = 0;

            byte[] udpMsg  = null;
            int    maxSize = AbstractNetworkUtils.GetMaxMessageSize();

            while (!this._isDone)
            {
                try
                {
                    if (this._socket.Available >= 4 /*Min size of CoAP block*/)
                    {
                        sender    = new IPEndPoint(IPAddress.Any, 0);
                        buffer    = new byte[maxSize * 2];
                        bytesRead = this._socket.ReceiveFrom(buffer, ref sender);
                        udpMsg    = new byte[bytesRead];
                        Array.Copy(buffer, udpMsg, bytesRead);

                        mType = AbstractCoAPMessage.PeekMessageType(udpMsg);
                        mId   = AbstractCoAPMessage.PeekMessageID(udpMsg);

                        if ((mType == CoAPMessageType.CON ||
                             mType == CoAPMessageType.NON) && AbstractCoAPMessage.PeekIfMessageCodeIsRequestCode(udpMsg))
                        {
                            this.ProcessRequestMessageReceived(udpMsg, ref sender);
                        }
                        else
                        {
                            this.ProcessResponseMessageReceived(udpMsg, ref sender);
                        }
                    }
                    else
                    {
                        //Nothing on the socket...wait
                        Thread.Sleep(5000);
                    }
                }
                catch (SocketException se)
                {
                    //Try to re-initialize socket, and proceed only when the socket
                    //is successfully re-initialized
                    this._isDone = !this.ReInitSocket();
                    this.HandleError(se, null);
                }
                catch (ArgumentNullException argEx)
                {
                    if (mType == CoAPMessageType.CON)
                    {
                        this.RespondToBadCONRequest(mId);
                    }
                    this.HandleError(argEx, null);
                }
                catch (ArgumentException argEx)
                {
                    if (mType == CoAPMessageType.CON)
                    {
                        this.RespondToBadCONRequest(mId);
                    }
                    this.HandleError(argEx, null);
                }
                catch (CoAPFormatException fEx)
                {
                    //Invalid message..
                    if (mType == CoAPMessageType.CON)
                    {
                        this.RespondToBadCONRequest(mId);
                    }
                    this.HandleError(fEx, null);
                }
            }
        }
Ejemplo n.º 19
0
        /// <summary>
        /// Create a header option by parsing the coap data stream
        /// </summary>
        /// <param name="coapStream">The CoAP message stream that contains the option</param>
        /// <param name="startIndex">The index to start looking for the option</param>
        /// <param name="previousOptionNumber">The previous option number in the sequence of options</param>
        /// <returns>The next index from where next set of information can be extracted from the message stream</returns>
        public int Parse(byte[] coapStream, int startIndex, UInt16 previousOptionNumber)
        {
            if (coapStream == null || coapStream.Length < startIndex || startIndex < AbstractCoAPMessage.HEADER_LENGTH)
            {
                throw new ArgumentNullException("CoAP stream is null or start index is invalid");
            }
            int  nextIndex    = startIndex;
            byte optionDelta  = (byte)((coapStream[nextIndex] & 0xF0) >> 4);
            byte optionLength = (byte)(coapStream[nextIndex] & 0x0F);

            UInt16 optionStreamSizeInBytes = 1;

            //Calculate option number
            if (optionDelta < 13)
            {
                this.Number = (UInt16)(optionDelta + previousOptionNumber);
            }
            else if (optionDelta == 13)
            {
                this.Number              = (UInt16)((UInt16)coapStream[++nextIndex] + 13 + previousOptionNumber);
                optionStreamSizeInBytes += 1;
            }
            else if (optionDelta == 14)
            {
                byte[] optionDeltaEx = new byte[] { coapStream[++nextIndex], coapStream[++nextIndex] };
                optionDeltaEx            = AbstractNetworkUtils.FromNetworkByteOrder(optionDeltaEx);
                this.Number              = (UInt16)(AbstractByteUtils.ToUInt16(optionDeltaEx) + (UInt16)269 + previousOptionNumber);
                optionStreamSizeInBytes += 2;
            }
            else if (optionDelta == 15)
            {
                throw new CoAPFormatException("Option delta cannot contain payload marker value");
            }

            //Calculate option value length
            if (optionLength < 13)
            {
                ValueSizeInBytes = optionLength;
            }
            else if (optionLength == 13)
            {
                ValueSizeInBytes         = (UInt16)(coapStream[++nextIndex] + 13);
                optionStreamSizeInBytes += 1;
            }
            else if (optionLength == 14)
            {
                byte[] optionLengthEx = new byte[] { coapStream[++nextIndex], coapStream[++nextIndex] };
                optionLengthEx           = AbstractNetworkUtils.FromNetworkByteOrder(optionLengthEx);
                ValueSizeInBytes         = (UInt16)(AbstractByteUtils.ToUInt16(optionLengthEx) + (UInt16)269);
                optionStreamSizeInBytes += 2;
            }
            else if (optionLength == 15)
            {
                throw new CoAPFormatException("Option length cannot be 0x0F. This is a reserved value");
            }
            //Check if option is of type uint or is empty
            if ((this.NeedsByteOrdering(this.Number) && optionLength == 0) || this.IsEmpty())
            {
                //this means that the value of the option is zero or this is an empty option
                Value = null;
            }
            else if (ValueSizeInBytes > 0) //normal processing
            {
                //Get option Value
                Value = new byte[ValueSizeInBytes];
                Array.Copy(coapStream, ++nextIndex, Value, 0, ValueSizeInBytes);
                if (this.NeedsByteOrdering(this.Number))
                {
                    Value = AbstractNetworkUtils.FromNetworkByteOrder(Value);
                }
                optionStreamSizeInBytes += ValueSizeInBytes;
            }
            return(startIndex + optionStreamSizeInBytes);
        }