nabaztag_hack_kit 0.0.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (122) hide show
  1. data/.gitignore +7 -0
  2. data/.travis.yml +3 -0
  3. data/CHANGELOG.md +11 -0
  4. data/Gemfile +4 -0
  5. data/README.md +119 -0
  6. data/Rakefile +21 -0
  7. data/bin/mtl_comp +41 -0
  8. data/bin/mtl_merge +22 -0
  9. data/bin/mtl_simu +40 -0
  10. data/bytecode/lib/buffer.mtl +109 -0
  11. data/bytecode/lib/button.mtl +27 -0
  12. data/bytecode/lib/data_helper.mtl +88 -0
  13. data/bytecode/lib/ear.mtl +90 -0
  14. data/bytecode/lib/led.mtl +33 -0
  15. data/bytecode/lib/rfid.mtl +50 -0
  16. data/bytecode/main.mtl +129 -0
  17. data/config.ru +6 -0
  18. data/ext/bytecode/Commands.md +172 -0
  19. data/ext/bytecode/Docs.md +488 -0
  20. data/ext/bytecode/README.md +5 -0
  21. data/ext/bytecode/lib/arp.mtl +159 -0
  22. data/ext/bytecode/lib/cfg.mtl +74 -0
  23. data/ext/bytecode/lib/choreos.mtl +1487 -0
  24. data/ext/bytecode/lib/dhcp.mtl +152 -0
  25. data/ext/bytecode/lib/dns.mtl +89 -0
  26. data/ext/bytecode/lib/http.mtl +84 -0
  27. data/ext/bytecode/lib/tcp.mtl +340 -0
  28. data/ext/bytecode/lib/udp.mtl +49 -0
  29. data/ext/bytecode/lib/util.mtl +74 -0
  30. data/ext/bytecode/lib/var.mtl +15 -0
  31. data/ext/bytecode/lib/wifi.mtl +243 -0
  32. data/ext/bytecode/nominal-ping.mtl +5828 -0
  33. data/ext/mtl/Makefile +42 -0
  34. data/ext/mtl/README.md +13 -0
  35. data/ext/mtl/bc.cpp +1891 -0
  36. data/ext/mtl/conf.bin.sans_password +0 -0
  37. data/ext/mtl/config.txt +5 -0
  38. data/ext/mtl/dumpbc.c +2566 -0
  39. data/ext/mtl/extconf.rb +1 -0
  40. data/ext/mtl/linux_simu.c +271 -0
  41. data/ext/mtl/linux_simuaudio.c +16 -0
  42. data/ext/mtl/linux_simuaudio.h +18 -0
  43. data/ext/mtl/linux_simunet.c +620 -0
  44. data/ext/mtl/linux_simunet.h +7 -0
  45. data/ext/mtl/log.c +297 -0
  46. data/ext/mtl/log.h +20 -0
  47. data/ext/mtl/main_compiler.cpp +104 -0
  48. data/ext/mtl/main_simu.cpp +221 -0
  49. data/ext/mtl/mp3/GTKANAL.H +97 -0
  50. data/ext/mtl/mp3/LAYER3.C +2090 -0
  51. data/ext/mtl/mp3/TABINIT.C +82 -0
  52. data/ext/mtl/mp3/common.c +265 -0
  53. data/ext/mtl/mp3/dct64_i386.c +316 -0
  54. data/ext/mtl/mp3/decode_i386.c +155 -0
  55. data/ext/mtl/mp3/huffman.h +332 -0
  56. data/ext/mtl/mp3/interface.c +258 -0
  57. data/ext/mtl/mp3/mpg123.h +182 -0
  58. data/ext/mtl/mp3/mpglib.h +44 -0
  59. data/ext/mtl/properties.c +293 -0
  60. data/ext/mtl/properties.h +10 -0
  61. data/ext/mtl/simu.c +750 -0
  62. data/ext/mtl/simuaudio.c +662 -0
  63. data/ext/mtl/simuaudio.h +74 -0
  64. data/ext/mtl/simunet.c +400 -0
  65. data/ext/mtl/simunet.h +30 -0
  66. data/ext/mtl/utils/correct_const.sh +34 -0
  67. data/ext/mtl/vaudio.c +677 -0
  68. data/ext/mtl/vaudio.h +46 -0
  69. data/ext/mtl/vbc.h +160 -0
  70. data/ext/mtl/vbc_str.h +166 -0
  71. data/ext/mtl/vcomp/Makefile +29 -0
  72. data/ext/mtl/vcomp/bootstrap.cpp +89 -0
  73. data/ext/mtl/vcomp/compiler.cpp +470 -0
  74. data/ext/mtl/vcomp/compiler.h +200 -0
  75. data/ext/mtl/vcomp/compiler_file.cpp +929 -0
  76. data/ext/mtl/vcomp/compiler_prog.cpp +250 -0
  77. data/ext/mtl/vcomp/compiler_term.cpp +1053 -0
  78. data/ext/mtl/vcomp/compiler_type.cpp +872 -0
  79. data/ext/mtl/vcomp/compiler_var.cpp +289 -0
  80. data/ext/mtl/vcomp/file.cpp +79 -0
  81. data/ext/mtl/vcomp/file.h +39 -0
  82. data/ext/mtl/vcomp/filesystem.h +14 -0
  83. data/ext/mtl/vcomp/interpreter.cpp +85 -0
  84. data/ext/mtl/vcomp/interpreter.h +121 -0
  85. data/ext/mtl/vcomp/memory.cpp +241 -0
  86. data/ext/mtl/vcomp/memory.h +326 -0
  87. data/ext/mtl/vcomp/param.h +95 -0
  88. data/ext/mtl/vcomp/parser.cpp +427 -0
  89. data/ext/mtl/vcomp/parser.h +97 -0
  90. data/ext/mtl/vcomp/parser_xml.cpp +124 -0
  91. data/ext/mtl/vcomp/prodbuffer.cpp +125 -0
  92. data/ext/mtl/vcomp/prodbuffer.h +42 -0
  93. data/ext/mtl/vcomp/resource.h +17 -0
  94. data/ext/mtl/vcomp/stdlib_core.cpp +122 -0
  95. data/ext/mtl/vcomp/terminal.cpp +73 -0
  96. data/ext/mtl/vcomp/terminal.h +30 -0
  97. data/ext/mtl/vcomp/util.cpp +48 -0
  98. data/ext/mtl/vcomp/util.h +31 -0
  99. data/ext/mtl/vinterp.c +1349 -0
  100. data/ext/mtl/vinterp.h +11 -0
  101. data/ext/mtl/vloader.c +127 -0
  102. data/ext/mtl/vloader.h +31 -0
  103. data/ext/mtl/vlog.c +589 -0
  104. data/ext/mtl/vlog.h +69 -0
  105. data/ext/mtl/vmem.c +424 -0
  106. data/ext/mtl/vmem.h +107 -0
  107. data/ext/mtl/vnet.c +255 -0
  108. data/ext/mtl/vnet.h +19 -0
  109. data/lib/nabaztag_hack_kit/message/api.rb +39 -0
  110. data/lib/nabaztag_hack_kit/message/helper.rb +39 -0
  111. data/lib/nabaztag_hack_kit/message.rb +36 -0
  112. data/lib/nabaztag_hack_kit/server.rb +50 -0
  113. data/lib/nabaztag_hack_kit/version.rb +3 -0
  114. data/lib/nabaztag_hack_kit.rb +4 -0
  115. data/nabaztag_hack_kit.gemspec +29 -0
  116. data/public/bytecode.bin +0 -0
  117. data/test/bytecode/helper.mtl +60 -0
  118. data/test/bytecode/native.mtl +28 -0
  119. data/test/bytecode/test.mtl +221 -0
  120. data/test/spec_helper.rb +5 -0
  121. data/test/unit/message_spec.rb +56 -0
  122. metadata +209 -0
