nabaztag_hack_kit 0.0.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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;;