REST example running on Cooja and Sky motes

From Contiki
Revision as of 21:06, 7 November 2014 by Muni (Talk | contribs) (COAP Example)

Jump to: navigation, search

Introduction

REST (Representational State Transfer) is an architectural style consisting of coordinated set of architectural constraints applied to components, connectors and data elements within a distributed hypermedia system. The REST architectural style is applied to development of web services. A web service can be characterized as RESTful if they conform to architectural constraints like client-server, stateless, cacheable, layered system and uniform Interface. A REST architecture style is one in which web services are viewed as resources and can be uniquely identified by their URLs. RESTful architecture can be run over HTTP or COAP. The basic REST design principle uses the HTTP protocol methods for typical CRUD operations:

  • POST - Create a resource
  • GET - Retrieve a resource
  • PUT – Update a resource
  • DELETE - Delete a resource

Each resource has a handler function which the REST layer calls to serve the request by the client.

You Will Learn

How to use REST layer to develop server-side applications like COAP or HTTP and run it on COOJA and using T-mote sky.

Relavant Directories

  • /contiki-2.7/apps/rest-common - It contains the codes that are mentioned as target in the rest-example.
  • /contiki-2.7/apps/rest-coap - It contains codes for codes mentioned as target in rest-common.
  • /contiki-2.7/apps/rest-http - It contains codes for codes mentioned as target in rest-common.
  • /contiki-2.7/examples/rest-example - It has the main example of the REST server side and COAP client side codes that are to be uploaded on COOJA and real motes.

Understanding The Code

rest-server-example.c

The REST server has light, led, toggle, helloworld and discover resources. Each resource has a resource handler function which is called when the client requests for that resource and the resource handler function sends the response back to the client. For example, when a HTTP client sends a request to the REST server for light resource, the REST server calls the light_handler function which reads the light sensor values from the mote and sends the light sensor values along with a simple etag back to the client as shown below.

/*A simple getter example. Returns the reading from light sensor with a simple etag*/
RESOURCE(light, METHOD_GET, "light");
void
light_handler(REQUEST* request, RESPONSE* response)
{
  read_light_sensor(&light_photosynthetic, &light_solar);
  sprintf(temp,"%u;%u", light_photosynthetic, light_solar);

  char etag[4] = "ABCD";
  rest_set_header_content_type(response, TEXT_PLAIN);
  rest_set_header_etag(response, etag, sizeof(etag));
  rest_set_response_payload(response, temp, strlen(temp));
}

coap-client-example.c

The COAP client establishes a connection with the server on the COAP port 61616 and sets the et timer to a particular value. Everytime the et timer is expired, the send_data(void) function is called. When it recieves the response from the server for its request, the handle_incoming_data() function is called as shown in the code snippet within the process.

    etimer_set(&et, 5 * CLOCK_SECOND);
  while(1) {
    PROCESS_YIELD();
    if (etimer_expired(&et)) {
      send_data();
      etimer_reset(&et);
    } else if (ev == tcpip_event) {
      handle_incoming_data();
    }
  }

The COAP client runs a timer which when resets, the client randomly selects a service_id (resource) using random_rand() function and sends the request to the REST server as seen below in the send_data(void) function.

    int data_size = 0;
    int service_id = random_rand() % NUMBER_OF_URLS;
    coap_packet_t* request = (coap_packet_t*)allocate_buffer(sizeof(coap_packet_t));
    init_packet(request);

    coap_set_method(request, COAP_GET);
    request->tid = xact_id++;
    request->type = MESSAGE_TYPE_CON;
    coap_set_header_uri(request, service_urls[service_id]);


When the server response returns back to the client, it runs the handle_incoming_data() function which takes the packet, parses the message and prints the payload that is it receives from the response. It can be seen in the code below

static void
handle_incoming_data()
{
  PRINTF("Incoming packet size: %u \n", (uint16_t)uip_datalen());
  if (init_buffer(COAP_DATA_BUFF_SIZE)) {
    if (uip_newdata()) {
      coap_packet_t* response = (coap_packet_t*)allocate_buffer(sizeof(coap_packet_t));
      if (response) {
        parse_message(response, uip_appdata, uip_datalen());
        response_handler(response);
      }
    }
    delete_buffer();
  }
}

