Your First CoAP Server

Your First CoAP Server

How to write the bare-minimum (a.k.a Hello World) CoAP server

While the size of this post may look large, we could have given you an overly simple implementation. However, by doing that, we would have missed giving you some insights in terms of how to do this right. Therefore, do not get panicked by the size of the post. The total lines of code is less than 150.

Pre-Requisites:

  1. You need Microsoft .NET Micro Framework 4.2
  2. You need Visual Studio 2010 or higher (even an express edition will do)
  3. This tutorial will use the emulator, but if you wish, you can download this to a Netduino 2 Plus board. For working with Netduino, please visit their website

Example Scenario: 

Let’s take an example based on which this CoAP server will be built. Let’s assume we have a sensor installed in the conference room of your office, that is measuring the temperature constantly. Another controller, that is responsible to take actions to ensure that the cooling system adjusts the cooling now needs to now the temperature. So, the controller is the CoAP client and the temperature monitor in the conference room is the server.

Key Concepts Covered:

  1. How to use CoAPSharp library to build a CoAP server
  2. How to listen for requests
  3. How to check message types (e.g. CON, NON)
  4. How to check message codes (e.g. GET, POST)
  5. How to extract the requested URI and take action
  6. How to respond back to client in case of an error
  7. How to respond back to client in case of a success
  8. How to send JSON data back to client

Steps: 

  1. Create a console project in Microsoft .NET Micro framework (or a Netduino 2 Plus Application for Netduino boards)
    SelectProject_ConsoleApp
  2. Now, pickup the CoAPSharp binary and add that as a reference
    AddCoAPSharpReference
  3. Now open the file named Program.cs and define an instance of the CoAPServerChannel class
    /// <summary>
    /// Holds the instance of the server channel class
    /// </summary>
    private CoAPServerChannel _coapServer = null;
    /// <summary>
    /// The main entry point for the program
    /// </summary> 
    public static void Main()
    {            
    }
  4. Next step is to setup so that we can start the server. Code is given below, self-explanatory!
    public class Program
    {        
    	/// <summary>
            /// Holds the instance of the server channel class
            /// </summary>
            private CoAPServerChannel _coapServer = null;
            /// <summary>
            /// The main entry point for the program
            /// </summary> 
            public static void Main()
            {
                Program p = new Program();
                p.StartServer();
                Thread.Sleep(Timeout.Infinite);//block here
            }
            /// <summary>
            /// Start the server
            /// </summary>
            public void StartServer()
            {
            }
    }
  5. Now, in the “StartServer” method, create an instance of the CoAPServerChannel and bind the events.
    /// <summary>
    /// Start the server
    /// </summary>
    public void StartServer()
    {
        this._coapServer = new CoAPServerChannel();
        this._coapServer.Initialize(null, 5683);//Initialize and listen on default CoAP port
        //Setup event listeners
        this._coapServer.CoAPRequestReceived += new CoAPRequestReceivedHandler(OnCoAPRequestReceived);
        this._coapServer.CoAPResponseReceived += new CoAPResponseReceivedHandler(OnCoAPResponseReceived);
        this._coapServer.CoAPError += new CoAPErrorHandler(OnCoAPError);
    }
  6. As stated before, our server sends the conference room’s temperature. Since we are running in simulation mode, simply create a new method that for now, returns a dummy temperature value. The code snippet is shown below:
    /// <summary>
    /// A dummy method to get the room temperature...in real life,
    /// this would be the real work the machine/sensor is required to do
    /// </summary>
    /// <returns>Temp in degree C</returns>
    private int GetRoomTemperature()
    {
        int temp = DateTime.Now.Second;
        if (temp < 15) temp = 25;// just do not want to show that it's too cold!
        return temp;
    }
  7. In this example, we will not look at error handling and we are not handling any responses, we will only look at handling requests. The request processing event handler code is given below:
    /// <summary>
    /// Called when a request is received
    /// </summary>
    /// <param name="coapReq">The CoAPRequest object</param>
    void OnCoAPRequestReceived(CoAPRequest coapReq)
    {
        //This sample only works on NON requests of type GET
        //This sample simualtes a temperature sensor at the path "sensors/temp"
    
        string reqURIPath = (coapReq.GetPath() != null) ? coapReq.GetPath().ToLower() : "";
        /**
            * Draft 18 of the specification, section 5.2.3 states, that if against a NON message,
            * a response is required, then it must be sent as a NON message
            */ 
        if (coapReq.MessageType.Value != CoAPMessageType.NON)
        {
            //only NON  combination supported..we do not understand this send a RST back
            CoAPResponse msgTypeNotSupported = new CoAPResponse(CoAPMessageType.RST, /*Message type*/
                                                                CoAPMessageCode.NOT_IMPLEMENTED, /*Not implemented*/
                                                                coapReq.ID.Value /*copy message Id*/);
            msgTypeNotSupported.Token = coapReq.Token; //Always match the request/response token
            msgTypeNotSupported.RemoteSender = coapReq.RemoteSender;
            //send response to client
            this._coapServer.Send(msgTypeNotSupported);
        }
        else if (coapReq.Code.Value != CoAPMessageCode.GET)
        {
            //only GET method supported..we do not understand this send a RST back
            CoAPResponse unsupportedCType = new CoAPResponse(CoAPMessageType.RST, /*Message type*/
                                                CoAPMessageCode.METHOD_NOT_ALLOWED, /*Method not allowed*/
                                                coapReq.ID.Value /*copy message Id*/);
            unsupportedCType.Token = coapReq.Token; //Always match the request/response token
            unsupportedCType.RemoteSender = coapReq.RemoteSender;
            //send response to client
            this._coapServer.Send(unsupportedCType);
        }
        else if (reqURIPath != "sensors/temp")
        {
            //classic 404 not found..we do not understand this send a RST back 
            CoAPResponse unsupportedPath = new CoAPResponse(CoAPMessageType.RST, /*Message type*/
                                                CoAPMessageCode.NOT_FOUND, /*Not found*/
                                                coapReq.ID.Value /*copy message Id*/);
            unsupportedPath.Token = coapReq.Token; //Always match the request/response token
            unsupportedPath.RemoteSender = coapReq.RemoteSender;
            //send response to client
            this._coapServer.Send(unsupportedPath);
        }
        else
        {
            //All is well...send the measured temperature back
            //Again, this is a NON message...we will send this message as a JSON
            //string
            Hashtable valuesForJSON = new Hashtable();
            valuesForJSON.Add("temp", this.GetRoomTemperature());
            string tempAsJSON = JSONResult.ToJSON(valuesForJSON);
            //Now prepare the object
            CoAPResponse measuredTemp = new CoAPResponse(CoAPMessageType.NON, /*Message type*/
                                                CoAPMessageCode.CONTENT, /*Carries content*/
                                                coapReq.ID.Value/*copy message Id*/);
            measuredTemp.Token = coapReq.Token; //Always match the request/response token
            //Add the payload
            measuredTemp.Payload = new CoAPPayload(tempAsJSON);
            //Indicate the content-type of the payload
            measuredTemp.AddOption(CoAPHeaderOption.CONTENT_FORMAT,
                                AbstractByteUtils.GetBytes(CoAPContentFormatOption.APPLICATION_JSON));
            //Add remote sender address details
            measuredTemp.RemoteSender = coapReq.RemoteSender;
            //send response to client
            this._coapServer.Send(measuredTemp);
        }
    }

