Skip to content
Permalink
b50d8d34a1
Switch branches/tags

Name already in use

A tag already exists with the provided branch name. Many Git commands accept both tag and branch names, so creating this branch may cause unexpected behavior. Are you sure you want to create this branch?
Go to file
 
 
Cannot retrieve contributors at this time

Lab Session 2

Prerequisites

  • You must be able to access the remote server and use an editor to edit files on the remote server
  • You must have access to a mote (you should have been allocated one)
  • You must have Cooja set up in either your local environment or on the VNC server provided

Learning outcomes

  • Gain a better understanding of routing protocols in Contiki-NG.
  • Be able to understand and modify the RPL UDP examples to suit your needs.
  • Be able to set up a new Cooja environment with your newly defined nodes and run a simulation.
  • Be able to compile the code onto physical motes and check that it’s working.

Simple RPL network with 2 nodes

In this exercise you will take two RPL UDP examples and modify them so that they have two distinct and simplified behaviours. This will allow you to better understand what each of the simple_udp components do and how to edit them to suit your needs.

Start by finding the two rpl-udp examples:

examples/rpl_udp/udp_client.c
examples/rpl_udp/udp_server.c

Create a copy of the rpl_udp folder so you can edit the file freely and still keep the originals. Make sure you are in the contiki-ng/examples folder when you do this.

cp -r rpl_udp my_rpl_app

Step 1 - Simplifying the code

Edit the newly copied files by removing anything except the raw transmission and reply features.

You should get the below code for your client:

#include "contiki.h"
#include "net/routing/routing.h"
#include "random.h"
#include "net/netstack.h"
#include "net/ipv6/simple-udp.h"

#include "sys/log.h"
#define LOG_MODULE "App"
#define LOG_LEVEL LOG_LEVEL_INFO

#define UDP_CLIENT_PORT 8765
#define UDP_SERVER_PORT 5678

#define SEND_INTERVAL     (10 * CLOCK_SECOND)

static struct simple_udp_connection udp_conn;

PROCESS(udp_client_process, "UDP client");
AUTOSTART_PROCESSES(&udp_client_process);

PROCESS_THREAD(udp_client_process, ev, data)
{
  static struct etimer periodic_timer;
  static char str[32];
  uip_ipaddr_t dest_ipaddr;

  PROCESS_BEGIN();

  /* Initialize UDP connection */
  simple_udp_register(&udp_conn, UDP_CLIENT_PORT, NULL,
                      UDP_SERVER_PORT, NULL);

  etimer_set(&periodic_timer, SEND_INTERVAL);


  while(1) {
    PROCESS_WAIT_EVENT_UNTIL(etimer_expired(&periodic_timer));

    if(NETSTACK_ROUTING.node_is_reachable() && NETSTACK_ROUTING.get_root_ipaddr(&dest_ipaddr)) {
      /* Send to DAG root */
      LOG_INFO("Sending request to ");
      LOG_INFO_6ADDR(&dest_ipaddr);
      LOG_INFO_("\n");
      snprintf(str, sizeof(str), "hello from client");
      simple_udp_sendto(&udp_conn, str, strlen(str), &dest_ipaddr);
    } else {
      LOG_INFO("Not reachable yet\n");
    }

    /* Send Event Timer */
    etimer_set(&periodic_timer, SEND_INTERVAL);
  }

  PROCESS_END();
}

Use the following code for the server:

#include "contiki.h"
#include "net/routing/routing.h"
#include "net/netstack.h"
#include "net/ipv6/simple-udp.h"

#include "sys/log.h"
#define LOG_MODULE "App"
#define LOG_LEVEL LOG_LEVEL_INFO

#define UDP_CLIENT_PORT 8765
#define UDP_SERVER_PORT 5678

static struct simple_udp_connection udp_conn;

PROCESS(udp_server_process, "UDP server");
AUTOSTART_PROCESSES(&udp_server_process);

static void
udp_rx_callback(struct simple_udp_connection *c,
         const uip_ipaddr_t *sender_addr,
         uint16_t sender_port,
         const uip_ipaddr_t *receiver_addr,
         uint16_t receiver_port,
         const uint8_t *data,
         uint16_t datalen)
{
  LOG_INFO("Received request '%.*s' from ", datalen, (char *) data);
  LOG_INFO_6ADDR(sender_addr);
  LOG_INFO_("\n");
}

PROCESS_THREAD(udp_server_process, ev, data)
{
  PROCESS_BEGIN();

  /* Initialize DAG root */
  NETSTACK_ROUTING.root_start();

  /* Initialize UDP connection */
  simple_udp_register(&udp_conn, UDP_SERVER_PORT, NULL,
                      UDP_CLIENT_PORT, udp_rx_callback);

  PROCESS_END();
}

Step 2 - Compiling the code to check for errors

Once your code is edited, try compiling it with the make commands and correct any errors.

make TARGET=sky udp_client
make TARGET=sky udp_server

Step 2 - Loading the code onto Cooja and testing it

Once you are happy that your code compiles, create a Cooja simulation with two motes. You should initially add one server and one client.

After running the code you should see the output similar to the following. Note that several “Not reachable yet” messages occur before messages from the client are transmitted to the server.

figures/cooja-networking.png

Group exercise

This exercise will have you working in separate break-out rooms with each room setting up their own RPL network tree. You each have access to a single mote so you will need to work together to set up the network and be able to send and receive messages. To ensure that you do not conflict with other rooms, edit your code to use the client and server port numbers assigned to your room.

Step 1 - Change both port numbers

#define UDP_CLIENT_PORT xxxx  # <- change 
#define UDP_SERVER_PORT yyyy  # <- change 

Assign one person to run the server - the others will run clients.

Optionally, add a LED blink when you send (red) or receive (green).

Hint: This can be done, by turning on a led when the message is sent, waiting a brief period of time and turning it off again. e.g.,

leds_on(LEDS_RED);
etimer_set(&et, CLOCK_SECOND/10);
PROCESS_WAIT_EVENT_UNTIL(etimer_expired(&et));
leds_off(LEDS_RED);

Step 2 - Download the code to the mote and run!

To upload your code the your device:

Build the project for the example file ‘my_test.c’

make TARGET=sky my_test

Upload the compiled files to the device where x is your usb number.

make my_test.upload PORT=/dev/ttyUSB[x]

Log in to see the outputs.

make login PORT=/dev/ttyUSB[x]

Hopefully it works! Good luck!