Run the REST-Example on COOJA

HTTP Example

1. Open the Makefile in the /contiki-2.7/examples/rest-example folder. For HTTP server, make sure the WITH_COAP = 0 in the Makefile.


2. Open the terminal. Go to the /contiki-2.7/examples/rest-example folder. Run the following command given below:

make TARGET=cooja rest-server-example.csc

This will open a COOJA terminal and loads the rest-server-example code for simulation. The Network will look as shown:

Networkhttp.PNG


3. Open another terminal. Go to the same directory and connect the COOJA simulation to the router.

make connect-router-cooja


4. Start the Simulation on the COOJA and test the connectivity by pinging the server. The IP addresses of the servers are aaaa::0212:7402:0002:0202 and aaaa::0212:7403:0003:0303.

ping6 aaaa::0212:7402:0002:0202

ping6 aaaa::0212:7403:0003:0303


5. Use curl as a HTTP client we interact with the COOJA motes that are running the REST code. The default HTTP client runs on 8080 port number.

curl -H "User-Agent: curl" aaaa::0212:7402:0002:0202:8080/helloworld #get helloworld plain text

curl -H "User-Agent: curl" aaaa::0212:7402:0002:0202:8080/led?color=green -d mode=off -i #turn off the green led

curl -H "User-Agent: curl" aaaa::0212:7402:0002:0202:8080/.well-known/core -i

curl -X POST -H "User-Agent: curl" aaaa::0212:7402:0002:0202:8080/helloworld #method not allowed


COAP Example

1. Open the Makefile in the /contiki-2.7/examples/rest-example folder. For COAP server, make sure the WITH_COAP = 1 in the Makefile.

2. Open the terminal. Go to the /contiki-2.7/examples/rest-example folder. Run the following command given below:

make TARGET=cooja coap-client-server-example.csc

This opens the COOJA terminal which runs rest-server-example.c over COAP in one node having IP address aaaa::0212:7401:0001:0101 and coap-client-example.c in the another node having IP address aaaa::0212:7402:0002:0202. COAP uses 61616 port number as default. The client in the example periodically accesses the resources of the server and prints the payload which can be seen on the mote output. The Network looks as shown below:

Coapnetwork.PNG

3.Start the Simulation and observe the mote output.

Coapmoteout.PNG

Run the REST-Example on T-mote Sky

1. Go to the /contiki-2.7/examples/rest-example folder. Connect the motes and program them with rest-server-example.

make TARGET=sky rest-server-example.upload


2. Disconnect the motes and load one other mote with the RPL border router to connect to the rest-server.

cd ../ipv6/rpl-border-router

make TARGET=sky border-router.upload


3. Connect the REST-server to the border router using tunslip6.

make connect-router


4. Open new terminal window for each mote and execute the following command and reset the motes. The IP addresses of these motes get printed after the motes are reset.

make login TARGET=sky MOTE=2 #Shows the prints for first mote

make login TARGET=sky MOTE=3 #For second mote and so on.


5. Ping the motes using the IP addresses we get from step 4.

ping6 <IPv6 Address of the MOTE>


6. If WITH_COAP = 0 i.e. HTTP Server, use the HTTP Client to connect to the REST server. When WITH_COAP = 1. i.e. COAP Server, load the coap-client-example.c to the motes and connect to the REST server (same as COOJA Example).


General Issues You Might Face

1. To use curl as the HTTP client you need to install curl by running the following command in the terminal:

sudo apt-get install curl

2. The memory on the Tmote sky is not big enough to fit in the HTTP example on REST server. Thus while running it on real motes we get the error “region text is full”. To overcome this problem, instead of RPL to decide the route, we can use static routes. We can also reduce the size by changing the Makefile of the border router by setting the WITH_WEBSERVER = 0.

3. Generally the COAP Client is used instead of HTTP client for running over REST Server.


References

1. REST-Example Github page: https://github.com/contiki-os/contiki/tree/master/examples/rest-example

2. A Low-Power CoAP for Contiki - Matthias Kovatsch, Simon Duquennoy, Adam Dunkels