Commit 2f4819b4 authored by Robert Hartung's avatar Robert Hartung
Browse files

Adds current version

parent 9db63059
......@@ -2,7 +2,6 @@ APPLICATION=software
BOARD ?= inga_blue
RIOTBASE ?= $(CURDIR)/../../RIOT/
DEVELHELP ?= 1
USEMODULE += shell
USEMODULE += shell_commands
USEMODULE += ps
......@@ -16,5 +15,10 @@ USEMODULE += auto_init_gnrc_netif
NODE_ID ?= 0
CFLAGS += -DNODE_ID=$(NODE_ID)
CFLAGS += -DDEBUG_ASSERT_VERBOSE
CFLAGS += -DGNRC_PKTBUF_SIZE=512
CFLAGS += -DSHELL_NO_ECHO -DSHELL_NO_PROMPT
#DEVELHELP ?= 1
CFLAGS += -DNDEBUG
include $(RIOTBASE)/Makefile.include
from time import sleep
import re
from clients.client import Client
from common.logging import Logger
from sqlalchemy import Column, Integer, String, Float
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.orm import sessionmaker
from sqlalchemy import create_engine
DATABASE = 'sqlite.db'
NODES = ['serial-AE00EI9M', 'serial-ATML2127031800008867', 'serial-A502C3ZD']
CHANNELS = [11, 15, 26]
logger = Logger(__file__)
Base = declarative_base()
class TX(Base):
__tablename__ = 'tx'
serial_id = Column(String(250), nullable=False, primary_key=True)
ts = Column(Float, nullable=False, primary_key=True)
seq_nr = Column(Integer, nullable=False)
class RX(Base):
__tablename__ = 'rx'
serial_id = Column(String(250), nullable=False, primary_key=True)
ts = Column(Float, nullable=False, primary_key=True)
rssi = Column(Integer, nullable=False)
lqi = Column(Integer, nullable=False)
node_id = Column(Integer, nullable=False)
seq_nr = Column(Integer, nullable=False)
class Corrupt(Base):
__tablename__ = 'corrupt'
serial_id = Column(String(250), nullable=False, primary_key=True)
ts = Column(Float, nullable=False, primary_key=True)
rssi = Column(Integer, nullable=False)
lqi = Column(Integer, nullable=False)
payload = Column(String(255), nullable=False)
engine = create_engine('sqlite:///test.db')
Session = sessionmaker(bind=engine)
Base.metadata.create_all(engine)
re_tx = re.compile("^>(?P<seq_nr>[0-9]+)=(?P<checksum>[A-Fa-f0-9]+)$")
re_rx = re.compile("^<(?P<node_id>[0-9]+)\|(?P<seq_nr>[0-9]+)\|(?P<rssi>\-?[0-9]+)\|(?P<lqi>[0-9]+)=(?P<checksum>[A-Fa-f0-9]+)$")
# <-94|52|0|=A5
re_rx_corrupt = re.compile("^<(?P<rssi>-?[0-9]+)\|(?P<lqi>[0-9]+)\|(?P<length>[0-9]+)\|(?P<payload>(?: [A-Fa-f0-9]+)*)=(?P<checksum>[A-Fa-f0-9]+)$")
re_ifconfig = re.compile("^success: set (.*?) o(n|f) interface [0-9]+ to (.*?)$")
def calculate_checksum(*args):
s = 0
for a in args:
s += sum(bytes(a, 'utf-8'))
return hex( s&0xFF )[2:].upper().zfill(2)
def handle_serial_rx(d):
src_id = d['src']['id'][0]
ts = d['ts']
line = d['line'].strip()
match_ifconfig = re_ifconfig.match(line)
if match_ifconfig is not None:
return True
match_tx = re_tx.match(line)
if match_tx is not None:
seq_nr = match_tx.group("seq_nr")
checksum = match_tx.group("checksum")
expected_checksum = calculate_checksum( seq_nr )
if expected_checksum == checksum:
session = Session()
session.add(TX(serial_id = src_id, ts=ts, seq_nr = seq_nr ))
session.commit()
#logger.log("[{}] TX: #{}".format( src_id, seq_nr ))
return True
else:
logger.debug("Corrupt Line")
return False
match_rx = re_rx.match(line)
if match_rx is not None:
node_id = match_rx.group("node_id")
seq_nr = match_rx.group("seq_nr")
rssi = match_rx.group('rssi')
lqi = match_rx.group('lqi')
checksum = match_rx.group("checksum")
expected_checksum = calculate_checksum( node_id, '|', seq_nr, '|', rssi, '|', lqi )
if expected_checksum == checksum:
session = Session()
session.add(RX(serial_id = src_id, ts=ts, seq_nr = seq_nr, node_id = node_id, rssi = rssi, lqi = lqi))
session.commit()
#logger.log("[{}] RX: #{} from {}".format( src_id, node_id, seq_nr ))
return True
else:
logger.debug("Corrupt Line {} != {}".format( expected_checksum, checksum) )
return False
return True
match_rx_corrupt = re_rx_corrupt.match(line)
if match_rx_corrupt is not None:
rssi = match_rx_corrupt.group('rssi')
lqi = match_rx_corrupt.group('lqi')
payload = match_rx_corrupt.group('payload').strip()
logger.debug( "Corrupt: {}dBm, {}, {}".format( rssi, lqi, payload ) )
session = Session()
session.add(Corrupt(serial_id = src_id, ts=ts, rssi = rssi, lqi = lqi, payload = payload))
session.commit()
return True
return False
class PRREvalClient(Client):
def __init__(self, args = None):
super(PRREvalClient, self).__init__(args, logging = True)
def eval(self):
for channel in [11, 15, 26]:
logger.log( "CHANNEL={} ".format(channel) )
self.set_channel( channel )
sleep(0.25)
for power in [-17, -7, 0, 3]:
logger.log( "POWER={} ".format(power) )
self.set_txpower( power )
sleep( 0.5 )
for payload in ['short', 'miiiiiiiiiiiiiiiiidle', 'loooooooooooooooooooooooooooooooooooooooong']:
logger.log( "PAYLOAD={} ".format(payload) )
self.send_all( "payload {}\n".format( payload ) )
sleep( 0.5 )
for sender in NODES:
self.send({'dst': {'id': sender}, 'type': 'serial_tx', 'line': 'tx 5 200000\n'})
# 5 packets, 200ms -> 1 second
sleep( 1.5 )
def run(self):
while True:
try:
self.eval()
except KeyboardInterrupt:
logger.success("Stopped")
break
def set_channel(self, channel):
self.send_all("ifconfig 3 set state idle\n")
self.send_all("ifconfig 3 set channel {}\n".format( channel ))
def set_txpower(self, power):
self.send_all("ifconfig 3 set power {}\n".format( power ))
def send_all(self, line):
self.send({'dst': {'id': NODES}, 'type': 'serial_tx', 'line': line})
def callback_receive(self, data_dict):
if 'type' in data_dict:
if data_dict['type'] == 'serial_rx':
if handle_serial_rx( data_dict ):
return True
logger.debug( data_dict )
if __name__ == '__main__':
client = PRREvalClient()
client.run()
\ No newline at end of file
......@@ -36,27 +36,77 @@
#define SEND_INTERVAL (1)
#define RCV_QUEUE_SIZE (4)
#define MAX_PAYLOAD_LENGTH (128)
#define MAX_PAYLOAD_LENGTH (64)
#define MAGIC_STRING "IBREVAL\0"
#ifndef NODE_ID
#error NODE_ID undefined
#endif
/// 512 required for samr21-xpro, 256 sufficuent for INGA and telosb
char dump_thread_stack[512];
char send_thread_stack[512];
/// 512 required for samr21-xpro, 256 sufficient for INGA and telosb
char dump_thread_stack[1024+255];
char send_thread_stack[1024+255];
static msg_t dump_thread_msg_queue[RCV_QUEUE_SIZE];
static msg_t send_thread_msg_queue[RCV_QUEUE_SIZE];
typedef struct {
typedef struct /*__attribute__((packed))*/ {
char magic_string[8];
uint8_t node_id;
uint16_t seq_nr;
uint8_t seq_nr;
uint8_t temp;
uint8_t payload_length;
uint8_t payload[MAX_PAYLOAD_LENGTH];
} eval_message_t;
eval_message_t eval_message = { .node_id = NODE_ID, .magic_string = MAGIC_STRING };
static eval_message_t eval_message = { .node_id = NODE_ID, .payload_length = 5, .payload = "Hello\0", .magic_string = MAGIC_STRING, .seq_nr = 0 };
kernel_pid_t send_thread_pid = 0;
/**
* Sends a packet via the network interface
*
* tx [count [delay]]
* - count: Number of packets to send
* - delay: Delay in µS between the packets
*/
int shell_tx(int argc, char** argv) {
(void)argc;
(void)argv;
uint8_t count = 1;
uint32_t delay = 100000; // 100000us = 100ms
if(argc > 1) {
count = atoi(argv[1]);
}
if(argc > 2) {
delay = (uint32_t)atol(argv[2]);
}
msg_t msg;
msg.type = 1337;
msg.content.value = 0;
//printf("Sending %u packets every %luus\n", count, delay);
while(count-- > 0) {
msg_send(&msg, send_thread_pid);
xtimer_usleep( delay );
}
return 0;
}
int shell_payload(int argc, char** argv) {
/// argv[0] is the function name
if(argc == 1) {
printf("Payload is: '%s'\n", eval_message.payload);
} else {
strcpy((char*)eval_message.payload, argv[1]);
eval_message.payload_length = strlen(argv[1]);
}
return 0;
}
shell_command_t eval_shell_commands[] = {
{"tx", "Sends packets", shell_tx},
{"payload", "Sets or prints the payload", shell_payload},
{NULL, NULL, NULL}
};
static void _dump(gnrc_pktsnip_t *pkt) {
gnrc_pktsnip_t *snip = pkt;
......@@ -65,6 +115,7 @@ static void _dump(gnrc_pktsnip_t *pkt) {
eval_message_t *packet;
gnrc_netif_hdr_t *hdr;
uint8_t len;
char serialbuffer[255];
// printf("_dump: %d %d\n", gnrc_netreg_num(GNRC_NETTYPE_UNDEF, 0), gnrc_netreg_num(GNRC_NETTYPE_NETIF, 0));
while(snip != NULL) {
switch(snip->type) {
......@@ -73,19 +124,51 @@ static void _dump(gnrc_pktsnip_t *pkt) {
break;
case GNRC_NETTYPE_NETIF :
hdr = snip->data;
printf("HDR: %d %d %d\n", hdr->rssi, hdr->lqi, hdr->crc_valid);
//printf("HDR: %d %d %d\n", hdr->rssi, hdr->lqi, hdr->crc_valid);
//puts("OK");
packet = (eval_message_t*)payload->data;
if(hdr->crc_valid && strcmp(packet->magic_string, MAGIC_STRING) == 0) {
printf("PACKET: #%d from %d\n", packet->seq_nr, packet->node_id);
if(hdr->crc_valid) {
if(strcmp(packet->magic_string, MAGIC_STRING) == 0) {
int length = sprintf(serialbuffer, "%u|%u|%d|%u", packet->node_id, packet->seq_nr, hdr->rssi, hdr->lqi);
uint8_t sum = 0;
for(uint8_t i=0; i<length; i++) {
sum += serialbuffer[i];
}
printf("<%s=%02X\n", serialbuffer, sum);
} else {
/// This is another packet, ignore it!
}
} else {
/* Make sure a corrupt packet does not exceed payload size */
len = payload->size;
if(len > 100) {
len = 100;
if(len > sizeof(eval_message_t)) {
len = sizeof(eval_message_t);
}
/* Pointer to data */
data = (uint8_t*)payload->data;
uint8_t i,
sum = 0,
length = 0;
length += snprintf(&serialbuffer[0], sizeof(serialbuffer) - length, "%d|%u|%d|", hdr->rssi, hdr->lqi, len);
/* Print each single byte */
for(i=0; i<len; i++) {
/// Even though " %02X" is only three characters long, we need to pass 4 because of the null terminator for the string!
length += snprintf(&serialbuffer[length], sizeof(serialbuffer) - length, " %02X", data[i]);
}
for(i=0; i<length; i++) {
sum += serialbuffer[i];
}
/*
[SAMR21] line received: '> <40| 09 12 FC FF 00 00 0A C6 B9 3A 97 03 00 6F 0D 00 28 43 74 50 04 B9 3A 97 03 00 6F 0D 00 00 C3 D7 EE 15 FE 3E 07 D5 2B E3=64'
[SAMR21] line received: '<40| 09 12 FC FF 00 00 09 C6 B9 3A 97 03 00 6F 0D 00 28 EF D8 9A 02 58 C6 97 03 00 6F 0D 00 00 D4 14 0C C8 49 65 34 7D DE 8F=77'
[SAMR21] line received: '<40| 09 12 FC '
[SAMR21] line received: 'Context before hardfault:'
*/
printf("<%s=%02X\n", serialbuffer, sum);
/*
printf("Contents(%02d):", len);
for(uint8_t i=0; i<len; i++) {
printf(" %02X", data[i]);
......@@ -99,8 +182,8 @@ static void _dump(gnrc_pktsnip_t *pkt) {
}
}
puts("");
*/
}
break;
default :
printf("snip of type %d\n", snip->type);
......@@ -194,16 +277,39 @@ void *send_thread(void *arg)
if(ret < 0) {
puts("Unable to set CSMA retries = 0");
}
uint8_t flags = 0 | GNRC_NETIF_HDR_FLAGS_BROADCAST;
uint8_t payload_length = sprintf((char*)eval_message.payload, "Hello from %2d", NODE_ID);
eval_message.payload_length = snprintf((char*)eval_message.payload, MAX_PAYLOAD_LENGTH, "Hello from %2d", NODE_ID);
msg_init_queue(send_thread_msg_queue, RCV_QUEUE_SIZE);
msg_t msg;
char serialbuffer[255];
while(1) {
msg_receive(&msg);
(void)msg;
/*
//printf("[dump_thread] message received: %d\n", msg.type);
switch(msg.type) {
case GNRC_NETAPI_MSG_TYPE_RCV :
_dump( msg.content.ptr );
break;
default :
puts("ERROR: Unknown message type???");
/// gnrc_pktbuf_release( msg.content.ptr );
break;
}
xtimer_sleep(SEND_INTERVAL);
printf("send... ");
*/
eval_message.seq_nr++;
pkt = gnrc_pktbuf_add(NULL, &eval_message, sizeof(eval_message) - MAX_PAYLOAD_LENGTH + payload_length, GNRC_NETTYPE_UNDEF);
//printf("send... %d", sizeof(eval_message) - MAX_PAYLOAD_LENGTH + payload_length);
//printf("send...");
/* Prepare packet */
eval_message.seq_nr += 1;
pkt = gnrc_pktbuf_add(NULL, &eval_message, sizeof(eval_message) - MAX_PAYLOAD_LENGTH + eval_message.payload_length, GNRC_NETTYPE_UNDEF);
if (pkt == NULL) {
puts("ERROR: packet buffer full");
return NULL;
......@@ -223,7 +329,12 @@ void *send_thread(void *arg)
printf("ERROR: unable to send: %d\n", ret);
gnrc_pktbuf_release(pkt);
} else {
puts("OK");
uint8_t sum = 0;
uint8_t length = snprintf(serialbuffer, 255, "%u", eval_message.seq_nr);
for(uint8_t i=0; i<length; i++) {
sum += serialbuffer[i];
}
printf(">%s=%02X\n", serialbuffer, sum);
}
}
return NULL;
......@@ -232,14 +343,14 @@ void *send_thread(void *arg)
int main(void)
{
/// +1 -> INGA working, but TelosB/Sky not
thread_create(dump_thread_stack, sizeof(dump_thread_stack), THREAD_PRIORITY_MAIN + 2, 0, dump_thread, NULL, "dump_thread");
thread_create(dump_thread_stack, sizeof(dump_thread_stack), THREAD_PRIORITY_MAIN + 1, 0, dump_thread, NULL, "dump_thread");
gnrc_netif_t *netif = NULL;
if((netif = gnrc_netif_iter(netif))) {
gnrc_netif_t *ieee802154_netif = netif;
printf("Found gnrc netif: %d %d", netif->pid, ieee802154_netif->pid);
/// +2 -> INGA working, but TelosB/Sky not
thread_create(send_thread_stack, sizeof(send_thread_stack), THREAD_PRIORITY_MAIN + 1, 0, send_thread, ieee802154_netif, "send_thread");
send_thread_pid = thread_create(send_thread_stack, sizeof(send_thread_stack), THREAD_PRIORITY_MAIN + 2, 0, send_thread, ieee802154_netif, "send_thread");
}
else {
puts("Unable to find netif");
......@@ -248,7 +359,7 @@ int main(void)
(void) puts("Welcome to RIOT!");
printf("This is node %d\n", NODE_ID);
char line_buf[SHELL_DEFAULT_BUFSIZE];
shell_run(NULL, line_buf, SHELL_DEFAULT_BUFSIZE);
shell_run(eval_shell_commands, line_buf, SHELL_DEFAULT_BUFSIZE);
return 0;
}
}
\ No newline at end of file
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment