[projects WEAtHeR]

* updated project by adding routing functionality
dev/timer
Oliver Hahm 12 years ago
parent c0af1a8189
commit 364905f0d6

@ -1,5 +1,5 @@
SubDir TOP projects weather ;
SubDir TOP projects WEAtHeR ;
Module weather : main.c : sht11 ltc4150 swtimer auto_init ;
Module WEAtHeR : main.c weather_routing.c protocol_msg_gateway.c : sht11 ltc4150 cc110x gpioint swtimer shell shell_commands posix_io uart0 auto_init rtc ;
UseModule weather ;
UseModule WEAtHeR ;

@ -3,31 +3,200 @@
#include <board.h>
#include <swtimer.h>
#include <ltc4150.h>
#include <board_uart0.h>
#include <posix_io.h>
#include <msg.h>
#include <thread.h>
#include <board.h>
#include <shell.h>
#include <cc1100.h>
#include <rtc.h>
#include <lpc2387-rtc.h>
#include <time.h>
#include "weather_routing.h"
#include "weather_protocol.h"
#include "protocol_msg_gateway.h"
#define SHELL_STACK_SIZE (2048)
#define PH_STACK_SIZE (2048)
/* per default not acting as data sink */
static uint8_t data_sink = 0;
static uint8_t data_src = 0;
char shell_stack_buffer[SHELL_STACK_SIZE];
char ph_stack_buffer[PH_STACK_SIZE];
void weather_send(char* unused);
void weather_sink(char* unused);
shell_t shell;
const shell_command_t sc[] = {
{"sender", "Enables node as data source.", weather_send},
{"sink", "Enables node as data sink.", weather_sink},
{NULL, NULL, NULL}};
void shell_runner(void) {
shell_init(&shell, sc, uart0_readc, uart0_putc);
posix_open(uart0_handler_pid, 0);
shell_run(&shell);
}
void weather_send(char* unused) {
if (data_src) {
data_src = 0;
puts("Disabling data source mode.");
}
else {
data_src = 1;
puts("Enabling data source mode.");
}
}
void weather_sink(char* unused) {
if (data_sink) {
data_sink = 0;
puts("Disabling data sink mode.");
}
else {
data_sink = 1;
puts("Enabling data sink mode.");
}
}
int main(void)
{
static void handle_packet(void* msg, int msg_size, packet_info_t* packet_info) {
weather_packet_header_t *header = (weather_packet_header_t*) msg;
printf("\n\t Pkt received from phy: %u\n"
"\t -> SEQ: %u | TYPE: %u | SRC: %hu \n\n",
packet_info->phy_src,
header->seq_nr,
header->type,
header->src
);
/* when destination is set, but I'm not the receiver, pass to routing */
if (!data_sink) {
if (header->type == WEATHER_DATA) {
weather_data_pkt_t* wdp = (weather_data_pkt_t*) msg;
/* <node_id_source>;<node_id_sink>;<timestamp_source>;<timestamp_sink>;<temperature>;<humidity_relative>;<humitidy_absolut>;<energy_counter> */
printf("%hu;%hu;%04lX;%04X;%.2f;%.2f;%.2f;%.2f\n",
header->src,
0,
wdp->timestamp,
0,
wdp->temperature,
wdp->relhum,
wdp->relhum_temp,
wdp->energy);
}
puts("Not for me, routing, baby!");
route_packet(msg, msg_size);
return;
}
/* in all other cases handle the packet */
switch (header->type) {
case WEATHER_HELLO: {
if (msg_size < sizeof(weather_hello_pkt_t)) {
puts("Bad hello packet received.");
} else {
puts("Hello packet received - no handler implemented");
}
break;
}
case WEATHER_CHAT: {
puts("\n*================================================================================*");
printf("\tCHAT MESSAGE from %hu: %s\n\n", packet_info->phy_src, ((weather_chat_pkt_t*) msg)->mesg);
puts("*================================================================================*\n");
break;
}
case WEATHER_DATA: {
weather_data_pkt_t* wdp = (weather_data_pkt_t*) msg;
time_t local_time = rtc_time(NULL);
/* <node_id_source>;<node_id_sink>;<timestamp_source>;<timestamp_sink>;<temperature>;<humidity_relative>;<humitidy_absolut>;<energy_counter> */
printf("%hu;%u;%04lX;%04lX;%.2f;%.2f;%.2f;%.2f\n",
header->src,
1,
wdp->timestamp,
local_time,
wdp->temperature,
wdp->relhum,
wdp->relhum_temp,
wdp->energy);
break;
}
default: {
printf("Unknown packet type \"%i\" received.", header->type);
}
}
}
/* endless loop for packet handling */
static void protocol_handler_thread(void) {
msg_t m;
puts("Protocol handler thread started.");
while(1) {
msg_receive(&m);
packet_t packet;
int pos = m.content.value;
packet = packet_buffer[pos];
handle_packet(packet.payload, packet.msg_size, &(packet.packet_info));
}
}
int main(void) {
weather_data_pkt_t wdp;
sht11_val_t sht11_val;
double mAh = 0;
uint8_t success = 0;
wdp.header.seq_nr = 0;
wdp.header.type = WEATHER_DATA;
puts("");
puts("WEAtHeR: Wireless Energy-Aware mulTi-Hop sEnsor Reading.");
puts("Printing \"temperature in °C;relative humidity;temperature compensated relative humidity\".");
/* <node_id_source>;<node_id_sink>;<timestamp_source>;<timestamp_sink>;<temperature>;<humidity_relative>;<humitidy_absolut>;<energy_counter> */
puts("Printing \"node id of data source;node id of sink;timestamp of measurement;timestamp at data sink;temperature in °C;relative humidity;temperature compensated relative humidity;energy value\".");
puts("");
thread_create(shell_stack_buffer, SHELL_STACK_SIZE, PRIORITY_MAIN-1, CREATE_STACKTEST, shell_runner, "shell");
/* create thread for radio packet handling */
int pid = thread_create(ph_stack_buffer, PH_STACK_SIZE, PRIORITY_MAIN-5, CREATE_STACKTEST, protocol_handler_thread, "protocol_handler");
set_protocol_handler_thread(pid);
ltc4150_start();
rtc_enable();
while (1) {
success = sht11_read_sensor(&sht11_val, HUMIDITY|TEMPERATURE);
mAh = ltc4150_get_total_mAh();
if (!success) {
printf("error;error;error\n");
}
else {
printf("%.2f;%.2f;%.2f;%.2f\n", sht11_val.temperature, sht11_val.relhum, sht11_val.relhum_temp, mAh);
if (data_src) {
wdp.header.src = cc1100_get_address();
wdp.timestamp = rtc_time(NULL);
wdp.energy = ltc4150_get_total_mAh();
success = sht11_read_sensor(&sht11_val, HUMIDITY|TEMPERATURE);
if (!success) {
printf("error;error;error\n");
}
else {
wdp.temperature = sht11_val.temperature;
wdp.relhum = sht11_val.relhum;
wdp.relhum_temp = sht11_val.relhum_temp;
if (cc1100_send_csmaca(0, WEATHER_PROTOCOL_NR, 0, (char*)&wdp, sizeof(weather_data_pkt_t))) {
printf("Successfully sent packet: \n");
wdp.header.seq_nr++;
}
else {
puts("Error on sending packet!");
}
}
LED_RED_TOGGLE;
}
LED_RED_TOGGLE;
swtimer_usleep(60 * 1000*1000);
}
}

@ -0,0 +1,54 @@
#include <stdint.h>
#include <stdio.h>
#include <radio/radio.h>
#include <radio/types.h>
#include <string.h>
#include <msg.h>
#include <cc1100.h>
#include <board.h>
#include "protocol_msg_gateway.h"
#define NUM_PROTOCOL_HANDLER_PIDS 8
static uint16_t protocol_handler_pid;
static int packet_buffer_next = 0;
packet_t packet_buffer[PACKET_BUFFER_SIZE];
static void protocol_msg_gateway(void* payload, int msg_size, protocol_t protocol, packet_info_t* packet_info) {
msg_t m;
// if ((((int16_t) packet_info->phy_src) > (((int16_t) cc1100_get_address()) + 10)) || (((int16_t) packet_info->phy_src) < (((int16_t) cc1100_get_address()) - 10))) {
// return;
// }
if (protocol_handler_pid <= 0) {
puts("protocol_handler(): received packet without protocol handler. msg dropped.");
return;
}
int mypos = packet_buffer_next++;
if (packet_buffer_next == PACKET_BUFFER_SIZE) packet_buffer_next = 0;
packet_t *p = &(packet_buffer[mypos]);
p->packet_info = *packet_info;
p->msg_size = msg_size;
memcpy(p->payload, payload, msg_size);
m.type = 0;
m.content.value = mypos;
int success = msg_send_int(&m, protocol_handler_pid);
if (! success) {
/* should set timer to retry. Dropping pkt for now. */
puts("protocol_handler(): msg dropped.");
}
}
void init_protocol_msg_gateway() {
cc1100_set_packet_monitor(protocol_msg_gateway);
}
int set_protocol_handler_thread(int pid) {
protocol_handler_pid = pid;
return 0;
}

@ -0,0 +1,18 @@
#ifndef __PROTOCOL_MSG_GATEWAY_H
#define __PROTOCOL_MSG_GATEWAY_H
#define PACKET_BUFFER_SIZE 32
#define MAXIMUM_PAYLOAD_SIZE 64
typedef struct {
packet_info_t packet_info;
unsigned int msg_size;
char payload[MAXIMUM_PAYLOAD_SIZE];
} packet_t;
void init_protocol_msg_gateway();
int set_protocol_handler_thread(int pid);
extern packet_t packet_buffer[PACKET_BUFFER_SIZE];
#endif /* __PROTOCOL_MSG_GATEWAY_H */

@ -0,0 +1,41 @@
#ifndef WEATHER_PROTOCOL_H_
#define WEATHER_PROTOCOL_H_
#include <stdint.h>
#include <radio/radio.h>
#define WEATHER_PROTOCOL_NR 6
typedef enum {
WEATHER_HELLO,
WEATHER_CHAT,
WEATHER_DATA
} packet_types;
typedef struct {
uint16_t seq_nr;
uint8_t src;
uint8_t type;
uint8_t resevered;
} weather_packet_header_t;
typedef struct __attribute__ ((packed)) {
weather_packet_header_t header;
} weather_hello_pkt_t;
typedef struct {
weather_packet_header_t header;
uint8_t len;
char mesg[40];
} weather_chat_pkt_t;
typedef struct {
weather_packet_header_t header;
time_t timestamp;
double temperature;
double relhum;
double relhum_temp;
double energy;
} weather_data_pkt_t;
#endif

@ -0,0 +1,60 @@
#include <stdlib.h>
#include <stdio.h>
#include <cc1100.h>
#include <time.h>
#include "weather_protocol.h"
#include "weather_routing.h"
static source_timestamp_t sources[MAX_SOURCES];
static uint8_t update_sources(uint8_t id, time_t timestamp) {
uint8_t i;
for (i = 0; i < MAX_SOURCES; i++) {
/* source id found */
if (sources[i].id == id) {
/* more current timestamp received, updating */
if (sources[i].timestamp < timestamp) {
sources[i].timestamp = timestamp;
return 1;
}
/* older, but still valid timestamp, not updating */
else if (sources[i].timestamp < timestamp + MAX_INTERVAL) {
return 1;
}
/* timestamp too old, discard this packet */
else {
puts("Timestamp too old, not routing");
return 0;
}
}
/* source id not yet stored creating new entry */
else if (!sources[i].id) {
sources[i].id = id;
sources[i].timestamp = timestamp;
return 1;
}
}
puts("No more sources could be stored!");
return 0;
}
void route_packet(void* msg, int msg_size) {
weather_packet_header_t *header = (weather_packet_header_t*) msg;
if (header->type == WEATHER_DATA) {
weather_data_pkt_t* wdp = (weather_data_pkt_t*) msg;
if (!update_sources(wdp->header.src, wdp->timestamp)) {
return;
}
}
if ((100.0 * rand()/(double) RAND_MAX) <= FLOODING_PROB) {
printf("Broadcasting packet...");
if (cc1100_send_csmaca(0, WEATHER_PROTOCOL_NR, 0, (char*)msg, msg_size)) {
puts("successful!");
}
else {
puts("failed!");
}
}
}

@ -0,0 +1,17 @@
#ifndef WEATHER_ROUTING_H
#define WEATHER_ROUTING_H
#include <time.h>
#define FLOODING_PROB (100)
#define MAX_SOURCES (10)
#define MAX_INTERVAL (5 * 60)
typedef struct {
uint8_t id;
time_t timestamp;
} source_timestamp_t;
void route_packet(void* msg, int msg_size);
#endif /* WEATHER_ROUTING_H */
Loading…
Cancel
Save