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(); } /*---------------------------------------------------------------------------*/