Hello-world-james

From Glacsweb Wiki
Jump to: navigation, search
#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();
}
/*---------------------------------------------------------------------------*/