The code above needs some explanation…here are key aspects:

  • First we get the requested URI from the CoAPRequest object. Store that for future.
  • Next, we check if the message type is NON. If not, we respond back with RST message stating that this is not implemented. Please note, we copy over the message ID and the token of request to the response.
  • As a technical requirement, the remote sender details are also copied over. During a send operation, the server extract this value and sends to the address encapsulated in the remote sender
  • Now, we check that the method code must be GET. This server does not support anything else. If not, then once again “METHOD_NOT_ALLOWED” error code is sent.
  • Finally, we check if the URI path requested is supported. If not, the classic “404″ NOT FOUND response is sent back.
  • Last, when we find everything is well, we get the temperature, create a simple JSON string, add that to the payload and send back to the client.

There you go…you have your first CoAP server!

Here are the source files.

8 Responses so far.

  1. duythang says:

    Hello
    I have a question. Please help me.
    At step 2 : “Now, pickup the CoAPSharp binary and add that as a reference”
    When i download source code here “http://www.coapsharp.com/releases/”.
    i did not see any CoAPSharp binary, so where can i download it ?
    Hope receive your response early.
    Thank you so much

  2. duythang says:

    Has anyone can help me ? :(

    • administrator says:

      Hi,
      We were having trouble with our website after we installed a WordPress plugin update over a week ago. We have now been able to recover all items. Hope you have downloaded the library. The link is working now. We sincerely apologize for this issue. We are trying to improve our patch application process to this website so that we can avoid such a situation form happening again and we can provide support more actively.
      In future, if you have any issues with this website and need support, you can also visit the http://www.coapsharp.com/contact-us/ link and connect with us via email.

      • duythang says:

        Hi
        Thank you for your response.
        Actually, with above link, i can download nomally.
        But i am practicing following your above guider.
        At step 2 : “Now, pickup the CoAPSharp binary and add that as a reference”
        I can not add “coapsharp” in reference on Visual Studio like picture
        because there are not this binary in source code of above link (Srouce code is only .cs file)
        So how can i get this binary ?
        Thank you

        • administrator says:

          Hi,
          We provide the source code of the CoAPSharp library under LGPL license. There are two ways you can do this:
          1. Download the library source code and recompile. The output will be a DLL (assembly) that you can incorporate in your project.
          2. Download the library source code and add that as a project in your main solution. Then, in your application, add the CoAPSharp project as a reference.

          Hope this helps

  3. duythang says:

    Hi
    Thank you for your response.
    Actually, with above link, i can download nomally.
    But i am practicing following your above guider.
    At step 2 : “Now, pickup the CoAPSharp binary and add that as a reference”

    I can not add “coapsharp” in reference on Visual Studio like picture
    because there are not this binary in source code of above link (Srouce code is only .cs file)
    So how can i get this binary ?
    Thank you

  4. Jennie says:

    Hi,
    The step 2 says “Now, pickup the CoAPSharp binary and add that as a reference”. I did not find the coapsharp binary in the source that you provided. Can you please tell me where is it?

Leave a Reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>