Your First CoAP Client

Your First CoAP Client

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

There are two ways you can build the client, either using the CoAPSyncClientChannel class that uses synchronous communication, or using the CoAPClientChannel that uses asynchronous communication. This sample uses the asynchronous method. The total lines of code is less than 100.

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 client 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 know 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 client
  2. How to send NON requests and get NON requests back
  3. How to check correlated messages
  4. How to extract JSON data from the message

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
  3. Now open the file named Program.cs and define an instance of the CoAPClientChannel class. Also, define a string variable to hold the token value. The token value will be sent in the NON request to the server. Once we receive another NON request from the server, we will use the token value to see if the received NON request was for the NON request we sent to the server
    /// <summary>
    /// Holds the instance of the CoAP client channel object
    /// </summary>
    private static CoAPClientChannel _coapClient = null;
    /// <summary>
    /// Used for matching request / response / associated request
    /// </summary>
    private static string _mToken = "";
    /// <summary>
    /// The entry point method
    /// </summary>
    public static void Main()
  4. Next step is to setup so that we can initialize the client and register for appropriate events (remember, this is asynchronous). We do this in the main method in this sample.
    /// <summary>
    /// The entry point method
    /// </summary>
    public static void Main()
    {
        string serverIP = "localhost";
        int serverPort = 5683;
    
        _coapClient = new CoAPClientChannel();
        _coapClient.Initialize(serverIP, serverPort);
        _coapClient.CoAPResponseReceived += new CoAPResponseReceivedHandler(OnCoAPResponseReceived);
        _coapClient.CoAPRequestReceived += new CoAPRequestReceivedHandler(OnCoAPRequestReceived);
        _coapClient.CoAPError += new CoAPErrorHandler(OnCoAPError);

    In the code above, we instantiate the client channel, initialize the channel and then register for the event handlers. In this sample, we will only focus on the event handler “OnCoAPRequestReceived”

  5. Next, we will construct a NON message type. Interesting thing to note is, that just like an HTTP request, we are putting a request URI (with the scheme as coap) .
    /// <summary>
    /// The entry point method
    /// </summary>
    public static void Main()
    {
        string serverIP = "localhost";
        int serverPort = 5683;
    
        _coapClient = new CoAPClientChannel();
        _coapClient.Initialize(serverIP, serverPort);
        _coapClient.CoAPResponseReceived += new CoAPResponseReceivedHandler(OnCoAPResponseReceived);
        _coapClient.CoAPRequestReceived += new CoAPRequestReceivedHandler(OnCoAPRequestReceived);
        _coapClient.CoAPError += new CoAPErrorHandler(OnCoAPError);
        //Send a NON request to get the temperature...in return we will get a NON request from the server
        CoAPRequest coapReq = new CoAPRequest(CoAPMessageType.NON,
                                            CoAPMessageCode.GET,
                                            100);//hardcoded message ID as we are using only once
        string uriToCall = "coap://" + serverIP + ":" + serverPort + "/sensors/temp";
        coapReq.SetURL(uriToCall);
        _mToken = DateTime.Now.ToString("HHmmss");//Token value must be less than 8 bytes
        coapReq.Token = new CoAPToken(_mToken);//A random token
        _coapClient.Send(coapReq);
        Thread.Sleep(Timeout.Infinite);//blocks
    }
  6. Once we send the NON request to the server, we expect a response from the server. So now let’s focus on the handler. While generally, you would expect a Request/Response mechanism, in CoAP, for NON messages, this boundary becomes confusing. For a NON request, if you are expecting a response, then it should be another NON. Therefore, please rememb we treat the NON response as a request only. Thus, NON is always a requeer, NON can be in a request as well as in a response. Whether the message is a request or a response is determined additionally, by the message code. If message code has PUT, GET, POST or DELETE, then it’s understood to be a request message, else it’s understood to be a response message. Therefore, in this case, we sent a NON request and we are expecting a NON response.
    /// <summary>
    /// Called when a response is received against a sent request
    /// </summary>
    /// <param name="coapResp">The CoAPResponse object</param>
    static void OnCoAPResponseReceived(CoAPResponse coapResp)
    {
        string tokenRx = (coapResp.Token != null && coapResp.Token.Value != null) ? AbstractByteUtils.ByteToStringUTF8(coapResp.Token.Value) : "";
        if (tokenRx == _mToken)
        {
            //This response is against the NON request for getting temperature we issued earlier
            if (coapResp.Code.Value == CoAPMessageCode.CONTENT)
            {
                //Get the temperature
                string tempAsJSON = AbstractByteUtils.ByteToStringUTF8(coapResp.Payload.Value);
                Hashtable tempValues = JSONResult.FromJSON(tempAsJSON);
                int temp = Convert.ToInt32(tempValues["temp"].ToString());
                //Now do something with this temperature received from the server
            }
            else
            {
                //Will come here if an error occurred..
            }
        }
    }

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

  • First we get the token that was sent by the server.
  • In this case, we match the received token with the token we had sent before. We are only interested in messages correlated with the NON request we had sent before. Message correlation in CoAP is via Tokens.
  • If the tokens match, then we check if we received the “CONTENT” or not. Any other value indicates an error (in this sample. To understand, we request that you first read the CoAP server sample)
  • When the tokens match and the request contains “CONTENT”, we should have received the temperature in the payload. The payload is a byte array.
  • Convert that byte array to UTF-8 string using the utility class. This string represents a JSON string (For this example the format is {“temp” : NN})
  • Use the JSONResult object to convert the JSON into a hashtable as key/value pairs and then extract the value of the temperature.

There you go…you have your first CoAP client!

Here are the source files

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>