-
Notifications
You must be signed in to change notification settings - Fork 0
/
bekon_main.bgs
330 lines (265 loc) · 10.9 KB
/
bekon_main.bgs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
# Have to declare variables first
dim result
dim endpoint
dim in(20) # endpoint data in
dim in_len
dim out(20) # endpoint data out
dim out_len
dim rssi
dim connection_handle
dim custom_adv_data(14)
# constants for serial interpreter
const START_BYTE = $53 # S - each command starts with a Start byte
const SERIAL = $24 # $ - Serial data will folow
const DATA1 = $21 # ! - Characteristic 1 data will follow
const DATA2 = $40 # @ - Characteristic 2 data will follow
const DFU = $7e
# command processor variables
dim receiving
dim data_len
dim command
dim xgatt
dim stop
dim watermark_len
dim received_len
dim ms #multiple send
#TODO: read from and write data to presistant storage (flash)
# flexible procedure to display %02X byte arrays
dim hex_buf(3) # [0,1] = ASCII hex representation, [2]=separator
dim hex_index # byte array index
procedure print_hex_bytes(my_endpoint, separator, reverse, b_length, b_data())
hex_buf(2:1) = separator
hex_index = 0
while hex_index < b_length
if reverse = 0 then
hex_buf(0:1) = (b_data(hex_index:1)/$10) + 48 + ((b_data(hex_index:1)/$10)/10*7)
hex_buf(1:1) = (b_data(hex_index:1)&$f) + 48 + ((b_data(hex_index:1)&$f )/10*7)
else
hex_buf(0:1) = (b_data(b_length - hex_index - 1:1)/$10) + 48 + ((b_data(b_length - hex_index - 1:1)/$10)/10*7)
hex_buf(1:1) = (b_data(b_length - hex_index - 1:1)&$f) + 48 + ((b_data(b_length - hex_index - 1:1)&$f )/10*7)
end if
if separator > 0 && hex_index < b_length - 1 then
call system_endpoint_tx(my_endpoint, 3, hex_buf(0:3))
else
call system_endpoint_tx(my_endpoint, 2, hex_buf(0:2))
end if
hex_index = hex_index + 1
end while
end
# TODO: not sure if need that (prob not)
event dfu_boot(version)
call system_endpoint_tx(endpoint, 19, "ble booted in dfu\r\n")
end
event system_boot(major, minor, patch, build, ll_version, protocol_version, hw)
endpoint = system_endpoint_uart1
receiving = 0
received_len = 0
ms = 0
watermark_len = 3
call system_endpoint_tx(endpoint, 12, "ble booted\r\n")
call system_endpoint_set_watermarks(endpoint, 0, 0) # disable watermarks
call system_endpoint_set_watermarks(endpoint, 3, $ff) # set RX watermark so that we can receive commands even before someone connects
custom_adv_data(0:1) = $04 #Length of adv data
custom_adv_data(1:1) = $ff #AD type is Manufacturer Specific Data AD type
custom_adv_data(2:1) = $47 #Bekonz Company Identifier Code - octet 2
custom_adv_data(3:1) = $00 #Bekonz Company Identifier Code - octet 1
custom_adv_data(4:1) = $e5 #Custom data indicating other side that we support spp_over_ble - or use line below
#custom_adv_data(4:1) = $e6 #Custom data indicating a remote bled112 to reboot in dfu mode
custom_adv_data(5:1) = $08 #Length of next adv data
custom_adv_data(6:1) = $09 # AD type is Complete local name
custom_adv_data(7:1) = $62 #b
custom_adv_data(8:1) = $65 #e
custom_adv_data(9:1) = $6b #k
custom_adv_data(10:1) = $6f #o
custom_adv_data(11:1) = $6e #n
custom_adv_data(12:1) = $7a #z
custom_adv_data(13:1) = $31 #1
call gap_set_adv_data(1, 14, custom_adv_data(0:14)) #overwrites the friendly name in gatt.xml with ET but also allows closed system's companion module-dongle to automatically connect
call gap_set_mode(gap_general_discoverable, gap_undirected_connectable) # start advertising
end
event connection_status(connection, flags, address, address_type, conn_interval, timeout, latency, bonding)
#call connection_get_rssi(connection)(connection_handle,rssi)
# let uart know that user connected
call system_endpoint_tx(endpoint, 18, "ble connected to: ")
call print_hex_bytes(endpoint, ":", 0, 6, address(0:6))
call system_endpoint_tx(endpoint, 2, "\r\n")
#call system_endpoint_set_watermarks(endpoint, 3, $ff) # set RX watermark to at least 3 bytes
#call system_endpoint_tx(endpoint, 15, ", rssi (hex): -")
#rssi = 256 - rssi #twos complement, now the negative values are positive
#call print_hex_bytes(endpoint, ":", 0, 1, rssi)
#call system_endpoint_tx(endpoint, 2, "\r\n")
#call system_endpoint_tx(endpoint, 26, "\n\r++ Connection interval: ")
#call system_endpoint_tx(endpoint, 4, conn_interval)
#call system_endpoint_tx(endpoint, 4, " ++\n")
end
event attributes_status(handle, flags)
# indications enabled so we can start receiving data from uart
if (handle = xgatt_serial) && (flags = 2) then
call system_endpoint_tx(endpoint, 22, "ble serial_can_start\r\n")
call system_endpoint_set_watermarks(endpoint, watermark_len, $ff) # set RX watermark to at least 3 bytes
end if
# indications disabled, stop receiving
if (handle = xgatt_serial) && (flags = 0) then
call system_endpoint_tx(endpoint, 20, "ble serial_stopped\r\n")
call system_endpoint_set_watermarks(endpoint, 0, $ff) # disable RX watermark
end if
# data1 requested (currently through subscribing to indications for simplicity)
if (handle = xgatt_data1) && (flags = 2) then
call system_endpoint_set_watermarks(endpoint, watermark_len, $ff) # set RX watermark to at least 3 bytes
call system_endpoint_tx(endpoint, 9, "ble -D1\r\n") # send command to Contiki requesting data1
end if
end
event system_endpoint_watermark_rx(curr_endpoint, size)
# debug
#call system_endpoint_tx(endpoint, 6, "size: ")
#call print_hex_bytes(endpoint, ":", 0, 1, size)
#call system_endpoint_tx(endpoint, 2, "\r\n")
# TODO: artifacts ? can prob get rid of that
#in_len = size
#if in_len > 20 then
# in_len = 20
#end if
# if we are not currently receiving, check the header first (3 bytes long)
if receiving = 0 then
in_len = 3
end if
call system_endpoint_set_watermarks(endpoint, 0, $ff) # disable RX watermark
call system_endpoint_rx(endpoint, in_len)(result, in_len, in(0:in_len)) # put the received data into a buffer we can access
# debug
#call system_endpoint_tx(endpoint, 8, "in_len: ")
#call print_hex_bytes(endpoint, ":", 0, 1, in_len)
#call system_endpoint_tx(endpoint, 2, ", ")
#call system_endpoint_tx(endpoint, in_len, in(0:in_len))
#call system_endpoint_tx(endpoint, 2, "\r\n")
#call system_endpoint_tx(endpoint, 10, "data_len: ")
#call print_hex_bytes(endpoint, ":", 0, 1, data_len)
#call system_endpoint_tx(endpoint, 2, "\r\n")
received_len = received_len + in_len
# debug
#call system_endpoint_tx(endpoint, 14, "received_len: ")
#call print_hex_bytes(endpoint, ":", 0, 1, received_len)
#call system_endpoint_tx(endpoint, 2, "\r\n")
stop = 0
# if received firmware update command - boot into dfu
if receiving = 1 && command = DFU && in(0:1) = $00 && in(1:1) = $01 then
#call system_endpoint_tx(endpoint, 10, "boot dfu\r\n")
call dfu_reset(1)
end if
if receiving = 0 && in(0:1) = $00 && in(1:1) = $01 && in(2:1) = $09 then #we will probably be receiving dfu_boot command
receiving = 1
command = DFU
data_len = 2
watermark_len = 2
in_len = 2
stop = 1
call system_endpoint_set_watermarks(endpoint, watermark_len, $ff) # set RX watermark
end if
# new command received
if receiving = 0 && in(0:1) = START_BYTE then
data_len = in(1:1) # load the data length
command = in(2:1) # load the command
# debug
#call system_endpoint_tx(endpoint, 10, "data_len: ")
#call print_hex_bytes(endpoint, ":", 0, 1, data_len)
#call system_endpoint_tx(endpoint, 11, ", command: ")
#call system_endpoint_tx(endpoint, 1, command)
#call system_endpoint_tx(endpoint, 2, "\r\n")
end if
# set flag if the data requires 'multiple sends'
if data_len > 60 && receiving = 0 then
ms = 1
# debug
#call system_endpoint_tx(endpoint, 4, "ms: ")
#call print_hex_bytes(endpoint, ":", 0, 1, ms)
#call system_endpoint_tx(endpoint, 2, "\r\n")
end if
# check the characteristic we'll be writing to
if command = SERIAL then
xgatt = xgatt_serial
end if
if command = DATA1 then
xgatt = xgatt_data1
end if
if command = DATA2 then
xgatt = xgatt_data2
end if
# use the maximum BLE payload if there is still data to be received through uart
if data_len > 20 && receiving = 0 && command != 0 then
watermark_len = 20
in_len = 20
end if
# will be receiving last chunk, so make sure we read only so many data bytes
if data_len <= 20 && receiving = 0 && command != 0 then
watermark_len = data_len
in_len = data_len
end if
# we can start processing the commands
if receiving = 0 && command != 0 then
received_len = 0
receiving = 1
stop = 1
call system_endpoint_set_watermarks(endpoint, watermark_len, $ff) # set RX watermark
end if
if receiving = 1 && data_len > 20 && stop = 0 then
stop = 1
data_len = data_len - in_len
call attributes_write(xgatt, 0, in_len, in(0:in_len))
end if
if receiving = 1 && data_len <= 20 && stop = 0 then
#call system_endpoint_tx(endpoint, 13, "last chunk?\r\n")
stop = 1
data_len = 0
command = 0
receiving = 0
received_len = 0
ms = 0
watermark_len = 3
call attributes_write(xgatt, 0, in_len, in(0:in_len))
end if
end
event attclient_indicated(connection, handle)
# second last chunk reception indicated, make sure we try read from uart only as much as there is left
if data_len != 0 && data_len <= 20 then
watermark_len = data_len
in_len = data_len
end if
# there is a 64 byte buffer that we cant overfill, this takes care of notifying Contiki it can send more data
if (received_len >= 60 && ms != 0) || data_len = 0 then
received_len = 0
call system_endpoint_tx(endpoint, 7, "ble x\r\n") # TODO: change it to something more sophisticated
end if
# the client has received data, we can read more from uart
if handle = xgatt then
#call system_endpoint_tx(endpoint, 11, "indicated\r\n")
call system_endpoint_set_watermarks(endpoint, watermark_len, $ff) # set RX watermark
end if
if data_len = 0 then
xgatt = 0
end if
end
event attributes_value(connection, reason, handle, offset, value_len, value_data)
# we received serial data from the client, pass it on to uart
if handle = xgatt_serial then
out(0:value_len) = value_data(0:value_len)
out_len = value_len
call system_endpoint_set_watermarks(endpoint, $ff, out_len) # set TX watermark
end if
end
event system_endpoint_watermark_tx(curr_endpoint, size)
if curr_endpoint = endpoint then
call system_endpoint_set_watermarks(endpoint, $ff, 0) # disable TX watermark
call system_endpoint_tx(endpoint, out_len, out(0:out_len))
call attributes_user_write_response(0, 0) # indicate reception
end if
end
event connection_disconnected(conn, reas)
call system_endpoint_tx(endpoint, 18, "ble disconnected\r\n")
#debug (not really working)
#call system_endpoint_tx(endpoint, 17, "\r-- Reason code: ")
#call system_endpoint_tx(endpoint, 2, reas)
#call system_endpoint_tx(endpoint, 4, " --\n")
call system_endpoint_set_watermarks(endpoint, 0, 0) # disable watermarks
# client disconnected so start advertising again
call gap_set_adv_data(1, 14, custom_adv_data(0:14))
call gap_set_mode(gap_general_discoverable, gap_undirected_connectable)
end