From a38a5a98749c9a435707a9871f25aa6afc00334d Mon Sep 17 00:00:00 2001 From: Stefan `Sec` Zehl Date: Fri, 27 Jan 2012 01:44:10 +0100 Subject: [PATCH 01/19] Simple curses-based mesh display --- tools/mesh/meshtrace.pl | 60 +++++++++++++++ tools/mesh/r0ket.pm | 167 ++++++++++++++++++++++++++++++++++++++++ 2 files changed, 227 insertions(+) create mode 100755 tools/mesh/meshtrace.pl create mode 100755 tools/mesh/r0ket.pm diff --git a/tools/mesh/meshtrace.pl b/tools/mesh/meshtrace.pl new file mode 100755 index 0000000..6dbd2d1 --- /dev/null +++ b/tools/mesh/meshtrace.pl @@ -0,0 +1,60 @@ +#!/usr/bin/perl +# +# vim:set ts=4 sw=4: + +use strict; +use Curses; +use POSIX qw(strftime); + +use lib '.'; +use r0ket; + +$|=1; + +my $ser=""; + +do {$ser=$_ if ( -e $_ ) } for qw(/dev/ttyS3 /dev/ttyACM0); + +if ($ARGV[0] eq "-s"){ + shift; + $ser=shift; +}; + +open(SER, "+<",$ser) || die "open serial: $!"; + +r0ket::readbeacon(); + +my $str; +my %bdata; + +initscr; +END{endwin;} +use constant WIDTH => 80; +use constant m_height => 15; +my $win_top=subwin(2,WIDTH,0,0); +my $win=subwin(m_height,WIDTH,2,0); +noecho; +curs_set(0); +$win_top->addstr(0,0,"r0ket Mesh-Trace 0.1"); +$win_top->addstr(1,0,"-"x20); +$win_top->refresh; + +my $beaconctr=0; +while(1){ + $str=r0ket::get_packet(\*SER); + my $p=r0ket::pkt_beauty($str); + if(!$bdata{$p->{beacon}}){ + $bdata{$p->{beacon}}=++$beaconctr; + }; + $win->addstr($bdata{$p->{beacon}},0, + sprintf "%s | g=%d rel=%s time=%s =%+4d | %s", + $p->{beacon}, + $p->{generation}, + $p->{release}, + strftime("%Y-%m-%d %H:%M:%S",gmtime $p->{time}), + $p->{time}-(time+3600), + r0ket::getbeacon($p->{beacon}) + ); + $win->refresh; +}; +r0ket::rest(); diff --git a/tools/mesh/r0ket.pm b/tools/mesh/r0ket.pm new file mode 100755 index 0000000..1161690 --- /dev/null +++ b/tools/mesh/r0ket.pm @@ -0,0 +1,167 @@ +#!/usr/bin/perl +# +# vim:set ts=4 sw=4: + +use strict; + +use IO::Select; +package r0ket; + +use Digest::CRC qw(crcccitt); +use POSIX qw(strftime); + + +### Utility +sub sprint{ + return join("",map { + if (ord($_)>30 && ord($_)<127){ + $_; + }else{ + "[x".unpack("H*",$_)."]"; + } + }split(//,shift)); +}; + +### Nickname/beacon helper functions +our %beacon; +sub readbeacon{ + return if( ! -f "BEACON" ); + open(B,"<","BEACON") || die "open: $!"; + while(){ + /(\w+)\s+(.*)/ && do { + $beacon{$1}=$2; + }; + }; + close(B); +}; +sub getbeacon{ + my $b=shift; + if(!$beacon{$b}){ + return ""; + }else{ + return $beacon{$b}; + }; +}; +sub resolvebeacon{ + my $b=shift; + if(!$beacon{$b}){ + return $b; + }else{ + return "$b ($beacon{$b})"; + }; +}; +sub addbeacon{ + my($b,$n)=@_; + if(!$beacon{$b}){ + $beacon{$b}=$n; + }; +}; +sub writebeacon{ + open(B,">","BEACON") || die "write: $!"; + for(sort keys %beacon){ + print B "$_ $beacon{$_}\n"; + }; + close(B); +}; + +### Packet mgmt + +our $buffer; +sub get_packet{ + my $dev=shift; + + sub _get_bytes{ + my $rr; + sysread($dev,$rr,1024); + if(length($rr)<=1){ + select(undef,undef,undef,0.1); + }; + $buffer.=$rr; + }; + + my $cnt=0; + while(++$cnt<10){ + if(length($buffer)<2){ + _get_bytes(); + }elsif($buffer !~ /^\\[12]/){ + $buffer=~s/^(.[^\\]*)//s; +# print STDERR "Unparseable stuff: <",sprint($1),">\n"; + }elsif ($buffer =~ s/^\\([12])(.*?)\\0//s){ + my $str=$2; + $str=~s/\\\\/\\/g; # dequote + return $str; + }else{ + _get_bytes(); + }; + }; + die "No packets for >1sec?\n"; +}; + +sub rest{ + if(length($buffer)>0){ + print "rest: <", sprint($buffer), ">\n"; + }; +}; + +### Pkt beautify +sub nice_mesh{ + my $pkt=shift; + my $out; + my $type=substr($pkt,0,1); +# next if(defined $arg && $arg ne $i); + $out->{type}=$type; + $out->{string}="[$type]"; + $out->{generation}=unpack("C",substr($pkt,1,1)); + $out->{string}.= " g=".$out->{generation}; + if($type eq "T"){ + $out->{time}= unpack("N",substr($pkt,2,4)); + $out->{release}=unpack("H*",substr($pkt,24,2)); + $out->{beacon}= unpack("H*",substr($pkt,26,4)); + + $out->{string}.=sprintf " t=%s (%+4d) rel=%s beacon=%s", + strftime("%Y-%m-%d %H:%M:%S",gmtime $out->{time}), + $out->{time}-(time+3600), + $out->{release}, + resolvebeacon($out->{beacon}); + }elsif($type eq "i"){ + $out->{score}=unpack("N",substr($pkt,2,4)); + $out->{nick}= unpack("Z*",substr($pkt,6,length($pkt)-8)); + + $out->{string}.=sprintf " score=%d nick=%s", + $out->{score}, + $out->{nick}; + }elsif($type eq "B"){ + $out->{time}=unpack("N",substr($pkt,2,4)); + $out->{id}= unpack("c",substr($pkt,6,1)); + $out->{hop}= unpack("n",substr($pkt,11,4)); + + $out->{string}.=sprintf " t=%d id=%s hop=%3d", + $out->{time}, + $out->{id}, + $out->{hop}; + }else{ + $out->{string}.= " "; + }; + return $out; +}; + +sub pkt_beauty{ + my $pkt=shift; + my $out; + + $out=nice_mesh($pkt); + + my $pkt_crc= unpack("n",substr($pkt,length($pkt)-2,2)); + my $calc_crc= crcccitt(substr($pkt,0,length($pkt)-2)); + + if ($pkt_crc eq $calc_crc){ + $out->{crc}="ok"; + }else{ + $out->{crc}="fail"; + $out->{string}.= " CRCFAIL"; + }; + return $out; +} + + +1; From df42d159ed629d64734420adccb37068a81e6400 Mon Sep 17 00:00:00 2001 From: Stefan `Sec` Zehl Date: Fri, 27 Jan 2012 02:02:51 +0100 Subject: [PATCH 02/19] Add simple beacon tracer. --- tools/mesh/beacontrace.pl | 64 +++++++++++++++++++++++++++++++++++++++ tools/mesh/r0ket.pm | 39 ++++++++++++++++++++++++ 2 files changed, 103 insertions(+) create mode 100755 tools/mesh/beacontrace.pl diff --git a/tools/mesh/beacontrace.pl b/tools/mesh/beacontrace.pl new file mode 100755 index 0000000..c23fd8a --- /dev/null +++ b/tools/mesh/beacontrace.pl @@ -0,0 +1,64 @@ +#!/usr/bin/perl +# +# vim:set ts=4 sw=4: + +use strict; +use Curses; +use POSIX qw(strftime); + +use lib '.'; +use r0ket; + +$|=1; + +my $ser=""; + +do {$ser=$_ if ( -e $_ ) } for qw(/dev/ttyS3 /dev/ttyACM0); + +if ($ARGV[0] eq "-s"){ + shift; + $ser=shift; +}; + +open(SER, "+<",$ser) || die "open serial: $!"; + +#r0ket::readbeacon(); + +my $str; +my %bdata; + +initscr; +END{endwin;} +use constant WIDTH => 80; +use constant m_height => 15; +my $win_top=subwin(2,WIDTH,0,0); +my $win=subwin(m_height,WIDTH,2,0); +noecho; +curs_set(0); +$win_top->addstr(0,0,"r0ket Beacon-Trace 0.1"); +$win_top->addstr(1,0,"-"x20); +$win_top->refresh; + +my $beaconctr=0; +while(1){ + $str=r0ket::get_packet(\*SER); + my $p=r0ket::nice_beacon($str); + if(!$bdata{$p->{beacon}}){ + $bdata{$p->{beacon}}=++$beaconctr; + }; + if($p->{type} eq "beacon"){ + $win->addstr($bdata{$p->{beacon}},0, + sprintf "%s | bt=%s str=%s idx=%8s | %s", + $p->{beacon}, + $p->{button}, + $p->{strength}, + $p->{idx}, + r0ket::getbeacon($p->{beacon}) + ); + }else{ + $win->addstr($bdata{$p->{beacon}},40,$p->{nick}); + }; + + $win->refresh; +}; +r0ket::rest(); diff --git a/tools/mesh/r0ket.pm b/tools/mesh/r0ket.pm index 1161690..26a94cc 100755 --- a/tools/mesh/r0ket.pm +++ b/tools/mesh/r0ket.pm @@ -145,6 +145,45 @@ sub nice_mesh{ return $out; }; +sub nice_beacon{ + my $pkt=shift; + my $out; + my $type=substr($pkt,1,1); + $out->{type}=$type; + + if($type eq "\x17"){ + $out->{type}= "beacon"; + $out->{length}= unpack("C", substr($pkt,0,1)); + $out->{button}= unpack("H*",substr($pkt,2,1)); + $out->{strength}=unpack("H*",substr($pkt,3,1)); + $out->{idx}= unpack("N", substr($pkt,4,4)); + $out->{beacon}= unpack("H*",substr($pkt,8,4)); + $out->{unused}= unpack("H*",substr($pkt,12,2)); + + $out->{string}=sprintf "BEACON ln=%d bt=%s str=%s idx=%08x beacon=%s", + $out->{length}, + $out->{button}, + $out->{strength}, + $out->{idx}, + $out->{beacon}; + if(unpack("H*",substr($pkt,12,2)) ne "ffff"){ + print "unused=",unpack("H*",substr($pkt,12,2))," "; + }; + }elsif($type eq "\x23"){ + $out->{type}= "nick"; + $out->{beacon}= unpack("H*",substr($pkt,2,4)); + $out->{nick}= unpack("Z*",substr($pkt,6,length($pkt)-2)); + + $out->{string}=sprintf "NICK beacon=%s nick=%s", + $out->{beacon}, + $out->{nick}; + }else{ + $out->{string}=""; + }; + return $out; +}; + + sub pkt_beauty{ my $pkt=shift; my $out; From 2c8ec43a1e5b8fb39a0bca76960e589b96605a07 Mon Sep 17 00:00:00 2001 From: Stefan `Sec` Zehl Date: Fri, 27 Jan 2012 22:25:30 +0100 Subject: [PATCH 03/19] Make change to memmove for l0dables complete. --- firmware/l0dable/EXPORTS | 2 +- firmware/l0dable/system-include-hack.h | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/firmware/l0dable/EXPORTS b/firmware/l0dable/EXPORTS index 1a3d7d5..13d3d3a 100644 --- a/firmware/l0dable/EXPORTS +++ b/firmware/l0dable/EXPORTS @@ -83,7 +83,7 @@ meshnice #external strcpy strlen -memcpy +memmove memset #stuff GetLight diff --git a/firmware/l0dable/system-include-hack.h b/firmware/l0dable/system-include-hack.h index 29ea22f..89a80dd 100644 --- a/firmware/l0dable/system-include-hack.h +++ b/firmware/l0dable/system-include-hack.h @@ -1,5 +1,5 @@ size_t strlen(const char *s); -char strcpy(char * restrict dst, const char * restrict src); -void memcpy(void *dst, const void *src, size_t len); -void memset(void *s, int c, size_t n); +char* strcpy(char * restrict dst, const char * restrict src); +void* memmove(void *dst, const void *src, size_t len); +void* memset(void *s, int c, size_t n); int getrelease(); From e8eb8402d0745c6f3f62754182e1d0ce86212384 Mon Sep 17 00:00:00 2001 From: Stefan `Sec` Zehl Date: Fri, 27 Jan 2012 22:33:44 +0100 Subject: [PATCH 04/19] Sanitize linking for main firmware, too. --- firmware/Makefile | 6 +++--- firmware/Makefile.inc | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/firmware/Makefile b/firmware/Makefile index 44f6a76..5cf7513 100644 --- a/firmware/Makefile +++ b/firmware/Makefile @@ -37,13 +37,13 @@ ifdef APP OUTFILE=$(APP) endif -LDFLAGS+= -Wl,--gc-sections +LDFLAGS+= --gc-sections OBJS += lpc1xxx/$(TARGET)_handlers.o lpc1xxx/LPC1xxx_startup.o ########################################################################## # Startup files ########################################################################## -LDLIBS = -lm +LDLIBS = LDLIBS += -Lapplications -lapp LDLIBS += -Lfunk -lfunk LDLIBS += -Lusbcdc -lusbcdc @@ -111,7 +111,7 @@ $(LD_TEMP): -@echo "INCLUDE $(LD_SCRIPT)" >> $(LD_TEMP) $(OUTFILE).elf: $(OBJS) $(SYS_OBJS) $(SUBDIRS) $(LPCFIX) $(LD_TEMP) - $(CC) $(LDFLAGS) -T $(LD_TEMP) -o $(OUTFILE).elf $(OBJS) $(LDLIBS) + $(LD) $(LDFLAGS) -T $(LD_TEMP) -o $(OUTFILE).elf $(OBJS) $(LDLIBS) -@echo "" $(SIZE) $(OUTFILE).elf -@echo "" diff --git a/firmware/Makefile.inc b/firmware/Makefile.inc index 3cf227d..dda77a0 100644 --- a/firmware/Makefile.inc +++ b/firmware/Makefile.inc @@ -42,7 +42,7 @@ CPU_TYPE = cortex-$(CORTEX_TYPE) # Compiler settings, parameters and flags ########################################################################## -CFLAGS = -std=c99 -c -g -Os $(INCLUDE_PATHS) -Wall -mthumb -ffunction-sections -fdata-sections -fmessage-length=0 -mcpu=$(CPU_TYPE) -DTARGET=$(TARGET) -DRAMCODE=$(RAMCODE) -fno-builtin -Wno-unused-function +CFLAGS = -std=c99 -c -g -Os $(INCLUDE_PATHS) -Wall -mthumb -ffunction-sections -fdata-sections -fmessage-length=0 -mcpu=$(CPU_TYPE) -DTARGET=$(TARGET) -DRAMCODE=$(RAMCODE) -fno-builtin -Wno-unused-function -ffreestanding LDFLAGS = -nostartfiles ifeq "$(USBSERIAL)" "YES" From 163429f0357a53100700b4297b7b6239641f3a9e Mon Sep 17 00:00:00 2001 From: Stefan `Sec` Zehl Date: Fri, 27 Jan 2012 22:42:56 +0100 Subject: [PATCH 05/19] Make memcpy smaller. We don't need the speed :) --- firmware/core/libc/string.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/firmware/core/libc/string.c b/firmware/core/libc/string.c index 3fe0b9c..e6bb0fe 100644 --- a/firmware/core/libc/string.c +++ b/firmware/core/libc/string.c @@ -52,6 +52,7 @@ void * memcpy(void *pDestination, const void *pSource, size_t num) { unsigned char *pByteDestination; unsigned char *pByteSource; +#ifdef FAST_MEMCPY unsigned int *pAlignedSource = (unsigned int *) pSource; unsigned int *pAlignedDestination = (unsigned int *) pDestination; @@ -71,6 +72,10 @@ void * memcpy(void *pDestination, const void *pSource, size_t num) // Copy remaining bytes pByteDestination = (unsigned char *) pAlignedDestination; pByteSource = (unsigned char *) pAlignedSource; +#else + pByteDestination = (unsigned char *) pDestination; + pByteSource = (unsigned char *) pSource; +#endif while (num--) { *pByteDestination++ = *pByteSource++; From d0be542bbea85956cd308bc108670366590e28b0 Mon Sep 17 00:00:00 2001 From: Stefan `Sec` Zehl Date: Sat, 28 Jan 2012 12:50:41 +0100 Subject: [PATCH 06/19] ignore binary files in smartflash/ --- tools/smartflash/.gitignore | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 tools/smartflash/.gitignore diff --git a/tools/smartflash/.gitignore b/tools/smartflash/.gitignore new file mode 100644 index 0000000..b211c62 --- /dev/null +++ b/tools/smartflash/.gitignore @@ -0,0 +1,2 @@ +firmware.bin +files From 709c402f294f4266d4ce651fcb37a1cc21273168 Mon Sep 17 00:00:00 2001 From: Stefan `Sec` Zehl Date: Sat, 28 Jan 2012 14:23:27 +0100 Subject: [PATCH 07/19] Improve meshtrace/beacontrace --- tools/mesh/beacontrace.pl | 104 +++++++++++++++++++++++++++++--------- tools/mesh/meshtrace.pl | 17 +++---- tools/mesh/r0ket.pm | 68 +++++++++++++++++++++++-- 3 files changed, 150 insertions(+), 39 deletions(-) diff --git a/tools/mesh/beacontrace.pl b/tools/mesh/beacontrace.pl index c23fd8a..fe90f61 100755 --- a/tools/mesh/beacontrace.pl +++ b/tools/mesh/beacontrace.pl @@ -5,28 +5,28 @@ use strict; use Curses; use POSIX qw(strftime); +use Time::HiRes qw(time); use lib '.'; use r0ket; $|=1; -my $ser=""; +r0ket::r0ket_init(); -do {$ser=$_ if ( -e $_ ) } for qw(/dev/ttyS3 /dev/ttyACM0); - -if ($ARGV[0] eq "-s"){ - shift; - $ser=shift; -}; - -open(SER, "+<",$ser) || die "open serial: $!"; +# Default openbeacon settings. +r0ket::set_txmac(pack("H*","0102030201")); +r0ket::set_rxmac(pack("H*","0102030201")); +r0ket::set_channel(81); +r0ket::set_rxlen(16); #r0ket::readbeacon(); my $str; my %bdata; +sub do_str; + initscr; END{endwin;} use constant WIDTH => 80; @@ -40,25 +40,79 @@ $win_top->addstr(1,0,"-"x20); $win_top->refresh; my $beaconctr=0; +use constant CLEAN => 10; +use constant UPDATE => 0.3; +my $lasttime; +my $lastcleantime; +my $clean; +my $crcerr=0; while(1){ - $str=r0ket::get_packet(\*SER); + $str=r0ket::get_packet(); my $p=r0ket::nice_beacon($str); - if(!$bdata{$p->{beacon}}){ - $bdata{$p->{beacon}}=++$beaconctr; - }; - if($p->{type} eq "beacon"){ - $win->addstr($bdata{$p->{beacon}},0, - sprintf "%s | bt=%s str=%s idx=%8s | %s", - $p->{beacon}, - $p->{button}, - $p->{strength}, - $p->{idx}, - r0ket::getbeacon($p->{beacon}) - ); - }else{ - $win->addstr($bdata{$p->{beacon}},40,$p->{nick}); + if($p->{crc} ne "ok"){ + $crcerr++; + next; }; - $win->refresh; + if($p->{type} eq "beacon"){ + $bdata{$p->{beacon}}{seen}=time; + $bdata{$p->{beacon}}{beacon}=$p; + $bdata{$p->{beacon}}{stats}{$p->{strength}}++; + if(!defined($bdata{$p->{beacon}}{stats}{first})){ + $bdata{$p->{beacon}}{stats}{first}=time; + }; + }elsif($p->{type} eq "nick"){ + $bdata{$p->{beacon}}{nick}=$p->{nick}; + }else{ #unknown + ; + }; + + if(time>$lastcleantime+CLEAN){ + $clean=1; + $lastcleantime=time; + }else{ + $clean=0; + }; + + my $line=0; + if($clean){ + $win->clear; + for my $b (sort keys %bdata){ + if($bdata{$b}{seen}+10$lasttime+UPDATE){ + for my $b (sort keys %bdata){ + $win->addstr($line++,0, + sprintf "%s | bt=%s idx=%8s | %s | %s", + $b, + $bdata{$b}{beacon}->{button}, + $bdata{$b}{beacon}->{idx}, + do_str($bdata{$b}{stats}), + $bdata{$b}{nick}." " + ); + }; + $win_top->addstr(1,20,sprintf" cnt=%2d, crc=%d",scalar(keys %bdata),$crcerr); + $win_top->refresh; + + $win->refresh; + $lasttime=time; + }; }; r0ket::rest(); + +sub do_str{ + my $hr=shift; + my $df=time()-$hr->{first}; + $df=1 if $df==0; + my $out=""; +# for(sort keys %$hr){ + for(qw(00 55 aa ff)){ + next if $_ eq "first"; + $out.=sprintf("%3d% ",($hr->{$_}/$df)*100/2); + }; + + return $out; +}; diff --git a/tools/mesh/meshtrace.pl b/tools/mesh/meshtrace.pl index 6dbd2d1..5b94300 100755 --- a/tools/mesh/meshtrace.pl +++ b/tools/mesh/meshtrace.pl @@ -11,16 +11,13 @@ use r0ket; $|=1; -my $ser=""; +r0ket::r0ket_init(); -do {$ser=$_ if ( -e $_ ) } for qw(/dev/ttyS3 /dev/ttyACM0); - -if ($ARGV[0] eq "-s"){ - shift; - $ser=shift; -}; - -open(SER, "+<",$ser) || die "open serial: $!"; +# Default mesh settings. +r0ket::set_txmac("ORBIT"); +r0ket::set_rxmac("ORBIT"); +r0ket::set_channel(83); +r0ket::set_rxlen(32); r0ket::readbeacon(); @@ -41,7 +38,7 @@ $win_top->refresh; my $beaconctr=0; while(1){ - $str=r0ket::get_packet(\*SER); + $str=r0ket::get_packet(); my $p=r0ket::pkt_beauty($str); if(!$bdata{$p->{beacon}}){ $bdata{$p->{beacon}}=++$beaconctr; diff --git a/tools/mesh/r0ket.pm b/tools/mesh/r0ket.pm index 26a94cc..ca97a41 100755 --- a/tools/mesh/r0ket.pm +++ b/tools/mesh/r0ket.pm @@ -10,6 +10,8 @@ package r0ket; use Digest::CRC qw(crcccitt); use POSIX qw(strftime); +our $verbose=1; +our $bridge; # Open device ### Utility sub sprint{ @@ -68,11 +70,9 @@ sub writebeacon{ our $buffer; sub get_packet{ - my $dev=shift; - sub _get_bytes{ my $rr; - sysread($dev,$rr,1024); + sysread($bridge,$rr,1024); if(length($rr)<=1){ select(undef,undef,undef,0.1); }; @@ -80,7 +80,7 @@ sub get_packet{ }; my $cnt=0; - while(++$cnt<10){ + while(++$cnt<50){ if(length($buffer)<2){ _get_bytes(); }elsif($buffer !~ /^\\[12]/){ @@ -180,6 +180,17 @@ sub nice_beacon{ }else{ $out->{string}=""; }; + + my $pkt_crc= unpack("n",substr($pkt,length($pkt)-2,2)); + my $calc_crc= crcccitt(substr($pkt,0,length($pkt)-2)); + + if ($pkt_crc eq $calc_crc){ + $out->{crc}="ok"; + }else{ + $out->{crc}="fail"; + $out->{string}.= " CRCFAIL"; + }; + return $out; }; @@ -202,5 +213,54 @@ sub pkt_beauty{ return $out; } +sub r0ket_init{ + my $ser; + if ($ARGV[0] eq "-s"){ + shift; + $ser=shift; + }; + if(!defined $ser){ + if (defined $ENV{R0KETBRIDGE} && -e $ENV{R0KETBRIDGE}){ + $ser=$ENV{R0KETBRIDGE} + }; + }; + if(!defined $ser){ + do {$ser=$_ if ( -e $_ ) } for qw(/dev/ttyS3 /dev/ttyACM0); + }; + open($bridge, "+<",$ser) || die "open serial: $!"; + if($verbose){ + print "using: $ser\n"; + }; +}; + +sub send_raw { + if($verbose){ + print "send: ",unpack("H*",$_[0]),"\n"; + }; + syswrite($bridge,shift); +}; + +sub send_pkt_num { + my $pkt=shift; + $pkt=~s/\\/\\\\/; + send_raw('\\'.shift().$pkt.'\0'); +}; + +sub send_pkt { + send_pkt_num(shift,1); +}; + +sub set_txmac { + send_pkt_num(shift,3); +}; +sub set_rxmac { + send_pkt_num(shift,4); +}; +sub set_channel { + send_pkt_num(pack("C",shift),5); +}; +sub set_rxlen { + send_pkt_num(pack("C",shift),6); +}; 1; From 3b04b9e052c94e725d96a94d3b18b3263fd2f58a Mon Sep 17 00:00:00 2001 From: Stefan `Sec` Zehl Date: Sat, 28 Jan 2012 17:12:43 +0100 Subject: [PATCH 08/19] Add new "rf" utility. Quite functional rf debugging/dumping util --- tools/mesh/meshtrace.pl | 8 +- tools/mesh/r0ket.pm | 135 ++++++++++++++++----- tools/mesh/rf | 263 ++++++++++++++++++++++++++++++++++++++++ 3 files changed, 377 insertions(+), 29 deletions(-) create mode 100755 tools/mesh/rf diff --git a/tools/mesh/meshtrace.pl b/tools/mesh/meshtrace.pl index 5b94300..2788083 100755 --- a/tools/mesh/meshtrace.pl +++ b/tools/mesh/meshtrace.pl @@ -37,9 +37,15 @@ $win_top->addstr(1,0,"-"x20); $win_top->refresh; my $beaconctr=0; +my $crcerr=0; while(1){ $str=r0ket::get_packet(); - my $p=r0ket::pkt_beauty($str); + my $p=r0ket::nice_mesh($str); + if($p->{crc} ne "ok"){ + $crcerr++; + next; + }; + if(!$bdata{$p->{beacon}}){ $bdata{$p->{beacon}}=++$beaconctr; }; diff --git a/tools/mesh/r0ket.pm b/tools/mesh/r0ket.pm index ca97a41..38baaab 100755 --- a/tools/mesh/r0ket.pm +++ b/tools/mesh/r0ket.pm @@ -9,8 +9,9 @@ package r0ket; use Digest::CRC qw(crcccitt); use POSIX qw(strftime); +use Time::HiRes; -our $verbose=1; +our $verbose=0; our $bridge; # Open device ### Utility @@ -19,11 +20,32 @@ sub sprint{ if (ord($_)>30 && ord($_)<127){ $_; }else{ - "[x".unpack("H*",$_)."]"; +# "[x".unpack("H*",$_)."]"; + "\\".unpack("C",$_); } }split(//,shift)); }; +sub hprint{ + return unpack("H*",shift); +}; + +sub flagsstr { + my $in=shift; + my @f; + my $f=1; + for (@_){ + if($in & $f){ + push @f,$_; + }; + $f*=2; + }; + return join(",",@f); +}; + + + + ### Nickname/beacon helper functions our %beacon; sub readbeacon{ @@ -69,32 +91,39 @@ sub writebeacon{ ### Packet mgmt our $buffer; +our $firstpkt=2; sub get_packet{ sub _get_bytes{ my $rr; sysread($bridge,$rr,1024); if(length($rr)<=1){ - select(undef,undef,undef,0.1); + select(undef,undef,undef,0.05); }; $buffer.=$rr; }; my $cnt=0; - while(++$cnt<50){ + while(++$cnt<100){ if(length($buffer)<2){ _get_bytes(); }elsif($buffer !~ /^\\[12]/){ $buffer=~s/^(.[^\\]*)//s; -# print STDERR "Unparseable stuff: <",sprint($1),">\n"; - }elsif ($buffer =~ s/^\\([12])(.*?)\\0//s){ - my $str=$2; + if($firstpkt){ + $firstpkt--; + }else{ + print STDERR "Unparseable stuff: <",sprint($1),">\n"; + }; + }elsif ($buffer =~ s/^\\2\\0//s){ + return 'ack'; # In-band signalling. Evil %) + }elsif ($buffer =~ s/^\\1(.*?)\\0//s){ + my $str=$1; $str=~s/\\\\/\\/g; # dequote return $str; }else{ _get_bytes(); }; }; - die "No packets for >1sec?\n"; + die "No packets for 5seconds?\n"; }; sub rest{ @@ -120,7 +149,7 @@ sub nice_mesh{ $out->{string}.=sprintf " t=%s (%+4d) rel=%s beacon=%s", strftime("%Y-%m-%d %H:%M:%S",gmtime $out->{time}), - $out->{time}-(time+3600), + $out->{time}-(Time::HiRes::time+3600), $out->{release}, resolvebeacon($out->{beacon}); }elsif($type eq "i"){ @@ -142,6 +171,65 @@ sub nice_mesh{ }else{ $out->{string}.= " "; }; + + my $pkt_crc= unpack("n",substr($pkt,length($pkt)-2,2)); + my $calc_crc= crcccitt(substr($pkt,0,length($pkt)-2)); + + if ($pkt_crc eq $calc_crc){ + $out->{crc}="ok"; + }else{ + $out->{crc}="fail"; + $out->{string}.= " CRCFAIL"; + }; + + return $out; +}; + +sub nice_game{ + my $pkt=shift; + my $out; + my $type=substr($pkt,2,1); + + $out->{proto}=substr($pkt,1,1); + $out->{type} =substr($pkt,2,1); + $out->{id} =unpack("V",substr($pkt,3,4)); + $out->{ctr} =unpack("V",substr($pkt,7,4)); + + $out->{string}=sprintf "G[%s] id=%d ctr=%d", + $out->{type}, $out->{id}, $out->{ctr}; + + if($type eq "A"){ + $out->{mac} = substr($pkt,11,5); + $out->{channel} = unpack("C" ,substr($pkt,16,1)); + $out->{id} = unpack("v", substr($pkt,17,2)); + $out->{flags} = unpack("C", substr($pkt,19,1)); + $out->{flagsstr}=flagsstr($out->{flags},qw(mass short lrecv)); + $out->{interval} = unpack("C", substr($pkt,20,1)); + $out->{jitter} = unpack("C", substr($pkt,21,1)); + $out->{title} = unpack("Z*",substr($pkt,22,10)); + + $out->{string}.=sprintf " mac=%s ch=%s id=%d fl=<%s> itvl=%d j=%d %s", + sprint($out->{mac}), + $out->{channel}, + $out->{id}, + $out->{flagsstr}, + $out->{interval}, + $out->{jitter}, + $out->{title}; + }else{ + $out->{string}.= " "; + }; + + my $pkt_crc= unpack("n",substr($pkt,length($pkt)-2,2)); + my $calc_crc= crcccitt(substr($pkt,0,length($pkt)-2)); + + if ($pkt_crc eq $calc_crc){ + $out->{crc}="ok"; + }else{ + $out->{crc}="fail"; + $out->{string}.= " CRCFAIL"; + }; + return $out; }; @@ -194,25 +282,6 @@ sub nice_beacon{ return $out; }; - -sub pkt_beauty{ - my $pkt=shift; - my $out; - - $out=nice_mesh($pkt); - - my $pkt_crc= unpack("n",substr($pkt,length($pkt)-2,2)); - my $calc_crc= crcccitt(substr($pkt,0,length($pkt)-2)); - - if ($pkt_crc eq $calc_crc){ - $out->{crc}="ok"; - }else{ - $out->{crc}="fail"; - $out->{string}.= " CRCFAIL"; - }; - return $out; -} - sub r0ket_init{ my $ser; if ($ARGV[0] eq "-s"){ @@ -263,4 +332,14 @@ sub set_rxlen { send_pkt_num(pack("C",shift),6); }; +sub wait_ok { + my $pkt; + $pkt=get_packet(); + while($pkt ne "ack"){ + print "pkt=",(sprint $pkt),"\n"; + $pkt=get_packet(); + }; + print "ok!\n"; + return 1; +}; 1; diff --git a/tools/mesh/rf b/tools/mesh/rf new file mode 100755 index 0000000..23f68b3 --- /dev/null +++ b/tools/mesh/rf @@ -0,0 +1,263 @@ +#!/usr/bin/perl +# +# vim:set ts=4 sw=4: + +use strict; + +use IO::Select; +use Digest::CRC qw(crcccitt); +use POSIX qw(strftime); + +use lib '.'; +use r0ket; + +$|=1; + +r0ket::r0ket_init(); + +my @fh; +my $read; + +if ($ARGV[0] =~ /^-?-?h/){ + print STDERR "Mini-Help:\n"; + print STDERR "-s (or \$R0KETBRIDGE)\n"; + print STDERR "-w write beacon2nick file\n"; + print STDERR "\n"; + print STDERR "recv: receive (number) pakets\n"; + print STDERR " - r hex : hexdump packets\n"; + print STDERR " - r ascii : asciidump packets\n"; + print STDERR " - r beacon : parse as openbeacon\n"; + print STDERR " - r mesh : parse as mesh packet\n"; + print STDERR " - r m : and show only \n"; + print STDERR "\n"; + print STDERR "send: send packet (number) times\n"; + print STDERR " - s raw : send raw hex packet\n"; + print STDERR " - s hex : send packet with crc16\n"; + print STDERR " - s mesh t : send mesh time packet\n"; + print STDERR " - s mesh , see source :-)\n"; + print STDERR "\n"; + print STDERR "preset: config per preset\n"; + print STDERR "- p m - preset minimesh\n"; + print STDERR "- p b - preset openbeacon\n"; + print STDERR "config: config rf chip\n"; + print STDERR "- c rx - set rxmac\n"; + print STDERR "- c tx - set txmac\n"; + print STDERR "- c len - set rxlength\n"; + print STDERR "- c ch - set channel\n"; + print STDERR "- c hex - set any option via hex string\n"; + print STDERR "\n"; + print STDERR "etc...\n"; + exit(1); +}; + +my $writend=0; +if ($ARGV[0] eq "-w"){ + shift; + $writend=1; +}; + +END{ + r0ket::writebeacon if($writend); +}; + +my $cmd=shift; + +if($cmd =~ /^r/){ + r0ket::readbeacon(); + $cmd=~s/r(ecv)?//; + $cmd=100 if $cmd+0==0; + my $fmt=shift || "_"; + my $arg=shift || undef; + my $read=""; + + my $str; + while($cmd>0){ + $str=r0ket::get_packet(); + + if($fmt =~ /_/){ + if(substr($str,0,1)eq "\x10"){ + if(substr($str,1,1)eq"G"){ + $fmt="g_"; + }else{ + $fmt="b_"; + }; + }elsif(substr($str,0,1)eq "\x20"){ + $fmt="g_"; + }elsif(length($str)==32){ + $fmt="m_"; + }else{ + $fmt="x_"; + }; + }; + + if($fmt =~ /^m/){ + my $p=r0ket::nice_mesh($str); + print $p->{string}; + }elsif($fmt =~ /^b/){ + my $p=r0ket::nice_beacon($str); + print $p->{string}; + }elsif($fmt =~ /^g/){ + my $p=r0ket::nice_game($str); + print $p->{string}; + }elsif($fmt =~ /^(x|hex)/){ + my $pkt_crc= unpack("n",substr($str,length($str)-2,2)); + my $calc_crc= crcccitt(substr($str,0,length($str)-2)); + print "<",unpack("H*",$str),">"; + if($pkt_crc ne $calc_crc){ + print " CRCFAIL"; + }; + }elsif($fmt =~ /^a/){ + print "<", r0ket::sprint($str), ">"; + }else{ + die "Unknown packet format: $fmt\n"; + }; + print "\n"; + $cmd--; + next; + }; + r0ket::rest(); +}elsif ($cmd =~ /^p/){ # Preset + my $sub=shift; + if ($sub =~/^m/i){ # Default mesh settings. + r0ket::set_txmac("ORBIT"); + r0ket::set_rxmac("ORBIT"); + r0ket::set_channel(83); + r0ket::set_rxlen(32); + }elsif ($sub =~/^b/i){ # Default OpenBeacon settings + r0ket::set_txmac(pack("H*","0102030201")); + r0ket::set_rxmac(pack("H*","0102030201")); + r0ket::set_channel(81); + r0ket::set_rxlen(16); + }elsif ($sub =~/^a/i){ # Default rem0te announce settings + r0ket::set_txmac("REM0T"); + r0ket::set_rxmac("REM0T"); + r0ket::set_channel(87); + r0ket::set_rxlen(32); + }elsif ($sub =~/^r/i){ # Default bpong game settings + r0ket::set_txmac("BPONG"); + r0ket::set_rxmac("BPONG"); + r0ket::set_channel(91); + r0ket::set_rxlen(32); + }else{ + die "Unkown preset $sub\n"; + }; +}elsif ($cmd =~ /^c/){ + my $set=shift; + + if($set=~s/hex//){ + $ARGV[0]=pack("H*",$ARGV[0]); + }; + if ($set =~ /^tx/){ + r0ket::set_txmac(shift); + }elsif ($set =~ /^rx/){ + r0ket::set_rxmac(shift); + }elsif ($set =~ /^ch/){ + r0ket::set_channel(shift); + }elsif ($set =~ /^len/){ + r0ket::set_rxlen(shift); + }else{ + die "Unknown config argument $set\n"; + }; + r0ket::wait_ok(); + +}elsif ($cmd =~ /^s/){ + $cmd=~s/^//; + $cmd=1 if $cmd==0; + + my $pkt; + + my $sub=shift; + if($sub =~ /^raw/){ + $pkt=pack("H*",shift); + }elsif($sub =~ /^hex/){ + $pkt=pack("H*",shift); + $pkt.=pack("n",crcccitt($pkt)); + }elsif($sub =~ /^m/){ + my $scmd=shift; + + if($scmd eq "t"){ + $pkt.="T"; + $pkt.=chr(shift); #gen + $pkt.=pack("N",scalar(time)+1*60*60); + + $pkt.=pack("N",0); + $pkt.=pack("N",0); + $pkt.=pack("N",0); + $pkt.=pack("N",0); + $pkt.=pack("N",0); + $pkt.=pack("N",0); + }elsif($scmd eq "a"){ + $pkt.="A"; + $pkt.=chr(shift); #gen + $pkt.=pack("N",scalar(time)+1*60*60+ 300); + + $pkt.= pack("C",shift||0); + $pkt.= pack("C",0); + $pkt.= pack("C",0); + $pkt.= pack("C",0); + + $pkt.=pack("N",0); + $pkt.=pack("N",0); + $pkt.=pack("N",0); + $pkt.=pack("N",0); + $pkt.=pack("N",0); + }elsif($scmd eq "b"){ + $pkt.="B"; + $pkt.=chr(shift); #gen + $pkt.=pack("N",scalar(time)+1*60*60+ 600); + + $pkt.= pack("C",shift||0); + $pkt.= pack("C",0); + $pkt.= pack("C",0); + $pkt.= pack("C",0); + + $pkt.=pack("N",0); + $pkt.=pack("N",0); + $pkt.=pack("N",0); + $pkt.=pack("N",0); + $pkt.=pack("N",0); + }elsif($scmd eq "c"){ + $pkt.="\x1"; + $pkt.=chr(shift); #gen + $pkt.=pack("N",scalar(time)+1*60*60+ 600); + + $pkt.= pack("C",shift||0); + $pkt.= pack("C",0); + $pkt.= pack("C",0); + $pkt.= pack("C",0); + + $pkt.=pack("N",0); + $pkt.=pack("N",0); + $pkt.=pack("N",0); + $pkt.=pack("N",0); + $pkt.=pack("N",0); + }elsif($scmd eq "i"){ + $pkt.="i"; + $pkt.=chr(shift); #gen + $pkt.=pack("N",shift||42); + + $pkt.=shift; + $pkt.="\0"x(30-length($pkt)); + }else{ + die "Unknown mesh subtype: $scmd\n"; + }; + $pkt.=pack("n",crcccitt($pkt)); + }else{ + die "Unknown send subtype: $sub\n"; + }; + + print "Write: <", sprint($pkt),">, "; + print "crc: ",unpack("n",substr($pkt,length($pkt)-2,2))," "; + print "len: ",length($pkt),"\n"; + while($cmd-->0){ + r0ket::send_pkt($pkt); + r0ket::wait_ok; + }; +}else{ + die "Option not understood\n"; +}; + +#if (@fh = $sel->can_read(10)) { +# sysread($fh[0],$read,1024); +#} +#print "PostRead: <", sprint($read), ">\n"; From d75bc7c953522e5af8ded3f670fc80e4aa482468 Mon Sep 17 00:00:00 2001 From: Hagen Fritsch Date: Fri, 12 Aug 2011 23:47:41 +0200 Subject: [PATCH 09/19] Merge runmpletux': file select cursor wrap around Conflicts: firmware/filesystem/select.c --- firmware/filesystem/select.c | 31 ++++++++++++++++++++++--------- 1 file changed, 22 insertions(+), 9 deletions(-) diff --git a/firmware/filesystem/select.c b/firmware/filesystem/select.c index 07399f1..fb5cfef 100644 --- a/firmware/filesystem/select.c +++ b/firmware/filesystem/select.c @@ -8,6 +8,7 @@ #define FLEN 13 +/* if count is 0xff (-1) do not fill files and return the count instead */ int getFiles(char files[][FLEN], uint8_t count, uint16_t skip, const char *ext) { DIR dir; /* Directory object */ @@ -37,7 +38,9 @@ int getFiles(char files[][FLEN], uint8_t count, uint16_t skip, const char *ext) continue; }; - strcpy(files[pos++],Finfo.fname); + if(count != 0xff) + strcpy(files[pos],Finfo.fname); + pos++; if( pos == count ) break; } @@ -50,17 +53,19 @@ int selectFile(char *filename, const char *extension) int skip = 0; char key; int selected = 0; + int file_count = getFiles(NULL, 0xff, 0, extension); + font=&Font_7x8; + if(!file_count){ + lcdPrintln("No Files?"); + lcdRefresh(); + getInputWait(); + getInputWaitRelease(); + return -1; + }; while(1){ char files[PERPAGE][FLEN]; int count = getFiles(files, PERPAGE, skip, extension); - if(!count){ - lcdPrintln("No Files?"); - lcdRefresh(); - getInputWait(); - getInputWaitRelease(); - return -1; - }; if(count 0 ){ skip--; + } else { // wrap to bottom + skip = file_count - PERPAGE; + if(skip < 0) skip = 0; + selected = file_count - skip - 1; } } break; From b5c12b866698c1174fdb101520ebfd8b890af0ed Mon Sep 17 00:00:00 2001 From: Stefan `Sec` Zehl Date: Sat, 28 Jan 2012 18:01:52 +0100 Subject: [PATCH 10/19] Make release-all able to take $MAKE for non-gnumake systems inspired by 764d4ca from matthiasr --- firmware/release-all | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/firmware/release-all b/firmware/release-all index 0ba0d5b..bc0853c 100755 --- a/firmware/release-all +++ b/firmware/release-all @@ -1,5 +1,11 @@ #!/bin/sh -e +# We currently don't use crypto, so this script is deprecated. + +if [ -z ${MAKE} ]; then + which gmake >/dev/null && MAKE=gmake || MAKE=make +fi + TARG=../release if [ ! -d ../firmware ] ; then @@ -32,9 +38,9 @@ echo "###" echo "### Building final" echo "###" export FINAL=y -make clean +$MAKE clean ./l0dable/mktable.pl -make APP=final +$MAKE APP=final cp firmware.elf $TARG/final.elf cp firmware.bin $TARG/final.bin @@ -48,7 +54,7 @@ cp ../tools/image/lcd/i42.lcd $TARG/files/nick.lcd echo "###" echo "### Gathering loadables" echo "###" -(cd l0dable && make) +(cd l0dable && $MAKE) mv l0dable/*.c0d $TARG/files/ mv l0dable/*.int $TARG/files/ mv l0dable/*.nik $TARG/files/ @@ -59,7 +65,7 @@ if grep -q 'define ENCRYPT_L0DABLE' SECRETS ; then echo "###" echo "### Building crypto" echo "###" -(cd ../tools/crypto && make) +(cd ../tools/crypto && $MAKE) echo "###" echo "### Crypting loadables" From 62825bc3e5a1ab1886042bb924c2f9a237c8ac70 Mon Sep 17 00:00:00 2001 From: Stefan `Sec` Zehl Date: Sat, 28 Jan 2012 18:10:16 +0100 Subject: [PATCH 11/19] Add some notes for people using a standard cross-gcc --- firmware/README.building | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/firmware/README.building b/firmware/README.building index 954edae..6575602 100644 --- a/firmware/README.building +++ b/firmware/README.building @@ -1,4 +1,13 @@ -make flags supported by this Makefile +### A note on the compiler +We are currently using the CodeSourcery gcc (see wiki for link). +You can also use a standard arm cross-gcc + (https://github.com/esden/summon-arm-toolchain) +but please note that this creates larger binaries. +We are talking about 100-200 bytes for firmware.bin, +you will run into space problems with the default firmware. +Sorry about that. + +### Make flags supported by this Makefile APP= - builds "application" foo (check .c and the subdir in applications/) @@ -28,5 +37,5 @@ make APP=l0dable LAPP= (=l0dable.bin) # build all l0dables make l0dables -#build one l0dable +# build one l0dable cd l0dables && make .c0d From 1fda56be1e3b951e0a44a73706ff76f284944b76 Mon Sep 17 00:00:00 2001 From: Stefan `Sec` Zehl Date: Sat, 28 Jan 2012 18:20:51 +0100 Subject: [PATCH 12/19] Fix display for leading zeros on report by derf. --- firmware/l0dable/voltage.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/firmware/l0dable/voltage.c b/firmware/l0dable/voltage.c index 3a9ca5f..1ef8175 100644 --- a/firmware/l0dable/voltage.c +++ b/firmware/l0dable/voltage.c @@ -39,7 +39,7 @@ void ram(void) { lcdPrint(" "); lcdPrint(IntToStr(v,2,0)); lcdPrint("."); - lcdPrint(IntToStr(mv%1000,3,F_ZEROS)); + lcdPrint(IntToStr(mv%1000,3,F_ZEROS|F_LONG)); lcdPrintln("V"); lcdNl(); From 76b87e26ff6d743dbb5379ce467185b8537e34bd Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Wed, 28 Dec 2011 22:53:07 +0100 Subject: [PATCH 13/19] keep scrolling when the button keeps being pressed (cherry picked from commit dcb720ac223304e6c0b238403dda3ca851c15ef0) Signed-off-by: Stefan `Sec` Zehl --- firmware/filesystem/select.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/firmware/filesystem/select.c b/firmware/filesystem/select.c index fb5cfef..50e8067 100644 --- a/firmware/filesystem/select.c +++ b/firmware/filesystem/select.c @@ -93,8 +93,7 @@ int selectFile(char *filename, const char *extension) files[i][dot]='.'; } lcdRefresh(); - key=getInputWait(); - getInputWaitRelease(); + key=getInputWaitRepeat(); switch(key){ case BTN_DOWN: if( selected < count-1 ){ From 44f09ef804a718a8f80715b5db24c18f0b9d3795 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Wed, 4 Jan 2012 21:45:59 +0100 Subject: [PATCH 14/19] Update gitignore (cherry picked from commit 06cd54f63cd86a2788ecba914464da2ca46ac155) Signed-off-by: Stefan `Sec` Zehl --- firmware/.gitignore | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/firmware/.gitignore b/firmware/.gitignore index d2d2dd6..586d0f2 100644 --- a/firmware/.gitignore +++ b/firmware/.gitignore @@ -1,5 +1,5 @@ -firmware.bin -firmware.elf +*.bin +*.elf lpc1xxx/memory.ld applications/wrapper.c lcd/allfonts.h From 63f5536ccf2f439036b4e130c75519d63ef0e77c Mon Sep 17 00:00:00 2001 From: Stefan `Sec` Zehl Date: Sat, 28 Jan 2012 18:47:53 +0100 Subject: [PATCH 15/19] Add new/better snake.c from git://github.com/MascHman/r0ket.git --- firmware/applications/final/mesh.c | 6 + firmware/l0dable/snake.c | 322 +++++++++++++++++++++++++++++ firmware/l0dable/snake.c.disabled | 194 ----------------- 3 files changed, 328 insertions(+), 194 deletions(-) create mode 100644 firmware/l0dable/snake.c delete mode 100644 firmware/l0dable/snake.c.disabled diff --git a/firmware/applications/final/mesh.c b/firmware/applications/final/mesh.c index 63fb4c1..f2692f0 100644 --- a/firmware/applications/final/mesh.c +++ b/firmware/applications/final/mesh.c @@ -186,6 +186,9 @@ void m_choose(){ case('r'): strcpy(p,"r0type"); break; + case('s'): + strcpy(p,"Snake"); + break; #endif default: p[0]=*mm; @@ -233,6 +236,9 @@ void m_choose(){ case('r'): strcpy(p,"r0type"); break; + case('s'): + strcpy(p,"Snake"); + break; #endif }; if(tmm[i]>='a' && tmm[i]<='z'){ diff --git a/firmware/l0dable/snake.c b/firmware/l0dable/snake.c new file mode 100644 index 0000000..ce7a56c --- /dev/null +++ b/firmware/l0dable/snake.c @@ -0,0 +1,322 @@ +/* + * snake + ******** + * a snake clone for the r0ket + * created by Flori4n (DrivenHoliday) & MascH (CCCHB tent) + ***************************************/ + +#include +#include + +#include "basic/basic.h" +#include "basic/config.h" +#include "basic/random.h" +#include "lcd/render.h" +#include "lcd/display.h" +#include "lcd/fonts.h" +#include "lcd/fonts/invaders.h" +//#Include "lcd/lcd.h" +//#include "lcd/print.h" +#include "funk/mesh.h" +#include "usetable.h" + +#define MAX_SNAKE_LEN (40) +#define SNAKE_DIM (3) +#define MIN_SPEED (25) +#define MAX_SPEED (3) +#define MIN_X 2 +#define MAX_X (RESX-3) +#define MIN_Y 8 +#define MAX_Y (RESY-2) +#define SIZE_X ((MAX_X-MIN_X)/SNAKE_DIM) +#define SIZE_Y ((MAX_Y-MIN_Y)/SNAKE_DIM) + +#define RIGHT 0 +#define LEFT 2 +#define UP 3 +#define DOWN 1 + +struct pos_s { + int x,y; +}; + +struct snake_s { + struct pos_s *tail; + int len, dir, speed, t_start; +}; + +static void reset(); +static void next_level(); +static void draw_block(); +static void handle_input(); +static void death_anim(); +static struct pos_s getFood(void); +static int hitWall(); +static int hitFood(); +static int hitSelf(); +static int showHighscore(); + +int points = 0; +struct snake_s snake = { NULL, 3, 0, MIN_SPEED, 2}; +struct pos_s food; + +void ram(void) +{ + int c=0, pos=0,del=0; + + struct pos_s tail[MAX_SNAKE_LEN]; + snake.tail = tail; + + // initially reset everything + reset(); + + while (1) + { + if(!(++c % snake.speed)) { + handle_input(); + + pos = (snake.t_start+1) % MAX_SNAKE_LEN; + snake.tail[pos].x = snake.tail[snake.t_start].x; + snake.tail[pos].y = snake.tail[snake.t_start].y; + + if(snake.dir == 0) + snake.tail[pos].x++; + else if(snake.dir == 1) + snake.tail[pos].y++; + else if(snake.dir == 2) + snake.tail[pos].x--; + else if(snake.dir == 3) + snake.tail[pos].y--; + + snake.t_start = pos; + + if (pos < snake.len) { + del = MAX_SNAKE_LEN - (snake.len - pos); + } else + del = pos - snake.len; + + // remove last, add first line + draw_block(snake.tail[del].x, snake.tail[del].y, 0); + draw_block(snake.tail[pos].x, snake.tail[pos].y, 1); + + // check for obstacle hit.. + if (hitWall() || hitSelf()) { + death_anim(); + if (showHighscore()) + break; + reset(); + } + else if (hitFood()) + next_level(); + + lcdDisplay(); + } + +#ifdef SIMULATOR + delayms(50); +#else + delayms(3); +#endif + } +} + +static struct pos_s getFood(void) +{ + int i,pos; + struct pos_s res; + + tryagain: + res.x = (getRandom() % (SIZE_X-1)) + 1; + res.y = (getRandom() % (SIZE_Y-3)) + 3; + + for(i=0; i= MAX_X) + || (snake.tail[snake.t_start].y*3 <= MIN_Y) + || (snake.tail[snake.t_start].y*3 >= MAX_Y) ) ? + 1 : 0; + +} + +static int hitSelf() +{ + int i, pos; + for (i=1; ipkt)>score) + return false; + + MO_TIME_set(mpkt->pkt,score); + strcpy((char*)MO_BODY(mpkt->pkt),nick); + if(GLOBAL(privacy)==0){ + uint32touint8p(GetUUID32(),mpkt->pkt+26); + mpkt->pkt[25]=0; + }; + return true; +} + +static uint32_t highscore_get(char nick[]){ + MPKT * mpkt= meshGetMessage('s'); + char * packet_nick = (char*)MO_BODY(mpkt->pkt); + // the packet crc end is already zeroed + if(MAXNICKpkt); +} + +static int showHighscore() +{ + int key = getInputRaw(); //throw away pending keypress + char nick[20]; + uint32_t score = 0; + + highscore_set(points,GLOBAL(nickname)); + score = highscore_get(nick); + + lcdClear(); + DoString(0,RESY/2-33, " Your Score"); + DoInt(RESX/2-4, RESY/2-25, points); + DoString(0,RESY/2-10, " Highscore"); + DoInt(RESX/2-4, RESY/2-2, score); + DoString(0, RESY/2+18, " UP to play "); + DoString(0, RESY/2+26, "DOWN to quit "); + + lcdDisplay(); + + while(1) { + key = getInputRaw(); + if (key&BTN_DOWN) { + return 1; + } else if (key&BTN_UP) { + return 0; + } + } +} + +static int hitFood() +{ + return ((snake.tail[snake.t_start].x == food.x) && (snake.tail[snake.t_start].y == food.y)) ? 1 : 0; +} diff --git a/firmware/l0dable/snake.c.disabled b/firmware/l0dable/snake.c.disabled deleted file mode 100644 index 9422712..0000000 --- a/firmware/l0dable/snake.c.disabled +++ /dev/null @@ -1,194 +0,0 @@ -#include -#include "basic/basic.h" -#include "basic/config.h" - -#include "lcd/lcd.h" -#include "lcd/print.h" -#include "usetable.h" - -struct elem -{ - int x,y; -}; - -void reset(struct elem snake[],size_t *snake_size,int *dirc, -int*speed, int*points,int*point_s); -void o_rectangle (int x0, int y0, int width, int height); -struct elem rnd(void); - -#define MAX_SNAKE_LEN (40) -#define SNAKE_DEM (3) -#define MIN_SPEED (25) -#define MAX_SPEED (3) -#define SIZE_X (RESX) -#define SIZE_Y (RESY) - -void ram(void) -{ - int inpt,dirc,c,grows = 0,dx,dy,points,point_s=1; - size_t n = 0, snake_size = 5, speed=MIN_SPEED; - struct elem snake[MAX_SNAKE_LEN], food; - char test[512]; /* scratch space */ - o_init (test, sizeof(test)); - - reset(snake,&snake_size,&dirc,&speed,&points,&point_s); - - food = rnd(); - - while (1) - { - head: - if(!(++c % speed)) - { - - -inpt = getInputRaw(); - -dx=DoString(0,0,IntToStrX(points,2)); - dx=(SIZE_X-dx)/2; - if(dx<0) - dx=0; - dy=(SIZE_Y-getFontHeight())/2; - - lcdFill(255); - o_rectangle(1,0,SIZE_X-2,SIZE_Y-2); - o_set_gray (0); - o_fill (); - - //o_identity (); /* reset tranforms */ - - o_set_gray (50); - - setExtFont("UBUNTU29"); - - lcdSetPixel(1,1,1); - DoString(dx,dy,IntToStrX(points,2)); - - o_set_gray (255); - - - for(n=0;n SIZE_Y/SNAKE_DEM-1 || -t.x > SIZE_X/SNAKE_DEM) - { - reset(snake,&snake_size,&dirc,&speed,&points,&point_s); - goto head; - } - - for(n=0;n MAX_SPEED) --speed; - food = rnd(); - } - } - - if(!grows) - { - for(n=0;n Date: Sat, 28 Jan 2012 19:42:44 +0100 Subject: [PATCH 16/19] Fix some warnings. --- firmware/basic/basic.h | 4 ++-- firmware/l0dable/1boot.c | 2 +- firmware/l0dable/jeopardy.c | 4 +++- firmware/l0dable/jump.c | 2 +- firmware/l0dable/nick_work.c | 3 ++- firmware/l0dable/people.c | 2 +- firmware/l0dable/pongo.c | 5 ++++- firmware/l0dable/r_player.c | 12 ++++++------ firmware/l0dable/scope.c | 2 +- firmware/main.c | 5 ++++- 10 files changed, 25 insertions(+), 16 deletions(-) diff --git a/firmware/basic/basic.h b/firmware/basic/basic.h index 4025232..694e778 100644 --- a/firmware/basic/basic.h +++ b/firmware/basic/basic.h @@ -171,12 +171,12 @@ uint16_t crc16(uint8_t * buf, int len); // menu.c struct MENU_DEF { - char *text; + const char *text; void (*callback)(void); }; struct MENU { - char *title; + const char *title; struct MENU_DEF entries[]; }; diff --git a/firmware/l0dable/1boot.c b/firmware/l0dable/1boot.c index a544663..06a6063 100644 --- a/firmware/l0dable/1boot.c +++ b/firmware/l0dable/1boot.c @@ -117,7 +117,7 @@ static bool screen_overview() { while (key != BTN_ENTER) { lcdClear(); lcdPrintln("Privacy:"); - lcdPrintln(levels[GLOBAL(privacy)]); + lcdPrintln(levels[(int)GLOBAL(privacy)]); lcdPrintln(""); lcdPrintln("Nickname:"); lcdPrintln(GLOBAL(nickname)); diff --git a/firmware/l0dable/jeopardy.c b/firmware/l0dable/jeopardy.c index c3b31d1..35b0c4c 100644 --- a/firmware/l0dable/jeopardy.c +++ b/firmware/l0dable/jeopardy.c @@ -90,6 +90,8 @@ void setLeft(); void setRight(); struct packet a; +void setJeopardy(); + void ram(void) { int priv = GLOBAL(privacy); @@ -103,7 +105,7 @@ void ram(void) nrf_config_set(&config); nrf_set_strength(3); - int rnd; +// int rnd; volatile uint16_t i; while( 1 ){ diff --git a/firmware/l0dable/jump.c b/firmware/l0dable/jump.c index a83d940..e1add11 100644 --- a/firmware/l0dable/jump.c +++ b/firmware/l0dable/jump.c @@ -221,7 +221,7 @@ static void draw_platforms() { } static void draw_player() { - bool* sprite; + const bool* sprite; if(game.player_y_vel > 0) { sprite = PLAYER_SPRITE_DOWN; } diff --git a/firmware/l0dable/nick_work.c b/firmware/l0dable/nick_work.c index 2875c3d..519fa4a 100644 --- a/firmware/l0dable/nick_work.c +++ b/firmware/l0dable/nick_work.c @@ -71,11 +71,12 @@ int melody_timeout; static void init_lilakit(void); static void tick_lilakit(void); +void melody_play(void); static void mainloop(); void handler(void); void ram(void) { - timer32Callback0 = handler; + timer32Callback0 = (uint32_t) handler; /* Enable the clock for CT32B0 */ SCB_SYSAHBCLKCTRL |= (SCB_SYSAHBCLKCTRL_CT32B0); diff --git a/firmware/l0dable/people.c b/firmware/l0dable/people.c index 4f85e17..28118f6 100644 --- a/firmware/l0dable/people.c +++ b/firmware/l0dable/people.c @@ -29,7 +29,7 @@ void ram(void) { if( nrf_rcv_pkt_time(64,sizeof(buf),buf) == 16 ){ buf[14] = 0; if( buf[1] == 0x23 || buf[1] == 0x24){ - lcdPrintln(buf+6); + lcdPrintln((char*)(buf+6)); //lcdPrintln("foo"); } lcdRefresh(); diff --git a/firmware/l0dable/pongo.c b/firmware/l0dable/pongo.c index 150ea22..891c05f 100644 --- a/firmware/l0dable/pongo.c +++ b/firmware/l0dable/pongo.c @@ -113,6 +113,9 @@ void init(); ** Code Section *********************************************/ +void init(); +void ram(); + void game(void) { init(); @@ -139,7 +142,7 @@ void game(void) } } -init() +void init() { // init ball ball1.size = PONG_BALL_SIZE; diff --git a/firmware/l0dable/r_player.c b/firmware/l0dable/r_player.c index c2602df..da538ca 100644 --- a/firmware/l0dable/r_player.c +++ b/firmware/l0dable/r_player.c @@ -34,11 +34,11 @@ struct packet{ uint8_t x; uint8_t y; uint8_t flags; - uint8_t text[16]; + char text[16]; }__attribute__((packed)) text; struct nick{ uint8_t flags; - uint8_t nick[18]; + char nick[18]; }__attribute__((packed)) nick; struct nickrequest{ uint8_t reserved[19]; @@ -55,7 +55,7 @@ struct packet{ uint8_t gameFlags; uint8_t interval; uint8_t jitter; - uint8_t gameTitle[8]; + char gameTitle[8]; }__attribute__((packed)) announce; struct join{ uint16_t gameId; @@ -93,7 +93,7 @@ uint16_t gameId; uint8_t interval; uint8_t jitter; uint8_t flags; -uint8_t *gameTitle; +char *gameTitle; void sendButton(uint8_t button); void sendJoin(uint32_t game); @@ -321,7 +321,7 @@ void processNickRequest( struct nickrequest *nq) p.id= id; p.ctr= ++ctr; p.c.nick.flags = 0; - uint8_t *nick = GLOBAL(nickname); + char *nick = GLOBAL(nickname); strcpy(p.c.nick.nick, nick); nrf_snd_pkt_crc(sizeof(p),(uint8_t*)&p); } @@ -374,7 +374,7 @@ void processText(struct text *t) if( t->flags & FLAGS_CLS ) lcdClear() ; lcdSetCrsr(t->x, t->y); - t->text[16] = 0; + t->text[16] = 0; // XXX:Actually ok, beause the CRC is there. But evil! lcdPrint(t->text); lcdRefresh(); } diff --git a/firmware/l0dable/scope.c b/firmware/l0dable/scope.c index 6b44ecb..7603be6 100644 --- a/firmware/l0dable/scope.c +++ b/firmware/l0dable/scope.c @@ -116,7 +116,7 @@ void ram(void) { case BTN_RIGHT: if (kok) { xs++; xs&=63; kok=0; } break; case BTN_UP: if (kok) { ch++; ch&=7; kok=0; } break; case BTN_DOWN: if (kok) { ch--; ch&=7; kok=0; } break; - case BTN_ENTER: return 0; + case BTN_ENTER: return; default: kok=1; } } diff --git a/firmware/main.c b/firmware/main.c index e94a188..15ed254 100644 --- a/firmware/main.c +++ b/firmware/main.c @@ -4,7 +4,10 @@ #include "core/pmu/pmu.h" #include "basic/basic.h" +#include "basic/config.h" #include "lcd/render.h" +#include "lcd/print.h" +#include "usb/usbmsc.h" #include "filesystem/ff.h" @@ -34,7 +37,7 @@ void wrapper(void); -int main(void) { +void main(void) { // Configure cpu and mandatory peripherals cpuInit(); // Configure the CPU // we do it later From 1083f8aa4f9723dcf861f6ef16020393292034cd Mon Sep 17 00:00:00 2001 From: Stefan `Sec` Zehl Date: Sat, 28 Jan 2012 20:05:19 +0100 Subject: [PATCH 17/19] Save 70 more bytes! (realized this due to the memcpy-inserting cross-gcc :-) --- firmware/basic/basic.c | 2 +- firmware/lcd/display.c | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/firmware/basic/basic.c b/firmware/basic/basic.c index 51c1950..5b908df 100644 --- a/firmware/basic/basic.c +++ b/firmware/basic/basic.c @@ -18,7 +18,7 @@ void rbInit() { gpioSetDir(USB_CONNECT, gpioDirection_Output); gpioSetValue(USB_CONNECT, 1); - uint8_t ports[] = { RB_BTN0, RB_BTN1, RB_BTN2, RB_BTN3, RB_BTN4, + static uint8_t ports[] = { RB_BTN0, RB_BTN1, RB_BTN2, RB_BTN3, RB_BTN4, RB_LED0, RB_LED1, RB_LED2, RB_SPI_SS0, RB_SPI_SS1, RB_SPI_SS2, RB_SPI_SS3, RB_SPI_SS4, RB_SPI_SS5, diff --git a/firmware/lcd/display.c b/firmware/lcd/display.c index 2e60e08..5d0301d 100644 --- a/firmware/lcd/display.c +++ b/firmware/lcd/display.c @@ -166,7 +166,7 @@ void lcdInit(void) { lcd_select(); if(displayType==DISPLAY_N1200){ - uint8_t initseq[]= { 0xE2,0xAF, // Display ON + static uint8_t initseq[]= { 0xE2,0xAF, // Display ON 0xA1, // Mirror-X 0xA4, 0x2F, 0xB0, 0x10}; int i = 0; @@ -175,7 +175,7 @@ void lcdInit(void) { delayms(5); // actually only needed after the first } }else{ /* displayType==DISPLAY_N1600 */ - uint8_t initseq_d[] = { + static uint8_t initseq_d[] = { 0x36, 0x29, 0xBA, 0x07, 0x15, 0x25, 0x3f, From b9e054c08c3a79d6886979c673bed2f445399a4b Mon Sep 17 00:00:00 2001 From: Stefan `Sec` Zehl Date: Tue, 31 Jan 2012 17:49:20 +0100 Subject: [PATCH 18/19] Better start l0dable with no keys pressed. Most don't like it. --- firmware/filesystem/select.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/firmware/filesystem/select.c b/firmware/filesystem/select.c index 50e8067..d9b2f45 100644 --- a/firmware/filesystem/select.c +++ b/firmware/filesystem/select.c @@ -122,10 +122,12 @@ int selectFile(char *filename, const char *extension) } break; case BTN_LEFT: + getInputWaitRelease(); return -1; case BTN_ENTER: case BTN_RIGHT: strcpy(filename, files[selected]); + getInputWaitRelease(); return 0; } } From 8016d9ab22809741d8b81f6e2b0039d79ffb3f7b Mon Sep 17 00:00:00 2001 From: Stefan `Sec` Zehl Date: Tue, 31 Jan 2012 18:07:40 +0100 Subject: [PATCH 19/19] Allow calling "rf" from another dir. Also fix option doku. --- tools/mesh/rf | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/tools/mesh/rf b/tools/mesh/rf index 23f68b3..7445876 100755 --- a/tools/mesh/rf +++ b/tools/mesh/rf @@ -8,7 +8,8 @@ use IO::Select; use Digest::CRC qw(crcccitt); use POSIX qw(strftime); -use lib '.'; +use FindBin; +use lib "$FindBin::Bin"; use r0ket; $|=1; @@ -28,7 +29,7 @@ if ($ARGV[0] =~ /^-?-?h/){ print STDERR " - r ascii : asciidump packets\n"; print STDERR " - r beacon : parse as openbeacon\n"; print STDERR " - r mesh : parse as mesh packet\n"; - print STDERR " - r m : and show only \n"; + print STDERR " - r game : parse as game packet(incomplete)\n"; print STDERR "\n"; print STDERR "send: send packet (number) times\n"; print STDERR " - s raw : send raw hex packet\n"; @@ -39,6 +40,8 @@ if ($ARGV[0] =~ /^-?-?h/){ print STDERR "preset: config per preset\n"; print STDERR "- p m - preset minimesh\n"; print STDERR "- p b - preset openbeacon\n"; + print STDERR "- p a - preset game announce\n"; + print STDERR "- p r - preset sample game\n"; print STDERR "config: config rf chip\n"; print STDERR "- c rx - set rxmac\n"; print STDERR "- c tx - set txmac\n";