From 01e33ff31f1ba979c62dbf22325e299c39f6d31c Mon Sep 17 00:00:00 2001 From: roy rocket Date: Sun, 25 Dec 2011 15:56:38 +0100 Subject: [PATCH 01/12] Fahrplan 0.91 --- firmware/l0dable/files/fahrplan.scd | Bin 109116 -> 110551 bytes firmware/l0dable/files/fp-mini.scd | Bin 8089 -> 8166 bytes 2 files changed, 0 insertions(+), 0 deletions(-) diff --git a/firmware/l0dable/files/fahrplan.scd b/firmware/l0dable/files/fahrplan.scd index 4f890ad3fc8bc53b4150ffece7b1c0f89d99b2ac..2ae1c66b87c86d4c4a1e4d7cc74424c67dd6ae89 100644 GIT binary patch delta 2236 zcmZuye{2**6uxP1FGpK36cLXU9fZ(Q=+UG6P$02X5~yf_2qHv~x!t+Dp}RZF?rh6J zYoh(2WBE>_ecU`{dWI*(c(v) z^`-O8;}XTQ&Gn_PI_3dwB#2X-+cK#jJgPHa328GoPZcvcWohXvYVba8N{721%}6)Pl@fNADoI^# z$vzI}X+KMat+<|Tz9w8hL6mKbxaaAp=Z~yAT2z;VIt{5Ij%Q z&_|R6dj`1!ppu;QO{0=t!N#B)SFficgH<%U5dBuRNlNLm+iI$ZF&yc6A`Mz*CGB^m zot*=>q4jAK+6u~I6q8q~AmNhNh@R=fgr>#|Vs6Q_!s+{uOd^$V4& z8X>e;wrV$(b0zAH#h^XW*}lzpIKa$}s-ZA_7CH{J7J4r1p0wc6C^|`$|OcLec7V@Gt9iHGNi^J_jsRgs! zQ|;|^UgTllR6a}>e&7*bmL%y|9ByCi1Y~jSTvPe|`NWFV!_9pw@bbL&;ydT2ls7IR zhhlL+{qYzAJ69yi6T8UTSR7D0ABU}A+9)vZSxGi)alrf;?tOfWB#I4}CI?e`$f`Kt zj%`Bd+T#R&(#m^#$WW{Spo_L5RccYHIC}Y>a>sgNY7GGWOAogn=m@s=K=AXM$SbuP zV56D9+(N=%p?zD(k3<8Y>@9EKN-~-j&5$uC_?B1Bf9GVjrpaCs?F(9aVGn3m_L3Qz zHs+9}yUN=g(xJtpePpmemd`Ivd#0&;!6!4K+R|O*`at<=p19FCoIO7X$H7&NB!a=+ zWSe$?S`bW|PVPeT zGkZy)wxRU^*&T#u^VTPmYlDTD>KEWz`*R3pe|)&`8BB zjYL@n_989e3TXstvD7W7l(GmaA~LcMu!tVQhpdN!9;$n%nwK-@{D0?v?mhR_f^d6I zKnBU>kwPfj5UjuEx?-du_QsgQ8~kca5ckKiyw#G$uUN8hWfrc&&K1iJd7UC@(T-$; z8jN|@giyjo3m3L>&oh|lrqX#^?2ffoFm>x4gITn$b%t%s>_^5uUVG{_#b&dY+q7HR zrr5kU7>6B|z-y1UI%6&6O^M9+<-R@o@Vw^!B-Ted`t;m;raF=3!{JE-JLHz(XCmWQ zj}GUsc>T!}fyL7=%mU*=uc!35>HS-t{bwaSLX;pKYhWo( z#1<~m38^j|?*bjnb-^G)2iC%f2j5lx*4`=5Ac(0hkT*cFqTQKhS0wf8At;zeJn*HE zR@p*krmal)=7kG_NZI<$4EL7W$Yd$(5JUJqC8-tb`gQQl_Dj)dCYB;pkA#+uY z0X5jDI@lMi=gI>?weeU<+fl9XVbYDmunZw;6>THtQDQR(HWrKQsCrwUN0# z*ek@R^ng5|A5W3+d*`Bu#LYL7@*^ePz^GMj?gcSV=LNJ6x+A|(zGwn{W#nUTP zZYy%^RF4PL6I$V@l{~=E%_G{~8X;v7m_;JRtx+~RufR^+qtL^fTO)9PT=$p%ZFPPO z&IwM+m0Z^AZcl!$> CttANn diff --git a/firmware/l0dable/files/fp-mini.scd b/firmware/l0dable/files/fp-mini.scd index 67ca10c5be4d58405d41073270286b66e2307e1b..26e8d002b637d1e23526bee9368d1a3d7591d2b0 100644 GIT binary patch delta 831 zcmZ9IUq}>D6vpq2*Bp0dZQFMK?#%AQCgsY?%W=J;9oibXG9HN#P49nTR5Z@OA!<^63QEqiMU9P#ozA;8gk zu~wxSKKgoSQ$~D1lD8_}=TSmNsaw*$whODJ0jt&o>yI^_P*g0s@VL@|Nz*7i zuGDXpBHmKa3b<;&G^(Ozjcw+pfHP!xsvg8EDw=>zwF8rtYsaKz4b4`>{cHr?wO&t1gj{2K()p*4=nVpavj!OgEj2p4)SEG(CgG>feo`}H zn7l4Q)?luE#x7yfKyDc2(o?^6xM#HEB?AGh8-19ltI!obB0w1JH3L>CBeX(6P<$zlif}Ghel}(hin3_z(laLIHW(*T<48EJpRgh@M|g@ipm0^ND!A+jk#Qk#{K}R3*V0b delta 717 zcmXAmOK1~O6o$`C?%1?>n2yQJ+{sLm)`cVYzl=Gtqaj8E?kuw zU6xQjz3L0IwmVz6Ff;)*&s6ugJ+NCbyJ(JD-Ip_cWb6>wkRz?&#lg?+B zlp}IwdMRC`wYn@{nL$HZ#|*Arz(7t;J)i* zGq~5y@t>6PRaK(5sQnW_LiOm|ziq9>dA81fH(N&U28{Uws zo83Ao{^+?xhZ^#|5ZOl4w|VGf%V%;s>(;CR*SXZsvxv1YpG z-7xzU0qmH#WnT8qnlKiHLLP0^!inf=m42)A-k63rlv=FOWJl5>7sYy_$h9?J-3l zO&eRbMeiAm#hF0T=)}%>n>IX&QT`;e@L6n}rDNd1y_owmq4*iEaEoyQMh#BsJMom{ N!PR)eebUW%-+zVb$i)Bv From 43b1e47247587021765e126fc94df3fce17e5b93 Mon Sep 17 00:00:00 2001 From: Stefan `Sec` Zehl Date: Sun, 25 Dec 2011 18:40:32 +0100 Subject: [PATCH 02/12] Add smartflash utility set --- tools/smartflash/flash | 3 + tools/smartflash/mass | 52 ++++++++++++ tools/smartflash/smartflash | 153 ++++++++++++++++++++++++++++++++++++ 3 files changed, 208 insertions(+) create mode 100755 tools/smartflash/flash create mode 100755 tools/smartflash/mass create mode 100755 tools/smartflash/smartflash diff --git a/tools/smartflash/flash b/tools/smartflash/flash new file mode 100755 index 0000000..6108c29 --- /dev/null +++ b/tools/smartflash/flash @@ -0,0 +1,3 @@ +#!/bin/sh +dd if=firmware.bin seek=4 of=/dev/$1 2>/dev/null +echo "FLASH done: $1" diff --git a/tools/smartflash/mass b/tools/smartflash/mass new file mode 100755 index 0000000..0f3d1e8 --- /dev/null +++ b/tools/smartflash/mass @@ -0,0 +1,52 @@ +#!/bin/sh + +dev=$1 +dir=/tmp/r0ket + + +set -e + +if [ ! -d $dir ] ; then + mkdir $dir +fi + +if [ ! -d $dir/$dev ] ; then + mkdir $dir/$dev +fi + +umount /dev/$dev 2>/dev/null || true +./generate-keys +mount /dev/$dev -t vfat $dir/$dev +cp files/* $dir/$dev +cp \ + 1files/invaders.c0d \ + 1files/mandel.c0d \ + 1files/r_player.c0d \ + 1files/jump.c0d \ + 1files/bricks.c0d \ + 1files/rockets.c0d \ + 1files/fahrplan.c0d \ + 1files/r0type.c0d \ + 1files/beaconid.c0d \ + 1files/people.c0d \ + 1files/starfld.c0d \ + 1files/static.c0d \ + 1files/sendcard.c0d \ + 1files/recvcard.c0d \ + 1files/showcard.c0d \ + 1files/pongo.c0d \ + 1files/minichat.c0d \ + 1files/blink.c0d \ + 1files/pwgen.c0d \ + 1files/showlcd.c0d \ + 1files/tedliz.c0d \ + 1files/leiwand.c0d \ + 1files/scope.c0d \ + 1files/Geigerct.c0d \ + 1files/voltage.c0d \ + files/* \ + $dir/$dev +#sync +#ls -l $dir/$dev +umount /dev/$dev +echo "MASS done: $dev $dir" diff --git a/tools/smartflash/smartflash b/tools/smartflash/smartflash new file mode 100755 index 0000000..69a8916 --- /dev/null +++ b/tools/smartflash/smartflash @@ -0,0 +1,153 @@ +#!/usr/bin/perl + +use strict; +$|=1; + +my $DEV="/sys/bus/usb/devices"; + +sub getline{ + my($path)=@_; + open(my $f,"<",$DEV."/".$path) || do { +# print "failed opening $path: $!\n"; + return ""; + }; + my $l=<$f>; + close($f); + chomp($l); + return $l; +}; + + +my %found; +my %done; + +sub gosub { + my ($dev,$grep)=@_; + my $dh; + my $dir; + opendir($dh, $DEV."/".$dev) || do { +# print "Failure for $dev?\n"; + return ""; + }; + ($dir)=grep {/$grep/} grep {/^[^.]/} readdir($dh); + if($dir eq ""){ + return ""; + }; + close $dh; + $dev.="/".$dir; + return $dev; +}; + + + + +sub getdev{ + my ($dev)=@_; + my $dh; + my $dir; + + $dev=gosub($dev,":1"); + $dev=gosub($dev,"^host"); + $dev=gosub($dev,"^target"); + $dev=~/target(.*)/; + $dev=gosub($dev,$1); + $dev=gosub($dev,"^block"); + $dev=gosub($dev,"."); + $dev=~m!/([^/]*)$!; + my $r=$1; + if($r!~/^sd/){ +# print "Strange device? $dev -> $r\n"; + return ""; + }; + return $r; +}; + +my %pids; +use POSIX ":sys_wait_h"; + +my $kid; +$SIG{CHLD}=sub { + do { + $kid = waitpid(-1, WNOHANG); + delete $pids{$kid}; + }while $kid>0; +}; + +sub dwim{ + my($dev)=@_; +# print ("checking $dev\n"); + my $pr=getline($dev."/idProduct"); + return -1 if($pr eq ""); + my $ve=getline($dev."/idVendor"); + my $mf=getline($dev."/manufacturer"); +# print "$pr:$ve\n"; + if("$ve:$pr" eq "16c0:08ac") { + return 1 if $done{$dev}==1; + my $sdev=getdev($dev); + if ($sdev eq ""){ + print "$dev not ready.\n"; + return 1; + }; + print "Mass storage $dev -> $sdev\n"; + + my $pid = fork(); + if (not defined $pid) { + die "fork failed\n"; + } elsif ($pid == 0) { + system("./mass $sdev"); + exit(0); + } else { +# print "IM THE PARENT $pid\n"; + $pids{$pid}=1; +# print join(",",%pids),"\n"; +# print scalar keys %pids; +# print "\n"; + } + $done{$dev}=1; + return 1; + }; + if("$ve:$pr" eq "04cc:0003") { + return 1 if $done{$dev}==2; + my $sdev=getdev($dev); + if ($sdev eq ""){ + print "$dev not ready.\n"; + return 1; + }; + print "flash $dev -> $sdev\n"; + system("./flash $sdev"); + $done{$dev}=2; + return 1; + }; + return -1; +}; + +my %disable; +while(1){ + opendir(my $dh, $DEV); + my @paths=readdir($dh); + close $dh; +# print "f: ",join(",",@files),"\n"; +device: + for my $path (@paths){ + next if ($disable{$path}); + next if $path =~ /^usb/; + next if $path =~ /:/; +# print "p $path\n"; + $found{$path}=1; + my $res=dwim($path); + if($res==-1){ + print "Disabling: $path\n"; + $disable{$path}=1; + }; + }; + for my $a (keys %done){ + if (!$found{$a}){ + delete $done{$a}; + print "$a vanished\n"; + }; + }; + %found=(); +# print "\n"; + sleep(1); + print scalar(keys %pids),"\r"; +}; From 3f1b4593aad9067de053256ad98251eea80cd81d Mon Sep 17 00:00:00 2001 From: Stefan `Sec` Zehl Date: Sun, 25 Dec 2011 18:52:19 +0100 Subject: [PATCH 03/12] Mini makefile and small doku --- tools/smartflash/Makefile | 18 ++++++++++++++++++ tools/smartflash/README | 23 +++++++++++++++++++++++ 2 files changed, 41 insertions(+) create mode 100644 tools/smartflash/Makefile create mode 100644 tools/smartflash/README diff --git a/tools/smartflash/Makefile b/tools/smartflash/Makefile new file mode 100644 index 0000000..47a2162 --- /dev/null +++ b/tools/smartflash/Makefile @@ -0,0 +1,18 @@ +setup: + cd ../../firmware && make clean && make && make l0dables + cp ../../firmware/firmware.bin . + -mkdir files 1files + cp ../../firmware/l0dable/*c0d 1files + cp ../../firmware/l0dable/*nik files + cp ../../firmware/l0dable/*int files + cp ../../firmware/l0dable/files/* files + cd ../crypto && make clean && make generate-keys + cp ../crypto/generate-keys . + @echo + @echo Now run ./smartflash + +clean: + rm firmware.bin generate-keys + rm -rf files 1files + + diff --git a/tools/smartflash/README b/tools/smartflash/README new file mode 100644 index 0000000..8140912 --- /dev/null +++ b/tools/smartflash/README @@ -0,0 +1,23 @@ +smarflash recognizes r0kets in firmware flash or mass storage flash mode and flashes them to factory defaults with a new generated random crypto key. + +Runs only under linux (sorry, but requires /sys/... stuff) + +You NEED to disable your automounter and run it as root. + +Disabling automounter on ubuntu 10.4: + run gconf-editor + apps > nautilus > preferences + + media_automount = OFF + media_automount_open = OFF + media_autorun_never = ON + +run "make setup" to generate/gathe the necessary files +then run "./smarflash" and flash away. + + +TODO ideas: +- keep cryptokey if already there. +- ability to format if not? Or somehow force formatting? +- fix broken FS: save config/keys // reformat // copy back + From f70fb16ee4cd49c669112e49e71d873726cdd246 Mon Sep 17 00:00:00 2001 From: Stefan `Sec` Zehl Date: Sun, 25 Dec 2011 19:31:18 +0100 Subject: [PATCH 04/12] Forgot fonts. Whoops. --- tools/smartflash/Makefile | 3 +++ 1 file changed, 3 insertions(+) diff --git a/tools/smartflash/Makefile b/tools/smartflash/Makefile index 47a2162..79b8c25 100644 --- a/tools/smartflash/Makefile +++ b/tools/smartflash/Makefile @@ -6,6 +6,9 @@ setup: cp ../../firmware/l0dable/*nik files cp ../../firmware/l0dable/*int files cp ../../firmware/l0dable/files/* files + cp ../font/binary/*f0n files + cp ../image/lcd/*lcd files + cp ../image/lcd/i42.lcd files/nick.lcd cd ../crypto && make clean && make generate-keys cp ../crypto/generate-keys . @echo From 6dddb7639eca1b512fe555c42204c1afeaaa8d83 Mon Sep 17 00:00:00 2001 From: Stefan `Sec` Zehl Date: Sun, 25 Dec 2011 20:02:41 +0100 Subject: [PATCH 05/12] Add propagation test packet --- firmware/funk/mesh.c | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) diff --git a/firmware/funk/mesh.c b/firmware/funk/mesh.c index 8b9391b..f0ef254 100644 --- a/firmware/funk/mesh.c +++ b/firmware/funk/mesh.c @@ -19,9 +19,9 @@ MPKT meshbuffer[MESHBUFSIZE]; struct NRF_CFG oldconfig; -static int meshgen_gt(char gen){ - unsigned char dif=meshgen-gen; - if(meshgen==0) +static int mesh_gt(char curgen, char newgen){ + unsigned char dif=curgen-newgen; + if(curgen==0) return 1; return (dif>128); }; @@ -53,6 +53,7 @@ int mesh_sanity(uint8_t * pkt){ }; if(MO_TYPE(pkt)!='A' && MO_TYPE(pkt)!='a' && + MO_TYPE(pkt)!='B' && MO_TYPE(pkt)!='E' && MO_TYPE(pkt)!='F' && MO_TYPE(pkt)!='G' && @@ -213,7 +214,7 @@ uint8_t mesh_recvqloop_work(void){ // New mesh generation? if(MO_TYPE(buf)=='T'){ - if(meshgen_gt(MO_GEN(buf))){ + if(mesh_gt(meshgen,MO_GEN(buf))){ meshgen=MO_GEN(buf); _timet=0; meshincctr=0; @@ -241,6 +242,15 @@ uint8_t mesh_recvqloop_work(void){ // Store packet in a same/free slot MPKT* mpkt=meshGetMessage(MO_TYPE(buf)); + // Propagation test + if(MO_TYPE(buf)=='B'){ + if(! mesh_gt(MO_BODY(mpkt->pkt)[0],MO_BODY(buf)[0]) ) + return 0; + (*( + (uint32_t*)(MO_BODY(buf)+6) + ))++; + MO_TIME_set(mpkt->pkt,0); + }; #if 0 // Schnitzel if(MO_TYPE(buf)=='Z'){ From 03425fb0789eda43724287a908b8e74bcf6964d9 Mon Sep 17 00:00:00 2001 From: Stefan `Sec` Zehl Date: Sun, 25 Dec 2011 20:03:57 +0100 Subject: [PATCH 06/12] Sort debug loadable on top --- tools/smartflash/mass | 1 + 1 file changed, 1 insertion(+) diff --git a/tools/smartflash/mass b/tools/smartflash/mass index 0f3d1e8..cf7a3cd 100755 --- a/tools/smartflash/mass +++ b/tools/smartflash/mass @@ -44,6 +44,7 @@ cp \ 1files/scope.c0d \ 1files/Geigerct.c0d \ 1files/voltage.c0d \ + files/debug.int \ files/* \ $dir/$dev #sync From f7e016e8462657fe6c9f43c00eb6f6e018f7aa50 Mon Sep 17 00:00:00 2001 From: roy rocket Date: Sun, 25 Dec 2011 20:04:52 +0100 Subject: [PATCH 07/12] Neue Fahrplanordnung --- firmware/l0dable/files/fahrplan.scd | Bin 110551 -> 111131 bytes firmware/l0dable/files/fp-mini.scd | Bin 8166 -> 8261 bytes 2 files changed, 0 insertions(+), 0 deletions(-) diff --git a/firmware/l0dable/files/fahrplan.scd b/firmware/l0dable/files/fahrplan.scd index 2ae1c66b87c86d4c4a1e4d7cc74424c67dd6ae89..ad926e6ec2c417c57fb091230fc1fcd19947b999 100644 GIT binary patch delta 2252 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 DB?R*$ diff --git a/firmware/l0dable/files/fp-mini.scd b/firmware/l0dable/files/fp-mini.scd index 26e8d002b637d1e23526bee9368d1a3d7591d2b0..316d0f99f3cb224b1902f1059a041254a664df8c 100644 GIT binary patch delta 1538 zcmY+ETWl0%6vxlrI$w8ocXrS0ZfCZ$?Vzc&SYT(nlxr=tTUx5L&;%;dkk*=FW7|bq z8e>q10Uufvm(vIeX^|LBjbcfBP!k1>kO)e|nD|1_CSHh`fQcB?fSzxK5a;pt|D7`@ z-|eUR(4C`-iVW@s7h4mEWjl<9dI?M zi%<$}9@!)uwCJ*Djk-YR6s8Jnzh=_9qWQwnrSyY`mU`>NB+7J=moB>2C@&ym*h9~F zTSOk2!gVk0E$SE75cYVX!$2MddMfCEvB zrrnjHUy(z2Ng_M#&_Yj~YJ7Fdmnb!rmMSBm23_Wxm4Z@3HYVs#uDpPtDscP`&Ko9u zqg0D0QK}&F;a24{l=*6E6ZPUKGK52d2Gv&eIfT^$E(*w|^EXX8A#72N974L7PO5F9 zN|)iTVyf4g)MLmP&K0vvbxDgdfeN(+IfWL#WJ$E>hS(^sqLilm)D!6NarC>N-Vdw| z9p(k}LzBv??bP!4ChaJmCmux>;B}RP!A|iwO2HGLeOjlg=!~H`AbZbp?=!_oQHPwu zSbzqC%LSoKX9ILaYgbPpV^|rK_IECe{Qf11jhw<59S=5!Uq%_;kh$$FsY%gpUzE0l zTh&G`48l-I7N*=L_4zy0b12O-1$HZLQY@4ayHH9M8qI_|MHXfHtVXB&>&0ed47W5| zA9_k;kTGywy64 z()ma>{G&uLh>)$Z9q0DI|CB8AA)j}o2aF~$g)+ZSr?;Yyi7|;`Sf>OwX?rAw5A;HD zCPgO$F-pfOe8V~c(Yi6Okp}sv&Iu@8$xXyq9y!q-U*XB^=9!lathrg^lm&G zeh+0jBZa$LvCXU&`;iq;40=Ov7kwy|afAMj?+mX)#_+8nOVX*^i*d@V6tD0U2Gp8# zQ|}a?qEucrX;(>?IL~94@S923%y!|{8AE-7x}vK?A0uPfnM5K7#qGidfdV|--g3hEA3O|?0ZZ8^1I$b_Ty+?=1GDw$8Hp}QZ`5GTT|~P|9P_v9cEJYrf^>0QMceN{KZN^+3~TZeX;3Xsg}3V|XMtX!qs@ l2X_qh_x6nR=Z5TU+jAqi-rT^jeAWN=-K)!g08q-R`xiDrZ*Bkp delta 1489 zcmX|>ZERCz6vxl{vU|GQ_O|D)FL%3bH_76dytG|mxOGfMCv3tt1zCm!jR;7LFQCyV z2n0bB!eX{VL?VI`<1hgMgUTlqlteHRn-~*=$_Jt$NEl*BG|}ieoq9k1{=et#oaeb` z@A|nb;>pgqGq=qP>j~sr4*ZePXEfS?05?ai-TvhO#j4Rm-R35On*ckjpp@gB?eLFP zE!bpB2;WrkK2JC9Crz6?e9ha7H%KsS^YCB3`^~K+7|I?UnzdXus++BDTT*EB3Tw!> zX8A@i$$4X{wSrWX4GGWX3p_8AS0osY7&>J> zS74p;MD>tWCNV%t{O{QtDaKojnK(`=FFRJXmv|Uvhtl$7>ej!z2tI3Grfc2s=qIjE8t2*kLx1VE8qpJIy3q zUK^Sc{*okx-mos4&vJh#&ST+1$GD&3J*tfb(3Atn^K@VKrZfmT)J*`6xU{Jj3n@e@#FH-x8Es8*;Px zZzs-kYnPa9Bm%VBf;k*?`GeSO?5}wHZ9X1fg|Al9TQ;9e4B%dZ{WdJE2lyHr-Bo5Cd*h+4~Gb9);CU~y10)L7MhS^E3 zqh)w80WT%>NS%Q!A0o1jkVNpEGC6&g_0D@@c`TBOiyWRCe=K~0)Y#`#ByE7huOz0L zgCqi6QOxDA!$*_N)&)|pt4`Jb-qtCn)jCBg?wI6q1sW;IYwA|v%cL+@&nN32GJhvH zR|i}Vr9$Nmxv36pmVZS({7}zkx*Kn^HEnizB0V3c*n;74c{~lBxPt`4b(hO^&*S$b z81gA@aEtg$R4{B#@o~3gye>~X1y^`wYK?Dm3R?J!REIexdrQH_v@WZ^t!L6Lc)JZP wX}Fr^_RLyy6=^z{Q6WVxudnYi@319>H!DnwxyL2zX;MkPQsMt%o=G?T18HYmO#lD@ From 6cb9845b63ffcde128164468cf73b793e3922228 Mon Sep 17 00:00:00 2001 From: roy rocket Date: Sun, 25 Dec 2011 20:12:04 +0100 Subject: [PATCH 08/12] Reduced delay in Fahrplan, V0.003 --- firmware/l0dable/fahrplan.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/firmware/l0dable/fahrplan.c b/firmware/l0dable/fahrplan.c index 955d77d..d91de21 100644 --- a/firmware/l0dable/fahrplan.c +++ b/firmware/l0dable/fahrplan.c @@ -61,7 +61,7 @@ void ram(void) { lcdClear(); DoString(0,0,"Fahrplan "); DoString(60,0,favers); - DoString(0,16,"SW Rel. V0.002"); + DoString(0,16,"SW Rel. V0.003"); if(filvers!=2) { DoString(0,24,"Incompatible "); DoString(0,32,"Binary. Get "); @@ -76,11 +76,11 @@ void ram(void) { } DoString(0,24,"On C3 get new "); DoString(0,32,"version from "); - DoString(0,40,"r0ket.de for "); - DoString(0,48,"better UI "); + DoString(0,40,"r0ket.de "); + DoString(0,48," "); /* DoInt(0,24,filvers); */ lcdDisplay(); - delayms(1000); + delayms(100); DoString(0,56," PRESS BUTTON "); lcdDisplay(); getInputWait(); From 52085b91b5309ece93a315b9857cd3d9eb75d505 Mon Sep 17 00:00:00 2001 From: Stefan `Sec` Zehl Date: Sun, 25 Dec 2011 20:15:42 +0100 Subject: [PATCH 09/12] add rudimentary release version support --- firmware/l0dable/debug.c | 16 +++++++++++++--- firmware/l0dable/system-include-hack.h | 1 + firmware/main.c | 4 ++++ 3 files changed, 18 insertions(+), 3 deletions(-) diff --git a/firmware/l0dable/debug.c b/firmware/l0dable/debug.c index 66c7b3f..02b9042 100644 --- a/firmware/l0dable/debug.c +++ b/firmware/l0dable/debug.c @@ -26,17 +26,19 @@ void getsp(void); void uptime(void); void uuid(void); void lcdrtest(void); +void release(void); static const struct MENU submenu_debug={ "debug", { { "ChkBattery", &ChkBattery}, { "ChkLight", &ChkLight}, { "MeshInfo", &m_time}, { "ChkFunk", &ChkFunk}, - { "Qstatus", &Qstatus}, +// { "Qstatus", &Qstatus}, // { "ShowSP", &getsp}, - { "lcdrtest", &lcdrtest}, + { "LcdRead", &lcdrtest}, { "Uptime", &uptime}, { "Uuid", &uuid}, + { "Release", &release}, {NULL,NULL} }}; @@ -126,7 +128,7 @@ void uuid(void) { lcdPrintln(IntToStrX(iap_return.Result[2],8)); lcdPrintln(IntToStrX(iap_return.Result[3],8)); lcdNl(); - lcdPrintln("Beacon ID:"); + lcdPrintln("Bacon ID:"); lcdPrintln(IntToStrX(GetUUID32(),8)); lcdRefresh(); while(!getInputRaw())work_queue(); @@ -331,3 +333,11 @@ void lcdrtest(void){ lcdRefresh(); while(!getInputRaw())delayms(10); }; + +void release(){ + lcdPrint("r0ket"); + lcdPrint("Release: "); + lcdPrintln(IntToStrX(getrelease(),8)); + lcdRefresh(); + while(!getInputRaw())work_queue(); +}; diff --git a/firmware/l0dable/system-include-hack.h b/firmware/l0dable/system-include-hack.h index f1f77e5..29ea22f 100644 --- a/firmware/l0dable/system-include-hack.h +++ b/firmware/l0dable/system-include-hack.h @@ -2,3 +2,4 @@ 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); +int getrelease(); diff --git a/firmware/main.c b/firmware/main.c index 70f4b88..538f541 100644 --- a/firmware/main.c +++ b/firmware/main.c @@ -75,3 +75,7 @@ int main(void) { wrapper(); // see module/ subdirectory } + +int getrelease(void){ + return 0x00000104; +}; From 8f93286de9a3f5e5e98a3516ac8ec224c815b0bf Mon Sep 17 00:00:00 2001 From: Stefan `Sec` Zehl Date: Sun, 25 Dec 2011 20:48:38 +0100 Subject: [PATCH 10/12] forgot EXPORTS in last commit (and a newline) --- firmware/l0dable/EXPORTS | 1 + firmware/l0dable/debug.c | 4 ++-- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/firmware/l0dable/EXPORTS b/firmware/l0dable/EXPORTS index 5f586d3..4ff2c34 100644 --- a/firmware/l0dable/EXPORTS +++ b/firmware/l0dable/EXPORTS @@ -136,4 +136,5 @@ o_fill o_set_shader o_identity o_transform +getrelease #Add stuff here diff --git a/firmware/l0dable/debug.c b/firmware/l0dable/debug.c index 02b9042..263eb68 100644 --- a/firmware/l0dable/debug.c +++ b/firmware/l0dable/debug.c @@ -335,8 +335,8 @@ void lcdrtest(void){ }; void release(){ - lcdPrint("r0ket"); - lcdPrint("Release: "); + lcdPrintln("r0ket"); + lcdPrintln("Release: "); lcdPrintln(IntToStrX(getrelease(),8)); lcdRefresh(); while(!getInputRaw())work_queue(); From 709319048bcb0b61e864591045865fd2f3874c19 Mon Sep 17 00:00:00 2001 From: Stefan `Sec` Zehl Date: Sun, 25 Dec 2011 20:51:01 +0100 Subject: [PATCH 11/12] Very undocumented bridge-based mesh packet generator. Needs work --- tools/mesh/dbg.pl | 187 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 187 insertions(+) create mode 100755 tools/mesh/dbg.pl diff --git a/tools/mesh/dbg.pl b/tools/mesh/dbg.pl new file mode 100755 index 0000000..399349b --- /dev/null +++ b/tools/mesh/dbg.pl @@ -0,0 +1,187 @@ +#!/usr/bin/perl +# +# vim:set ts=4 sw=4: + +use strict; + +use IO::Select; +use Digest::CRC qw(crc16 crcccitt); + +$|=1; + +my @fh; +my $read; + +sub sprint{ + my @str=split(//,shift); + for (@str){ + if (ord($_)>30 && ord($_)<127){ + print $_; + }else{ + print "[x",unpack("H*",$_),"]"; + }; + }; +}; + +my $ser=shift || "/dev/ttyS3"; + +open(SER, "+<",$ser) || die "open: $!"; + +my $sel = IO::Select->new; + +$sel->add(\*SER); + +my $cmd=shift; + +if($cmd =~ /^r/){ + $cmd=~s/r//; + $cmd+=1; + my $fmt=shift; + while($cmd-->0){ + my $read=""; + while($read !~ /\\1.*\\0/){ + my $rr=""; + if (@fh = $sel->can_read(100)) { + sysread($fh[0],$rr,1024); + $read.=$rr; + } + }; + print "Read: <"; sprint $read; print ">\n"; + $read =~ s/^\\1//; + if($fmt eq "m"){ + print "M [",substr($read,0,1),"] "; + print "g=",unpack("C",substr($read,1,1))," "; + print "t=",unpack("N",substr($read,2,4))," "; + print "beacon=",unpack("H*",substr($read,26,4))," "; + print "\n"; + }; + my $cs=substr($read,0,30); + my $crc=substr($read,30,2); + print unpack("n",$crc),"<>"; + print crcccitt($cs),"\n"; + }; +}elsif ($cmd eq "mt"){ + my $par=pack("H*",shift); + print "Write: <"; sprint $par; print ">\n"; + syswrite(SER, '\3'.$par.'\0'); +}elsif ($cmd eq "mta"){ + my $par=shift; + print "Write: <"; sprint $par; print ">\n"; + print "len: ",length($par),"\n"; + syswrite(SER, '\3'.$par.'\0'); +}elsif ($cmd eq "mr"){ + my $par=pack("H*",shift); + print "Write: <"; sprint $par; print ">\n"; + syswrite(SER, '\4'.$par.'\0'); +}elsif ($cmd eq "mra"){ + my $par=shift; + print "Write: <"; sprint $par; print ">\n"; + syswrite(SER, '\4'.$par.'\0'); +}elsif ($cmd eq "ch"){ + my $par=pack("H*",shift); + print "Write: <"; sprint $par; print ">\n"; + syswrite(SER, '\5'.$par.'\0'); +}elsif ($cmd eq "len"){ + my $par=pack("H*",shift); + print "Write: <"; sprint $par; print ">\n"; + syswrite(SER, '\6'.$par.'\0'); +}elsif ($cmd =~ /^S/){ + $cmd=~s/S//; + $cmd+=1; + + my $par=""; + my $scmd=shift||"t"; + if($scmd eq "t"){ + $par.="T"; + $par.=chr(shift); #gen + $par.=pack("N",scalar(time)+1*60*60); + + $par.=pack("N",0); + $par.=pack("N",0); + $par.=pack("N",0); + $par.=pack("N",0); + $par.=pack("N",0); + $par.=pack("N",0); + }elsif($scmd eq "a"){ + $par.="A"; + $par.=chr(shift); #gen + $par.=pack("N",scalar(time)+1*60*60+ 300); + + $par.= pack("C",shift||0); + $par.= pack("C",0); + $par.= pack("C",0); + $par.= pack("C",0); + + $par.=pack("N",0); + $par.=pack("N",0); + $par.=pack("N",0); + $par.=pack("N",0); + $par.=pack("N",0); + }elsif($scmd eq "b"){ + $par.="B"; + $par.=chr(shift); #gen + $par.=pack("N",scalar(time)+1*60*60+ 300); + + $par.= pack("C",shift||0); + $par.= pack("C",0); + $par.= pack("C",0); + $par.= pack("C",0); + + $par.=pack("N",0); + $par.=pack("N",0); + $par.=pack("N",0); + $par.=pack("N",0); + $par.=pack("N",0); + }else{ + die; + }; + + $par.=pack("n",crcccitt($par)); + print "Write: <"; sprint $par; print ">\n"; + while($cmd-->0){ + syswrite(SER, '\1'.$par.'\0'); + print "len: ",length($par),"\n" if($cmd==0); + + my $read=""; + while($read !~ /\\2.*\\0/){ + my $rr=""; + if (@fh = $sel->can_read(100)) { + sysread($fh[0],$rr,1024); + $read.=$rr; + } + }; + + if($cmd==0){ + print "Send: <"; sprint $read; print ">\n"; + }; + }; +}elsif ($cmd =~ /^s/){ + $cmd=~s/s//; + $cmd+=1; + my $par=pack("H*",shift); + $par.=pack("n",crcccitt($par)); + print "Write: <"; sprint $par; print ">\n"; + while($cmd-->0){ + syswrite(SER, '\1'.$par.'\0'); + print "len: ",length($par),"\n"; + + my $read=""; + while($read !~ /\\2.*\\0/){ + my $rr=""; + if (@fh = $sel->can_read(100)) { + sysread($fh[0],$rr,1024); + $read.=$rr; + } + }; + + print "Send: <"; sprint $read; print ">\n"; + }; +}else{ +die; +}; + +if (@fh = $sel->can_read(10)) { + sysread($fh[0],$read,1024); +} +print "PostRead: <"; sprint $read; print ">\n"; + From e94680838d4aab47aaf0d3ca1507ee16edc97cee Mon Sep 17 00:00:00 2001 From: roy rocket Date: Mon, 26 Dec 2011 10:17:30 +0100 Subject: [PATCH 12/12] Fahrplan 0.92. Bug in l0dable fixed, now more than 128 lines desc possible... --- firmware/l0dable/fahrplan.c | 4 ++-- firmware/l0dable/files/fahrplan.scd | Bin 111131 -> 113184 bytes firmware/l0dable/files/fp-mini.scd | Bin 8261 -> 8447 bytes 3 files changed, 2 insertions(+), 2 deletions(-) diff --git a/firmware/l0dable/fahrplan.c b/firmware/l0dable/fahrplan.c index d91de21..a3248c4 100644 --- a/firmware/l0dable/fahrplan.c +++ b/firmware/l0dable/fahrplan.c @@ -28,7 +28,7 @@ void ram(void) { char buf[20]; int line; - char startline=0; + int startline=0; char *message=NULL; char filvers; char favers[5]; @@ -61,7 +61,7 @@ void ram(void) { lcdClear(); DoString(0,0,"Fahrplan "); DoString(60,0,favers); - DoString(0,16,"SW Rel. V0.003"); + DoString(0,16,"SW Rel. V0.004"); if(filvers!=2) { DoString(0,24,"Incompatible "); DoString(0,32,"Binary. Get "); diff --git a/firmware/l0dable/files/fahrplan.scd b/firmware/l0dable/files/fahrplan.scd index ad926e6ec2c417c57fb091230fc1fcd19947b999..5e6541ac5b9f534907ee600c7fe3288ea1d89a16 100644 GIT binary patch delta 3454 zcmZu!4R93I9p87kw;quA1;~d%AE-ni$=u~o5X)f92?bPQ6cw$?=I-6yn!Vj+cQ2Pf z<)VO~VzF6u4cd%ahaxxvF73*UqgDqQI$~*ycAQabTWlS*oz{c*Oy;v{>x zH)l>jy2zAp{M1w&*l_V#OHLNxZOucf_&YoOcHOu~PFLb-<%bt3nN;x4d8G0D_OfS{ zG*8d6cB5c9x>qc*rDiWTJ>4={1>c#*mUOQ4wX-G!uk9h@tE;Rss{qKEYvsL)=I~Y~ z&OGjV-#O|rtqLpR*Rvot45sIqSN!H8(_L1voF3gQw6YNWzIaq@gK~mhzTaLg^XET;?lM7cn9joAIr4pnw zni+R(p4Bx2YG-t44*bxe_5Wen`5jBDowJ$+Z;jbjg**AO0q-nBTFE*bp%i3CA|rX` zps-+yW4qYz>RHWTR`;zu>$$D$YR*Rk1lAo(IvKCIDZMPa;#SAXOglp|WFFWI4Kd?P zmpNj3Nh@%c*A4jXN)GTm_-ZeiIJJqTGl)-#I~ojSG_$~+1*|>mm4o&BNGdUWx^mJy zMY+U3WnQDGmzH^&N>Ldb7l;1Bs#>pHqO@FrI$^2#Y5%_AiD5dkMWq`TE62P17ne1P z`g>>D{j>ofdzHYoCDTd&(AcxX;m*}+{qZj4?3+f8#dTp~`gL3D5&*xo8Up{uV~yc& zZWyYgz#Yzo*3IwNB_O%92f`qgBU8kcwcXdM4Tp2eQbX!WCzJl_W0U+(i+`p7zHa+( z>5}~yx*n$h-R}8CQ=Z&u-c>j5bz3=Uoswx|sg(cai&Mh1)2-6mJ!SZ|aC_fij6!(M zK$u!L5NjB|P0=?=XxrQig3ci_A^h!a=TUmjfb!8M|HK{ZDa32HhSd#ssfmv^DWCiZ z;2@PCjbZcMD`WL*w<@~^<^8$IV8sxb?7ws5r0}V&Tk9yG7eC-HyifAF@jf#~fqZ3q z_}bu|G;#3*%D*1PJ%4YL^tkd+gGyi7uAF!xyla@mDTL+S;kL&;wc*4Q%3t?N6Z29R z_}W7gM1*EOxq{O2Ze=j^*FG&RJoNOISOUO>&kBaOF9gHPzRhtu7%E$y50CzQv6_I0 zzbvFrFN1W!a|hyd%k#?i!~W+lHpVeg7Ww}^_`UF&Uml|rxaOl_%b|N!y8Wbu9Q`tU_w#jiOJ6@7r^@O$$)u6-^oX)H4?6*rgUPmN;u^X<_Z%?gDllX9XzGn8_>5v3fCa z#5mHuCg><X3^@Hu$Y2ciCKAOV?MQbI`q0CKA!G+Py_4SEa)Z|Zd8gEt7s->qQzVe zkv2jS-(k4sW;e%F6y!K==7eVPQ7}Xsr_!y0L=^xz=nQy^%iSE4)x;$WLqF%@2Bdl2 zfory-_iES(-wvUq1^T00Jgui@FpG#FvCzo-Y(vnf6g5wHIts-ogilrGirq0P)C^45 z97cau40=O%iyT2WC2?ECH`NCFrdPzY1AFFaMh_MkwoV>Xxh$M1*_PwU(C}>0l#{rm z8`xXIEkg%Cv3iiue&JUYI=j*%!LuF9v%G#A=|H>+vKlhHRt=-HM?6GSzH!lZIFbPG zM9N3ADO5A7tK`Ca<$09ywsnytg83~ z9&+D}WznMJAR zk}>O}gEqO8QpgSs1ogc&nzMV!!?AH=))Q|t$;=h6r4ifj_mR8R#GwK5)K&=mMe)Yy z!77;mU7N{FKiIRecK^sma-Et0=1E_`zPckB{NNt4oX+&g@*sNZ9`cjA1VsMBkcu~x zc{KG1~8wZIl8&W=Hh>A@V|;0yD5Hsvjm!JTYbmS-Mx) z+1oTN`sw532}%cckwwo0m+!36xpgP`9jOQASI7r+d9YsfWk;mc* ai1!~5l<>dMw8-B>&W^?GDA>P`6#ffxIHX4a delta 1548 zcmXw&drTBp6vpqFoim;AC?aazy3lQXG(dwhEDtp`Vzbf&e1IqsES1M@bzPjrmC800 zM6IRDipp&}m5r+)RtpKQu^F`0s??&USWStRq$D;`5{<1yZPJJ_y|dfSKa-sA_nrCf zId_gd6#{n!wc`s*1$-%!#Mm`4YlnbL z9mvuA*&TuyV<(lZEu*YKze_qQE5}13HVTugJpkX0@KMhnQ8#&+$+G2q3WK|;PUq6}xSD6>zj6|k|L zc)Mv`SBMXEtwLl(d>?((8>&S2ea1z3yUCSrLm&EYp=Y#4J~Fh08hE_I^ zBp?GPF3^MLEyfM$K7W=+2F)F!TLvw>!%3D<<;vUI)xi-ICoT|u*a&l^h=sX$RS_cR z4w1YOqh+e3Dm<9Af*T(S$S87K8@|=WAyco9(Yn#lJ_4g%0+QQg!(A=+j$gp*W8}eo z`uliDd^WxbXK%Pmj!uO7*(5efS(2#n2{ZLZ9*R+1|D3$Xv9c;tkW_O7gOo84i(F#=Aa$e8YEh8Zi@S5E;4;ye-Dar$@DVE{#@{W#O;lGg@i{qtF{0MQ)> zLl*U>m9=py`XejcF-0<{{EbkE47Dx5&?j@C264y&QHi=I2~G&nOh1M@Um5{qmZDl()PBBmf z0U>ICKI9b}5mTk`C~HdL55U}YaJob*!nKQ8QU;3H? AS^xk5 diff --git a/firmware/l0dable/files/fp-mini.scd b/firmware/l0dable/files/fp-mini.scd index 316d0f99f3cb224b1902f1059a041254a664df8c..accb7447f53cd96712016693d05c284eb0741fb4 100644 GIT binary patch delta 1557 zcmZ9MOKcNY6oyaid*iV^w&Srq9@{haponKk7~4sJC?qx{3W4S!B~hW_QOj{dfY?VMP&k5iQMFKshr|Lx7gTMj$|6-OwX~@y-9Z+tQUp;~pdzJbZfF z&bhzuxp!uBOL^|Fnl@*q`D#bGFx_;{F;<%SL920;$~a&13TfEn*g~%_CmpO|4ZA0DqvO;is|n!V+>O6BTArEDIf-)6z= z861I^pU)I{=!CQQm(#FU^spvIT_0jQ+sV%|7~%LKJIo$3xPi}^VP{M5Ha5cHIqv2L z`fI%S9#6_QIOJ+6jG3{rxYwzz*?M$*yfij=xKJ)tUtSa5Rp2>?({=$`0Ucen4HA_v z3Lzhh;ZSW(Ci{>}v`jbS^^}G;YhRTK`DR(nTDT}{m~pL_3G+*WByokJ;rp%)^@P1H zM9WIIG+1fNGSe`0pmNN7@zB4$>)PO>%1gv$%yc?yO!hWBMXZ#!4 z9Y37HU;Lwtocp*wFycEEfPHm>O4Gg#`l5I-ut&ZhfN%d(#e7%RwaLV-3ksA*IpEXq zWZe!%*lC=r6RR%PZDmBJZH1ZAILSd8L<=+Ze{C&~`o_f+Jx(5z4d1Fx`K7}TQJkD%U`0| delta 1478 zcmZ9LUrbwd6vq$k??*4(-j=qv?Y-@7dkF!@m~d}f*rIH}27)jK0nId^jEn~VY+a@} zqf3}Gn-Ac_%1M@mED(~t@UV&Q#qGr`kwrEa^+lt>#YGHzFj;0sLNsxn-?h_(`_lCL z{hV{p?|kp?aoch$cUkpWtH7Uff$Bj z;)J_T{4Bdup1B~*yP*+#SVDkruzI%UhBJ7P_3%ap8w`JEN7xw#131hRqUt1nM&4j> zkwd#}rY$VQb^MXn>>uFpOHs>Mb(U>eW(Ee29ezDG@t!H3TpsqmGd`Xh>pwD@&rQJA z=YybV+E7Y;@tohl@zOepI-YZczjPh1mbOY{%N{|D#0-pj4k~013BgQfEDIO(D9(6x zD8yX(Po43o;%xUkRu!Qj3EHyk#(#&jVeqwM?>ZAYLt<8HP^kDh;?kyVXRN}KDh~dU zRK=+H0$!F5aB^3rnX(q?f&}R@BJpR#z{6!}X;p$#j!>Df@J?A+BKx)@oC+COTE0yo zyQ|!3o-K|%Q2sI_W*$E&AFLwpQPCEQv@({N-m*xnmeXv$96E4F?&U;ZlJT-^h*RE{ zn^}hpZj`-4(j^%>y<)ijh=EgHlexVxg;%^z)_1&S6}k5WVA?yM>|<+aSfOO4DKE4t zqER2y#aqUeW|<17gl5{i@Ea|HUn;crn!wAgdh%X`jPx=NWf^Pam zzppg|H+)%^_dzv2?H^(!PvXb^7nN#1{OuR*({{EIztf_~D~6>>KMYrh!jYJcA6D%4 z5_3xkB7gi=)9}}dZbnE0+5zX7{eiuVh!c1|u#Yzc;8pf@>jcRNEMt zF??TrgmS=1v#d|UDc^-Tp^s78(N3A{LqaGfB!YVs ztyKtGD#{|HD7I-k7=a!EA5HmgGmeirNI4|O;j!;-im4wZ^m@s=2@#IQ5o!q3K_JC4(2 z(Qu3LSNTc|mg49&9Co|0k9EgE!{dgN