Hello-world-james
From Glacsweb Wiki
#include "contiki.h"
#include "net/rime.h"
#include "lib/list.h"
#include "lib/memb.h"
#include "lib/random.h"
#include "dev/button-sensor.h"
#include "dev/leds.h"
#include <stdio.h>
#define CHANNEL 135
//define the structure of a neighbor
struct example_neighbor {
struct example_neighbor *next;
rimeaddr_t addr;
struct ctimer ctimer;
};
//neighbors time out after 60 'seconds'
#define NEIGHBOR_TIMEOUT 60 * CLOCK_SECOND
#define MAX_NEIGHBORS 16
LIST(neighbor_table);
MEMB(neighbor_mem, struct example_neighbor, MAX_NEIGHBORS);
/*---------------------------------------------------------------------------*/
PROCESS(hello_world_process, "Hello world process");
AUTOSTART_PROCESSES(&hello_world_process);
/*---------------------------------------------------------------------------*/
/**
* This function is called by the ctimer in each neighbor. This removes the neighbor from
* the table because it's too old
*/
static void remove_neighbor(void *n) {
struct example_neighbor *e = n;
list_remove(neighbor_table, e);
memb_free(&neighbor_mem, e);
}
/**
* This function is called when an announcement arrives.
* Adds the neighbor if it is new
*/
static void received_announcement(struct announcement *a, rimeaddr_t *from, uint16_t id, uint16_t value){
struct example_neighbor *e;
printf("Got announcement from %d.%d, id %d, value %d\n", from->u8[0], from->u8[1], id, value);
//update neighbor list or add new entry
for(e = list_head(neighbor_table); e != NULL; e = e->next) {
if(rimeaddr_cmp(from, &e->addr)){
//found the neighbor so update timeout
ctimer_set(&e->ctimer, NEIGHBOR_TIMEOUT, remove_neighbor, e);
return;
}
}
//the neighbor was not found, so we will add it by allocating memory from the pool
e = memb_alloc(&neighbor_mem);
if(e != NULL) {
rimeaddr_copy(&e->addr, from);
list_add(neighbor_table, e);
ctimer_set(&e->ctimer, NEIGHBOR_TIMEOUT, remove_neighbor, e);
}
}
static struct announcement example_announcement;
/*
* This function is called at the final recipient of the message
*/
static void recv(struct multihop_conn *c, const rimeaddr_t *sender, const rimeaddr_t *prevhop, uint8_t hops) {
printf("multihop message received '%s'\n", (char *)packetbuf_dataptr());
}
/**
* This function is called to forward a packet. Picks a random neighbor
* Drops packet if no neighbor found
*/
static rimeaddr_t * forward(struct multihop_conn *c, const rimeaddr_t *originator, const rimeaddr_t *dest, const rimeaddr_t *prevhop, uint8_t hops) {
//find random neighbor
int num, i;
struct example_neighbor *n;
printf("Neighbor table list length: %d\n", list_length(neighbor_table));
if(list_length(neighbor_table) > 0) {
num = random_rand() % list_length(neighbor_table);
i = 0;
for(n = list_head(neighbor_table); n != NULL && i != num; n = n->next) {
++i;
}
if(n != NULL) {
printf("%d.%d: Forwarding packet to %d.%d (%d in list), hops %d\n",
rimeaddr_node_addr.u8[0], rimeaddr_node_addr.u8[1], n->addr.u8[0], n->addr.u8[1], num, packetbuf_attr(PACKETBUF_ATTR_HOPS));
return &n->addr;
}
}
printf("%d.%d: did not find a neighbor to forward to\n", rimeaddr_node_addr.u8[0], rimeaddr_node_addr.u8[1]);
return NULL;
}
static const struct multihop_callbacks multihop_call = {recv, forward};
static struct multihop_conn multihop;
PROCESS_THREAD(hello_world_process, ev, data)
{
PROCESS_EXITHANDLER(multihop_close(&multihop);)
PROCESS_BEGIN();
//initialise memory
memb_init(&neighbor_mem);
//initialise list
list_init(neighbor_table);
//open a multihop connection on Rime channel CHANNEL
multihop_open(&multihop, CHANNEL, &multihop_call);
//register an announcement with the ID of the rime channel
announcement_register(&example_announcement, CHANNEL, 0, received_announcement);
//active the button sensor, sends when pressed
SENSORS_ACTIVATE(button_sensor);
while(1) {
rimeaddr_t to;
PROCESS_WAIT_EVENT_UNTIL(ev == sensors_event && data == &button_sensor);
packetbuf_copyfrom("Hello", 6);
to.u8[0] = 1;
to.u8[1] = 0;
//send packet
multihop_send(&multihop, &to);
}
PROCESS_END();
}
/*---------------------------------------------------------------------------*/