data/.gitignore ADDED
@@ -0,0 +1,7 @@
1
+ *.gem
2
+ .bundle
3
+ Gemfile.lock
4
+ pkg/*
5
+ .rvmrc
6
+ *.bin
7
+ *.o
data/.travis.yml ADDED
@@ -0,0 +1,3 @@
1
+ rvm:
2
+ - 1.9.2
3
+ script: "bundle exec rake test"
data/CHANGELOG.md ADDED
@@ -0,0 +1,11 @@
1
+ # Changes
2
+
3
+ ## v0.0.2 - 29-01-2012
4
+
5
+ * rename to NabaztagHackKit
6
+ * moved rake task to binaries
7
+ * fixed tests
8
+
9
+ ## v0.0.1 - 28-01-2012
10
+
11
+ * inital release
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source "http://rubygems.org"
2
+
3
+ # Specify your gem's dependencies in nabaztag_hack_kit.gemspec
4
+ gemspec
data/README.md ADDED
@@ -0,0 +1,119 @@
1
+ # Nabaztag Hack Kit
2
+
3
+ Everything you need to hack the Rabbit: a sinatra server including simple api framework to run custom bytecode on Nabaztag v1/v2. Sources + Compiler included (linux only)
4
+
5
+ ![](http://travis-ci.org/rngtng/NabaztagHackKit.png)
6
+
7
+ ## Getting Started
8
+
9
+ ### Compile & Run
10
+
11
+ The kit comes with violet sources and binaries to compile custom Nabaztag bytecode. On a linux machine those binaries are compiled on instalation of the gem. Following three binaries are available:
12
+
13
+ #### mtl_merge
14
+
15
+ Merges multiple `*.mtl` files into one. Files are included like in C: `#include "<relative path to file>"`. Output is temporary file `.tmp.mtl`.
16
+
17
+ #### mtl_comp
18
+
19
+ Compiles a `*.mtl` file. It calls `mtl_merge` before, and fallbacks to remote compiler in case binary is not found and `HOST` is given.
20
+
21
+ #### mtl_simu
22
+
23
+ Runs a `*.mtl` file. It calls `mtl_merge` before, and fallbacks to remote simulator in case binary is not found and `HOST` is given.
24
+
25
+
26
+ ### Understanding the Bytecode
27
+
28
+ The bytecode is written in a custom language by Sylvain Huet. Its referenced as _Metal_ and files end with `.mtl`. Unfortunately documentation is very poor (and in french). Check directory `ext/bytecode/` which contains a basic overview & documentaion as well as a list of (common) commands. A good reference is the original bytecode, included in the directory as well. Major parts got extracted into seperate files, found in `lib/` directory and ready to be included in your code.
29
+
30
+ ### Testing
31
+
32
+ The kit includes a simple test framework to test custom bytecode. See `test/bytecode/test.mtl`. A typical test looks like this:
33
+
34
+ ```c
35
+ let test "<test name>" -> t in
36
+ (
37
+ //assertions
38
+ assert_equalI 0 10 - (2* 5);
39
+ 0);
40
+ ```
41
+
42
+ The framework offers assertions similar to ruby tunit stile. Mind that the variable type has to be given
43
+ explicit. Convertion is:
44
+
45
+ * I = interger
46
+ * S = string
47
+ * L = list
48
+ * T = tab
49
+
50
+ Following assertions are available:
51
+
52
+ * assert_equalI I I
53
+ * assert_equalI S S
54
+ * assert_nil I
55
+ * assert_equalIL
56
+ * assert_equalSL
57
+ * assert_equalTL
58
+
59
+
60
+ ## Server
61
+
62
+ The Server is the communication endpoint for the rabbit. Its two main purposes are:
63
+
64
+ 1. serving the bytecode on bootup
65
+ 2. receive and respond to HTTP requests in a defined format.
66
+
67
+ To start the server, run shortcut `rake run` or, as it's based on rack, `rackup -p <portnumer>`.
68
+
69
+
70
+ ## API
71
+ As example and for my own purposes I implemented a simple API to deal with RFID, LEDS, BUTTON and EARS easily.
72
+
73
+ ### Input Devices
74
+
75
+ #### RFID
76
+ NabaztagInjector
77
+
78
+
79
+ #### BUTTON
80
+ Current Button has very basic functionality: a short press send HTTP Request of type `Log` to server, a long
81
+ press foreces the bunny to restart.
82
+
83
+ ### Output Devices
84
+ Data for all output devices are stored in buffers. Each device has two: one for ontime, imediate playback, another for permanet loops.
85
+
86
+ #### LEDS
87
+ Buffers 0 - 9, where 0-4 are used for onetime, and 5-9 for loop playback.
88
+
89
+ #### EARS
90
+ Buffers 10 - 13, where 10 & 11 are used for onetime, and 12 & 13 for loop playback.
91
+
92
+
93
+
94
+ ## Disclamer
95
+
96
+ The server party was heavily inspired by [Trudy.rb](https://github.com/quimarche/trudy/blob/master/trudy.rb), compiler code copied from OpenJabNab.
97
+ Thanks!
98
+
99
+
100
+ ### Protocol
101
+ A good introduction to understand Nabaztag Protocol:
102
+
103
+ * http://www.cs.uta.fi/hci/spi/jnabserver/documentation/index.html
104
+
105
+
106
+ ### Nabaztag Background
107
+ Read following posting for more backgorund on Nabaztag Hacking (uses google translate:)
108
+
109
+ * [Les source bytecode et compilateur](http://translate.googleusercontent.com/translate_c?hl=en&rurl=translate.google.com&sl=fr&tl=en&twu=1&u=http://nabaztag.forumactif.fr/t13241p30-les-sources-bytecode-et-compilateur&usg=ALkJrhjLTbx1GMfSUgwhdjES1LzlE07HZQ#338060)
110
+ * [Mindscape donne une seconde vie a nabaztag](http://translate.google.com/translate?hl=en&sl=fr&tl=en&u=http%3A%2F%2Fwww.planete-domotique.com%2Fblog%2F2011%2F08%2F07%2Fmindscape-donne-une-seconde-vie-a-nabaztag%2F)
111
+
112
+
113
+ ### Future
114
+ I'd like to hack the Violet mir:ror too. Some starting points:
115
+
116
+ * https://github.com/leh/ruby-mirror
117
+ * http://reflektor.sourceforge.net/
118
+
119
+
data/Rakefile ADDED
@@ -0,0 +1,21 @@
1
+ require "bundler/gem_tasks"
2
+
3
+ require 'rspec/core/rake_task'
4
+ RSpec::Core::RakeTask.new("unit") do |t|
5
+ t.pattern = "./test/**/*_spec.rb" # don't need this, it's default.
6
+ end
7
+
8
+ namespace :test do
9
+ desc "Test bytcode"
10
+ task :bytecode do
11
+ puts `bin/mtl_simu test/bytecode/test.mtl`
12
+ end
13
+ end
14
+
15
+ task :test => [:unit]
16
+ task :default => :test
17
+
18
+ desc "start server on port 9090"
19
+ task :run do
20
+ `rackup -p 9090`
21
+ end
data/bin/mtl_comp ADDED
@@ -0,0 +1,41 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ BIN_NAME = File.basename(__FILE__)
4
+ BIN_PATH = File.dirname(__FILE__)
5
+ BIN = File.join( File.expand_path("../ext/mtl", BIN_PATH), BIN_NAME)
6
+ FILE = ARGV.first
7
+
8
+ FILTER = ENV['FILTER'] || "| grep -v 'bytes' | grep -e'[a-z]'"
9
+ MERGE = File.join(BIN_PATH, 'mtl_merge')
10
+ TMP = ENV['TMP'] || '.tmp.mtl'
11
+ OUT = ENV['OUT'] || "bytecode.bin"
12
+
13
+ HOST = ENV['HOST']
14
+ REMOTE_PATH = ENV['REMOTE'] || "~/"
15
+ REMOTE_BIN = ENV['REMOTE_BIN']
16
+
17
+ unless FILE
18
+ puts "usage: #{File.basename(__FILE__)} [filename]"
19
+ abort
20
+ end
21
+
22
+ # merge
23
+ `TMP='#{TMP}' #{MERGE} #{FILE}`
24
+
25
+ # compile
26
+ out = nil
27
+ if File.exists?(BIN)
28
+ out = `#{BIN} -s #{FILE} #{OUT} 2>&1 #{FILTER}`
29
+ else
30
+ print "local binary not found"
31
+ end
32
+
33
+ if HOST
34
+ puts " - falling back to remote"
35
+ `scp #{TMP} #{HOST}:#{REMOTE_PATH}#{TMP}`
36
+ out = `ssh #{HOST} "cd #{REMOTE_PATH} && rm -f #{TMP}.bin && #{REMOTE_BIN}#{BIN_NAME} -s #{TMP} #{TMP}.bin 2>&1 #{FILTER}"`
37
+ `scp #{HOST}:#{REMOTE_PATH}#{TMP}.bin #{OUT}`
38
+ end
39
+
40
+ puts out
41
+ `rm #{TMP}`
data/bin/mtl_merge ADDED
@@ -0,0 +1,22 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ # Merge a file with its includes, pass filename as first argument
4
+
5
+ TMP = ENV['TMP'] || '.tmp.mtl'
6
+
7
+ unless ARGV.size == 1
8
+ puts "usage: #{File.basename(__FILE__)} [filename]"
9
+ abort
10
+ end
11
+
12
+ file = ARGV.first
13
+
14
+ dir = File.dirname(file)
15
+ File.open(TMP, 'w') do |out|
16
+ File.open(file).each_line do |line|
17
+ if line =~ /#include "([^"]+)"/
18
+ line = `cat #{dir}/#{$1}.mtl`
19
+ end
20
+ out.puts line
21
+ end
22
+ end
data/bin/mtl_simu ADDED
@@ -0,0 +1,40 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ BIN_NAME = File.basename(__FILE__)
4
+ BIN_PATH = File.dirname(__FILE__)
5
+ BIN = File.join( File.expand_path("../ext/mtl", BIN_PATH), BIN_NAME)
6
+ FILE = ARGV.first
7
+
8
+ FILTER = ENV['FILTER'] || "| grep -v 'bytes' | grep -e'[a-z]'"
9
+ MERGE = File.join(BIN_PATH, 'mtl_merge')
10
+ TMP = ENV['TMP'] || '.tmp.mtl'
11
+ OUT = ENV['OUT'] || "bytecode.bin"
12
+
13
+ HOST = ENV['HOST']
14
+ REMOTE_PATH = ENV['REMOTE'] || "~/"
15
+ REMOTE_BIN = ENV['REMOTE_BIN']
16
+
17
+ unless FILE
18
+ puts "usage: #{File.basename(__FILE__)} [filename]"
19
+ abort
20
+ end
21
+
22
+ # merge
23
+ `TMP='#{TMP}' #{MERGE} #{FILE}`
24
+
25
+ # simu
26
+ out = nil
27
+ if File.exists?(BIN)
28
+ out = `#{BIN} -s #{FILE} #{OUT} 2>&1 #{FILTER}`
29
+ else
30
+ print "local binary not found"
31
+ end
32
+
33
+ if HOST
34
+ puts " - falling back to remote"
35
+ `scp #{TMP} #{HOST}:#{REMOTE_PATH}#{TMP}`
36
+ out = `ssh #{HOST} "cd #{REMOTE_PATH} && #{REMOTE_BIN}#{BIN_NAME} --source #{TMP} < #{TMP} 1>&2"`
37
+ end
38
+
39
+ puts out
40
+ `rm #{TMP}`
@@ -0,0 +1,109 @@
1
+ //###############################################
2
+ //---------------------- Buffer -------------------------------
3
+
4
+ var buffers;;
5
+ type BUFFER=[valB stepB lenB posB loopB];;
6
+
7
+ fun buffersInit len=
8
+ set buffers = tabnew nil len;
9
+ for index = 0; index < len; index + 1 do
10
+ set buffers.index = [valB:""]
11
+ ;;
12
+
13
+ fun _bufferFill index step loop val=
14
+ let strlen val -> len in
15
+ set buffers.index = [valB:val stepB:step lenB:len posB:0 loopB:loop];
16
+ 0;;
17
+
18
+ fun bufferFill index val=
19
+ _bufferFill index 1 0 val
20
+ ;;
21
+
22
+ fun bufferFill3 index val=
23
+ _bufferFill index 3 0 val
24
+ ;;
25
+
26
+ fun loopBufferFill index val=
27
+ _bufferFill index 1 1 val
28
+ ;;
29
+
30
+ fun loopBufferFill3 index val=
31
+ _bufferFill index 3 1 val
32
+ ;;
33
+
34
+ fun buffersFill from to val=
35
+ for index = from; index <= to; index + 1 do
36
+ bufferFill index val
37
+ ;;
38
+
39
+ fun buffersFill3 from to val=
40
+ for index = from; index <= to; index + 1 do
41
+ bufferFill3 index val
42
+ ;;
43
+
44
+ fun bufferRead index=
45
+ let buffers.index -> buffer in
46
+ if buffer.posB < buffer.lenB then
47
+ (
48
+ set buffer.posB = buffer.posB + buffer.stepB;
49
+ let buffer.posB - buffer.stepB -> pos in
50
+ if buffer.stepB == 3 then
51
+ CtoI3 buffer.valB pos
52
+ else
53
+ strget buffer.valB pos
54
+ ) else if buffer.loopB > 0 && buffer.posB > 0 then (
55
+ set buffer.posB = 0;
56
+ bufferRead index
57
+ )
58
+ else (
59
+ nil
60
+ )
61
+ ;;
62
+
63
+ //-----------------------------------------------------
64
+ var palette = {0 90 130 170 215 255 255 255};; // 0x00 0x5a 0x82 0xaa 0xd7 0xFF
65
+
66
+ fun COtoI r g b=
67
+ r * 36 + g * 6 + b
68
+ ;;
69
+
70
+ fun ItoCO val=
71
+ if val == nil then set val = 0;
72
+ if val > 215 then set val = 215;
73
+ let val / 36 -> r in
74
+ let (val % 36) / 6 -> g in
75
+ let (val % 36) % 6 -> b in
76
+ palette.r << 16 + palette.g << 8 + palette.b
77
+ ;;
78
+
79
+ // returns number of chars before char \255
80
+ fun str_find_end val=
81
+ strstr val "\255" 0
82
+ ;;
83
+
84
+ //-----------------------------------------------------
85
+ const RESPONSE_HEADER = 0x7f;;
86
+
87
+ fun parseResponse_ s i res=
88
+ if (i < strlen s) then
89
+ (
90
+ let (strget s i) -> code in
91
+ let (CtoI3 s i+1) -> len in
92
+ (
93
+ if len >= 0 then
94
+ (
95
+ let strsub s i+4 len -> data in
96
+ parseResponse_ s i+4+len [code data]::res
97
+ )
98
+ )
99
+ )
100
+ else (
101
+ res
102
+ )
103
+ ;;
104
+
105
+ // messages will be reveresed!
106
+ fun parseResponse s=
107
+ if (strget s 0) == RESPONSE_HEADER then
108
+ parseResponse_ s 1 nil
109
+ ;;
@@ -0,0 +1,27 @@
1
+ //###############################################
2
+ //------------------- Button --------------------
3
+
4
+ const BUTTON_REBOOT = 30;; //ms MIN 50ms
5
+ var button_pressed = 0;;
6
+ fun checkButton=
7
+ if (button2 > 0) then
8
+ (
9
+ set button_pressed = button_pressed + 1;
10
+ if button_pressed == 1 then
11
+ (
12
+ httprequest "GET" buttonUrl (itoa time_ms) "" #_cbHttp HTTP_NORMAL;
13
+ 0
14
+ ) else if button_pressed == BUTTON_REBOOT then
15
+ (
16
+ buffersFill 0 4 "\0\255\0\255\0\255\255\255"
17
+ )
18
+ )
19
+ //reboot only when button not pressed, otherwise we get into setup mode
20
+ else if button_pressed > BUTTON_REBOOT then
21
+ (
22
+ exit
23
+ )
24
+ else (
25
+ set button_pressed = 0
26
+ )
27
+ ;;
@@ -0,0 +1,88 @@
1
+ var logs = "";;
2
+
3
+ fun log t tab=
4
+ let "|"::nil -> all in
5
+ (
6
+ for i = tablen tab; i > 0 ; i - 1 do
7
+ (
8
+ let itoa tab.(i - 1) -> data in
9
+ set all = data::","::all
10
+ );
11
+ set logs = strcatlist logs::t::","::(itoa time_ms)::","::all
12
+ )
13
+ ;;
14
+
15
+ fun TLtoS tlist=
16
+ if tlist == nil then
17
+ ""
18
+ else
19
+ let hd tlist -> [a b] in
20
+ strcatlist (itoa a)::b::(TLtoS tl tlist)::nil
21
+ ;;
22
+
23
+ //----------- Data Dump
24
+
25
+ // echo a string list as string
26
+ fun SLecho list=
27
+ Secho strcatlist list
28
+ ;;
29
+
30
+ fun SLecholn list=
31
+ SLecho list;
32
+ Secholn ""
33
+ ;;
34
+
35
+ // echo a integer list as string
36
+ fun ILecho list=
37
+ Secho listtostr list
38
+ ;;
39
+
40
+ fun ILecholn list=
41
+ ILecho list;
42
+ Secholn ""
43
+ ;;
44
+
45
+ fun TLecho tlist=
46
+ Secho TLtoS tlist
47
+ ;;
48
+
49
+ //----------- Data Transformation
50
+
51
+ // string to list of hex chars
52
+ fun _webmac key i=
53
+ if i < strlen key then (ctoh strget key i)::_webmac key i+1;;
54
+ fun webmac key=
55
+ strcatlist _webmac key 0;;
56
+
57
+ //convert chars into int (there is a limit!!!)
58
+ fun _StoI val pos len=
59
+ let strget val pos -> v in
60
+ if(len >= 0) then
61
+ v << (8 * len) + _StoI val (pos + 1) (len - 1)
62
+ else
63
+ 0
64
+ ;;
65
+ fun StoI val=
66
+ _StoI val 0 (strlen val) - 1
67
+ ;;
68
+
69
+ //convert first 3 chars into int (perfect to set led color)
70
+ fun StoI3 val=
71
+ _StoI val 0 2
72
+ ;;
73
+
74
+ //convert first 2 chars into int (perfect to set led color)
75
+ fun StoI2 val=
76
+ _StoI val 0 1
77
+ ;;
78
+
79
+ fun CtoI3 s offset=
80
+ (strget s offset) << 16 + (strget s offset+1) << 8 + strget s offset+2
81
+ ;;
82
+
83
+ // -------------------- other stuff
84
+
85
+ fun exit=
86
+ Secholn "\n";
87
+ reboot 0x0407FE58 0x13fb6754
88
+ ;;
@@ -0,0 +1,90 @@
1
+ //###############################################
2
+ //------------------- EAR -----------------------
3
+
4
+ var ears;;
5
+ const EAR_INIT = nil;;
6
+ const EAR_STOP = 0;;
7
+ const EAR_FORWARD = 1;;
8
+ const EAR_BACKWARD = -1;;
9
+ const EAR_TICKS = 17;;
10
+
11
+ type EAR=[dir pos shouldPos lastOffset lastTime lastTime2 lastRead];;
12
+
13
+ fun earNorm norm=
14
+ (EAR_TICKS + norm) % EAR_TICKS
15
+ ;;
16
+
17
+ fun earBufferRead index=
18
+ let bufferRead index+10 -> earPos in
19
+ (
20
+ if earPos != nil then
21
+ set earPos = earNorm earPos;
22
+ earPos
23
+ )
24
+ ;;
25
+
26
+ fun earRead index=
27
+ let ears.index -> ear in
28
+ let time_ms -> currentTime in
29
+ (
30
+ let motorget index -> currentOffset in
31
+ let (currentOffset - ear.lastOffset) -> diff in
32
+ (
33
+ if diff > 0 then //ear moved
34
+ (
35
+ // update pos
36
+ if ear.pos != EAR_INIT then
37
+ let ear.dir -> direction in
38
+ (
39
+ if direction == 0 then set direction = 1; //manual moved!!
40
+ set ear.pos = earNorm ear.pos + direction * diff
41
+ );
42
+
43
+ // check for reset Reset
44
+ let currentTime - ear.lastTime -> lastDuration in
45
+ let currentTime - ear.lastTime2 -> totalDuration in
46
+ if ear.dir != EAR_STOP && lastDuration > 1000 && totalDuration < 1450 then
47
+ (
48
+ set ear.pos = earNorm (ear.dir - 1) / 2; // either 0 or 16
49
+ bufferFill 0 "\100";
50
+ log "reset" {index lastDuration totalDuration ear.dir ear.pos}
51
+ );
52
+ log "moved" {index ear.lastTime ear.lastTime2 ear.lastRead ear.pos ear.shouldPos ear.dir };
53
+
54
+ set ear.lastTime2 = ear.lastTime;
55
+ set ear.lastTime = currentTime
56
+ );
57
+ set ear.lastOffset = currentOffset
58
+ );
59
+
60
+ // check & read new value
61
+ if (ear.pos != EAR_INIT) && (ear.pos == ear.shouldPos) && (currentTime - ear.lastRead) > 270 then
62
+ (
63
+ let earBufferRead index -> earPos in
64
+ (
65
+ if earPos == nil then set earPos = earBufferRead index+2;
66
+ if earPos == nil then set earPos = ear.pos;
67
+ set ear.shouldPos = earPos;
68
+ set ear.dir = earNorm ear.shouldPos - ear.pos;
69
+ if ear.dir > 8 then set ear.dir = -1;
70
+ if ear.dir > 0 then set ear.dir = 1;
71
+ motorset index ear.dir;
72
+
73
+ set ear.lastRead = currentTime
74
+
75
+ // log "ear read" {index time_ms earPos ear.pos ear.shouldPos}
76
+ )
77
+ )
78
+ )
79
+ ;;
80
+
81
+ fun earsInit=
82
+ let time_ms -> currentT in
83
+ (
84
+ set ears = tabnew nil 2;
85
+ set ears.0 = [dir:EAR_FORWARD pos:EAR_INIT shouldPos:0 lastTime:currentT lastTime2:currentT];
86
+ set ears.1 = [dir:EAR_FORWARD pos:EAR_INIT shouldPos:0 lastTime:currentT lastTime2:currentT];
87
+ motorset 0 1;
88
+ motorset 1 1
89
+ );
90
+ 0;;
@@ -0,0 +1,33 @@
1
+ //###############################################
2
+ //------------------ LED ----------------------
3
+
4
+ const LED_CHECK_FQ = 500;; //ms MIN 50ms
5
+ var led_last_check = 0;;
6
+
7
+ fun ledBufferRead index=
8
+ let bufferRead index -> color in
9
+ let buffers.index -> buffer in
10
+ if color != nil && buffer.stepB == 1 then
11
+ ItoCO color
12
+ else
13
+ color
14
+ ;;
15
+
16
+ fun setLeds=
17
+ //LED_CHECK_FQ
18
+ let (button3 + 1) * 3 -> led_check_fq in
19
+ if ((time_ms - led_last_check) > led_check_fq) then
20
+ (
21
+ for index = 0; index < 5; index + 1 do
22
+ (
23
+ let ledBufferRead index+5 -> loopColor in
24
+ let ledBufferRead index -> color in
25
+ (
26
+ if color == nil then set color = loopColor;
27
+ if color == nil then set color = 0;
28
+ led index color
29
+ )
30
+ );
31
+ set led_last_check = time_ms
32
+ )
33
+ ;;
@@ -0,0 +1,50 @@
1
+ //###############################################
2
+ //--------------- RFID ------------------------
3
+
4
+ const RFID_CHECK_FQ = 500;; //ms MIN 50ms
5
+ const RFID_STOP_BYTE = 0xFF;;
6
+ const RFID_ID_START = "\208\2\26";; // 0xd0 0x02 0x1a
7
+ const RFID_ID_FALSE = "\0\0\0\0\0\0\0\0\v";;
8
+ const RFID_ID_ERROR = "\69\114\114\111\114\0\0\0\v";; // 0x45 72 72 6f 72 00 00 00
9
+
10
+ var rfid_last_check = 0;;
11
+ var rfid_data = "";;
12
+
13
+ fun checkRFID=
14
+ if ((time_ms - rfid_last_check) > RFID_CHECK_FQ) then
15
+ (
16
+ let rfidGet -> rfid in
17
+ if (rfid != nil) then
18
+ (
19
+ if ((strstr rfid RFID_ID_START 0) == 0) then
20
+ (
21
+ httprequest "PUT" playerUrl rfid "" #_cbHttp HTTP_NORMAL;
22
+ 0
23
+ )
24
+ else if ((strstr rfid RFID_ID_FALSE 0) == 0) then
25
+ (
26
+ 0
27
+ )
28
+ else
29
+ (
30
+ let strlen rfid -> len in //usually that's 8
31
+ for index = 0; index < len; index + 1 do
32
+ (
33
+ let strget rfid index -> data_byte in
34
+ (
35
+ if (data_byte != RFID_STOP_BYTE) then
36
+ set rfid_data = strcat rfid_data ctoh data_byte
37
+ else if ((strlen rfid_data) > 0) then
38
+ (
39
+ httprequest "POST" eventUrl rfid_data "" #_cbHttp HTTP_NORMAL;
40
+ set rfid_data = ""
41
+ )
42
+ )
43
+ );
44
+ 0
45
+ )
46
+ );
47
+ //all done
48
+ set rfid_last_check = time_ms
49
+ );
50
+ 0;;