ruby-xbee 1.1.0 → 1.2.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,530 @@
1
+ $: << File.dirname(__FILE__)
2
+ require 'test_helper'
3
+ require 'socket'
4
+ ##
5
+ # The main goal of these testcases is to test basic API frame reading from
6
+ # socket, ensuring the integrity of frames by checksum calculation and
7
+ # ability to construct frames. Some of the frame examples for testing are
8
+ # based on the XBee reference manuals but feel free to run with your
9
+ # imagination.
10
+ #
11
+ # More detailed frame testing are kept separate from this file. Only
12
+ # basic frame stuff here.
13
+ # ==================================================
14
+ # Currently known frames, o = covered by test frames
15
+ # ==================================================
16
+ # o - 0x08 - AT Command
17
+ # o - 0x09 - AT Command - Queue Parameter Value
18
+ # o - 0x10 - ZigBee Transmit Request
19
+ # o - 0x11 - Explicit Addressing ZigBee Command Frame
20
+ # o - 0x17 - Remote Command Request
21
+ # o - 0x21 - Create Source Route
22
+ # o - 0x88 - AT Command Response
23
+ # o - 0x8a - Modem Status
24
+ # o - 0x8b - ZigBee Transmit Status
25
+ # o - 0x90 - ZigBee Receive Packet (AO=0)
26
+ # o - 0x91 - ZigBee Explicit Rx Indicator (AO=1)
27
+ # o - 0x92 - ZigBee IO Data Sample Rx Indicator
28
+ # x - 0x94 - XBee Sensor Read Indicator (AO=0)
29
+ # x - 0x95 - Node Identification Indicator (AO=0)
30
+ # o - 0x97 - Remote Command Response
31
+ # x - 0xA0 - Over-the-Air Firmware Update Status
32
+ # x - 0xA1 - Route Record Indicator
33
+ # x - 0xA3 - Many-to-One Route Request Indicator
34
+ class RubyXbeeApiFrameTest < MiniTest::Test
35
+ def setup
36
+ if ENV['OS'] != "Windows_NT"
37
+ @unix_socket = '/tmp/ruby-xbee-test.sock'
38
+ File.delete( @unix_socket ) if FileTest.exists?( @unix_socket )
39
+ @server = UNIXServer.new(@unix_socket)
40
+ @s = UNIXSocket.open(@unix_socket)
41
+ else
42
+ @server = TCPServer.new(2000)
43
+ @s = TCPSocket.new('localhost', 2000)
44
+ end
45
+ end
46
+
47
+ ##
48
+ # We test sending the most simplistic packet possible
49
+ # (unknown frame type)
50
+ # +----------------------------+-----------------------------+------+
51
+ # |___________Header___________|____________Frame____________| |
52
+ # | SDelim | DlenMSB | DlenLSB | Type | ID | A T | (Par) | CSum |
53
+ # +--------+---------+---------+------+----+---------+-------+------+
54
+ # | 0x7e | 0x00 | 0x00 | 0x00 | | | | | 0xff |
55
+ # +--------+---------+---------+------+----+-----------------+------+
56
+ def test_frame_00
57
+ Thread.fork(@server.accept) do |client|
58
+ f = [ 0x7e, 0x00, 0x01, 0x00, 0xff]
59
+ client.write(f.pack("c*"))
60
+ client.close
61
+ end
62
+
63
+ xbee_frame = XBee::Frame.new(@s)
64
+ assert_equal(0x00, xbee_frame.api_identifier)
65
+ end
66
+
67
+ ##
68
+ # We test sending the most simplistic packet possible with incorrect checksum
69
+ # (unknown frame type)
70
+ # +----------------------------+-----------------------------+------+
71
+ # |___________Header___________|____________Frame____________| |
72
+ # | SDelim | DlenMSB | DlenLSB | Type | ID | A T | (Par) | CSum |
73
+ # +--------+---------+---------+------+----+---------+-------+------+
74
+ # | 0x7e | 0x00 | 0x00 | 0x00 | | | | | 0x80 |
75
+ # +--------+---------+---------+------+----+-----------------+------+
76
+ def test_bad_checksum
77
+ Thread.fork(@server.accept) do |client|
78
+ f = [ 0x7e, 0x00, 0x01, 0x00, 0x80]
79
+ client.write(f.pack("c*"))
80
+ client.close
81
+ end
82
+
83
+ runtimeerror_raised = assert_raises(RuntimeError) {
84
+ xbee_frame = XBee::Frame.new(@s)
85
+ }
86
+ assert_equal("Bad checksum - data discarded", runtimeerror_raised.message)
87
+ end
88
+
89
+ ##
90
+ # AT Command (0x08) that allows joining by setting NJ to 0xFF; AT = NJ
91
+ # +----------------------------+-----------------------------+------+
92
+ # |___________Header___________|____________Frame____________| |
93
+ # | SDelim | DlenMSB | DlenLSB | Type | ID | A T | (Par) | CSum |
94
+ # +--------+---------+---------+------+----+---------+-------+------+
95
+ # | 0x7e | 0x00 | 0x05 | 0x08 |0x01|0x4e|0x4a| 0xff | 0x5f |
96
+ # +--------+---------+---------+------+----+-----------------+------+
97
+ def test_allow_join
98
+ Thread.fork(@server.accept) do |client|
99
+ f = [ 0x7e, 0x00, 0x05, 0x08, 0x01, 0x4e, 0x4a, 0xff, 0x5f ]
100
+ client.write(f.pack("c*"))
101
+ client.close
102
+ end
103
+
104
+ xbee_frame = XBee::Frame.new(@s)
105
+ assert_equal("\x01NJ\xFF".force_encoding("iso-8859-1"), xbee_frame.cmd_data.force_encoding("iso-8859-1"))
106
+ assert_equal(0x08, xbee_frame.api_identifier)
107
+ end
108
+
109
+ ##
110
+ # AT Command (0x08) for Network Discovery; AT = ND
111
+ # +----------------------------+-----------------------------+------+
112
+ # |___________Header___________|____________Frame____________| |
113
+ # | SDelim | DlenMSB | DlenLSB | Type | ID | A T | (Par) | CSum |
114
+ # +--------+---------+---------+------+----+---------+-------+------+
115
+ # | 0x7e | 0x00 | 0x04 | 0x08 |0x01|0x4e|0x44| | 0x64 |
116
+ # +--------+---------+---------+------+----+-----------------+------+
117
+ def test_network_discovery
118
+ Thread.fork(@server.accept) do |client|
119
+ f = [ 0x7e, 0x00, 0x04, 0x08, 0x01, 0x4e, 0x44, 0x64 ]
120
+ client.write(f.pack("c*"))
121
+ client.close
122
+ end
123
+
124
+ xbee_frame = XBee::Frame.new(@s)
125
+ assert_equal("\x01ND".force_encoding("iso-8859-1"), xbee_frame.cmd_data.force_encoding("iso-8859-1"))
126
+ assert_equal(0x08, xbee_frame.api_identifier)
127
+ end
128
+
129
+ ##
130
+ # AT Command - Queue Parameter Value (0x09); AT = BD
131
+ # +----------------------------+-----------------------------+------+
132
+ # |___________Header___________|____________Frame____________| |
133
+ # | SDelim | DlenMSB | DlenLSB | Type | ID | A T | (Par) | CSum |
134
+ # +--------+---------+---------+------+----+---------+-------+------+
135
+ # | 0x7e | 0x00 | 0x05 | 0x09 |0x01|0x42|0x44| 0x07 | 0x68 |
136
+ # +--------+---------+---------+------+----+-----------------+------+
137
+ def test_at_command_queue_parameter_value
138
+ Thread.fork(@server.accept) do |client|
139
+ f = [ 0x7e, 0x00, 0x05, 0x09, 0x01, 0x42, 0x44, 0x07, 0x68 ]
140
+ client.write(f.pack("c*"))
141
+ client.close
142
+ end
143
+
144
+ xbee_frame = XBee::Frame.new(@s)
145
+ assert_equal("\x01BD\x07".force_encoding("iso-8859-1"), xbee_frame.cmd_data.force_encoding("iso-8859-1"))
146
+ assert_equal(0x09, xbee_frame.api_identifier)
147
+ end
148
+
149
+ ##
150
+ # ZigBee Transmit Request (0x10)
151
+ # A Transmit Request API frame causes the module to send data as an RF packet
152
+ # to the specified destination.
153
+ # +----------------------------+-----------------------------------------------------------------------------------+------+
154
+ # |___________Header___________|_______________________________________Frame_______________________________________| |
155
+ # | SDelim | DlenMSB | DlenLSB | Type | ID | 64-bitDestination | Dest16 | BCRadius | Options | RF Data | CSum |
156
+ # +--------+---------+---------+------+----+--------------------+--------+----------+---------+--------------------+------+
157
+ # | 0x7e | 0x00 | 0x16 | 0x10 |0x01| 0x0013a200400a0127 | 0xfffe | 0x00 | 0x00 | 0x5478446174613041 | 0x13 |
158
+ # +--------+---------+---------+------+----+--------------------+--------+----------+---------+--------------------+------+
159
+ def test_zigbee_transmit_request
160
+ Thread.fork(@server.accept) do |client|
161
+ f = [ 0x7e, 0x00, 0x16, 0x10, 0x01, 0x00, 0x13, 0xa2, 0x00, 0x40, 0x0a, 0x01, 0x27, 0xff, 0xfe, 0x00, 0x00, 0x54, 0x78,
162
+ 0x44, 0x61, 0x74, 0x61, 0x30, 0x41, 0x13 ]
163
+ client.write(f.pack("c*"))
164
+ client.close
165
+ end
166
+
167
+ xbee_frame = XBee::Frame.new(@s)
168
+ assert_equal("\x01\x00\x13\xa2\x00\x40\x0a\x01\x27\xff\xfe\x00\x00\x54\x78\x44\x61\x74\x61\x30\x41".force_encoding("iso-8859-1"), xbee_frame.cmd_data.force_encoding("iso-8859-1"))
169
+ assert_equal(0x10, xbee_frame.api_identifier)
170
+ end
171
+
172
+ ##
173
+ # Explicit Addressing ZigBee Command Frame (0x11)
174
+ # This allows ZigBee application layer fields (endpoint and cluster ID) to be specified for a data transmission.
175
+ # +----------------------------+--------------------------------------------------------------------------------------------------------------------------------+------+
176
+ # |___________Header___________|______________________________________________________________Frame_____________________________________________________________| |
177
+ # | SDelim | DlenMSB | DlenLSB | Type | ID | 64-bitDestination | Dest16 | SrcEndPnt | DestEndPnt | ClusterID | ProfileID | BCRadius | Options | Data Payload | CSum |
178
+ # +--------+---------+---------+------+----+--------------------+--------+-----------+------------+-----------+-----------+----------+---------+----------------+------+
179
+ # | 0x7e | 0x00 | 0x1A | 0x11 |0x01| 0x0000000000000000 | 0xfffe | 0xA0 | 0xA1 | 0x1554 | 0xC105 | 0x00 | 0x00 | 0x547844617461 | 0x3A |
180
+ # +--------+---------+---------+------+----+--------------------+--------+-----------+------------+-----------------------+----------+---------+----------------+------+
181
+ def test_explicit_addressing_zigbee
182
+ Thread.fork(@server.accept) do |client|
183
+ f = [ 0x7e, 0x00, 0x1a, 0x11, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
184
+ 0x00, 0x00, 0xff, 0xfe, 0xa0, 0xa1, 0x15, 0x54, 0xc1, 0x05, 0x00,
185
+ 0x00, 0x54, 0x78, 0x44, 0x61, 0x74, 0x61, 0x3a ]
186
+ client.write(f.pack("c*"))
187
+ client.close
188
+ end
189
+
190
+ xbee_frame = XBee::Frame.new(@s)
191
+ assert_equal("\x01\x00\x00\x00\x00\x00\x00\x00\x00\xff\xfe\xa0\xa1\x15\x54\xc1\x05\x00\x00\x54\x78\x44\x61\x74\x61".force_encoding("iso-8859-1"), xbee_frame.cmd_data.force_encoding("iso-8859-1"))
192
+ assert_equal(0x11, xbee_frame.api_identifier)
193
+ end
194
+
195
+ ##
196
+ # Remote Command Request (0x17)
197
+ # Send remote command to the coordinator and set AD1/DIO1 as a digital input
198
+ # applying the changes to force IO update; AT = D1
199
+ # +----------------------------+-----------------------------------------------------------------------+------+
200
+ # |___________Header___________|_________________________________Frame_________________________________| |
201
+ # | SDelim | DlenMSB | DlenLSB | Type | ID | CoordinatorAddress | Dest16 | RemComOpt | A T | (Par) | CSum |
202
+ # +--------+---------+---------+------+----+--------------------+--------+-----------+---------+-------+------+
203
+ # | 0x7e | 0x00 | 0x10 | 0x17 |0x01| 0x0123456789abcdef | 0xfcfe | 0x02 |0x44|0x31| 0x03 | 0xb3 |
204
+ # +--------+---------+---------+------+----+--------------------+--------+-----------+----+----+-------+------+
205
+ def test_remote_command_request
206
+ Thread.fork(@server.accept) do |client|
207
+ f = [ 0x7e, 0x00, 0x10, 0x17, 0x01, 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef, 0xfc, 0xfe, 0x02, 0x44, 0x31, 0x03, 0xb3 ]
208
+ client.write(f.pack("c*"))
209
+ client.close
210
+ end
211
+
212
+ xbee_frame = XBee::Frame.new(@s)
213
+ assert_equal("\x01\x01\x23\x45\x67\x89\xAB\xCD\xEF\xFC\xFE\x02D1\x03".force_encoding("iso-8859-1"), xbee_frame.cmd_data.force_encoding("iso-8859-1"))
214
+ assert_equal(0x17, xbee_frame.api_identifier)
215
+ end
216
+
217
+ ##
218
+ # Crete Source Route (0x21)
219
+ # This frame creates the source route in the module. A source route specifies
220
+ # the complete route a packet should traverse to get from source to destination.
221
+ # +----------------------------+----------------------------------------------------------------------------------------------+------+
222
+ # |___________Header___________|____________________________________________Frame_____________________________________________| |
223
+ # | SDelim | DlenMSB | DlenLSB | Type | ID | CoordinatorAddress | Dest16 | RouteOpt | NumberOfAddr | Addr 1 | Addr 2 | Addr 3 | CSum |
224
+ # +--------+---------+---------+------+----+--------------------+--------+----------+--------------+--------+--------+--------+------+
225
+ # | 0x7e | 0x00 | 0x14 | 0x21 |0x00| 0x0013a20040401122 | 0x3344 | 0x00 | 0x03 | 0xeeff | 0xccdd | 0xaabb | 0x01 |
226
+ # +--------+---------+---------+------+----+--------------------+--------+-------------------------+--------+--------+--------+------+
227
+ def test_create_source_route
228
+ Thread.fork(@server.accept) do |client|
229
+ f = [ 0x7e, 0x00, 0x14, 0x21, 0x00, 0x00, 0x13, 0xa2, 0x00, 0x40, 0x40, 0x11, 0x22, 0x33, 0x44, 0x00, 0x03, 0xee, 0xff, 0xcc, 0xdd, 0xaa, 0xbb, 01 ]
230
+ client.write(f.pack("c*"))
231
+ client.close
232
+ end
233
+
234
+ xbee_frame = XBee::Frame.new(@s)
235
+ assert_equal("\x00\x00\x13\xa2\x00\x40\x40\x11\x22\x33\x44\x00\x03\xee\xff\xcc\xdd\xaa\xbb".force_encoding("iso-8859-1"), xbee_frame.cmd_data.force_encoding("iso-8859-1"))
236
+ assert_equal(0x21, xbee_frame.api_identifier)
237
+ end
238
+
239
+ ##
240
+ # AT Command Response (0x88) are sent in a response to an AT Command. Some
241
+ # commands trigger multiple responses, like the ATND (Node Discover) command.
242
+ # AT = BD
243
+ # +----------------------------+---------------------------------+------+
244
+ # |___________Header___________|______________Frame______________| |
245
+ # | SDelim | DlenMSB | DlenLSB | Type | ID | A T |Status|Data| CSum |
246
+ # +--------+---------+---------+------+----+---------+------+----+------+
247
+ # | 0x7e | 0x00 | 0x05 | 0x88 |0x01|0x42|0x44| 0x00 | | 0xf0 |
248
+ # +--------+---------+---------+------+----+----------------+----+------+
249
+ def test_command_response
250
+ Thread.fork(@server.accept) do |client|
251
+ f = [ 0x7e, 0x00, 0x05, 0x88, 0x01, 0x42, 0x44, 0x00, 0xf0 ]
252
+ client.write(f.pack("c*"))
253
+ client.close
254
+ end
255
+
256
+ xbee_frame = XBee::Frame.new(@s)
257
+ assert_equal("\x01\x42\x44\x00".force_encoding("iso-8859-1"), xbee_frame.cmd_data.force_encoding("iso-8859-1"))
258
+ assert_equal(0x88, xbee_frame.api_identifier)
259
+ end
260
+
261
+ ##
262
+ # Modem Status (0x8A) These frames are sent on specific conditions
263
+ # This frame is sent by end-device upon joining a network
264
+ # +----------------------------+---------------+------+
265
+ # |___________Header___________|_____Frame_____| |
266
+ # | SDelim | DlenMSB | DlenLSB | Type | Status | CSum |
267
+ # +--------+---------+---------+------+--------+------+
268
+ # | 0x7e | 0x00 | 0x02 | 0x8a | 0x02 | 0x73 |
269
+ # +--------+---------+---------+------+--------+------+
270
+ def test_modem_status_joined_network
271
+ Thread.fork(@server.accept) do |client|
272
+ f = [ 0x7e, 0x00, 0x02, 0x8a, 0x02, 0x73 ]
273
+ client.write(f.pack("c*"))
274
+ client.close
275
+ end
276
+
277
+ xbee_frame = XBee::Frame.new(@s)
278
+ assert_equal("\x02", xbee_frame.cmd_data)
279
+ assert_equal(2, xbee_frame.status[0])
280
+ assert_equal(:Associated, xbee_frame.status[1])
281
+ assert_equal(0x8a, xbee_frame.api_identifier)
282
+ end
283
+
284
+ ##
285
+ # Modem Status (0x8A) These frames are sent on specific conditions
286
+ # This frame is sent by coordinator upon forming a network
287
+ # (currently this is unimplemented and raises a RuntimeError)
288
+ # BORKEN
289
+ # +----------------------------+---------------+------+
290
+ # |___________Header___________|_____Frame_____| |
291
+ # | SDelim | DlenMSB | DlenLSB | Type | Status | CSum |
292
+ # +--------+---------+---------+------+--------+------+
293
+ # | 0x7e | 0x00 | 0x02 | 0x8a | 0x06 | 0x6f |
294
+ # +--------+---------+---------+------+--------+------+
295
+ def test_modem_status_coordinator_started_invalid_status
296
+ Thread.fork(@server.accept) do |client|
297
+ f = [ 0x7e, 0x00, 0x02, 0x8a, 0x06, 0x6f ]
298
+ client.write(f.pack("c*"))
299
+ client.close
300
+ end
301
+
302
+ runtimeerror_raised = assert_raises(RuntimeError) {
303
+ xbee_frame = XBee::Frame.new(@s);
304
+ assert_equal(0x8a, xbee_frame.api_identifier)
305
+ }
306
+
307
+ assert_equal("ModemStatus frame appears to include an invalid status value: 0x06", runtimeerror_raised.message)
308
+ end
309
+
310
+ ##
311
+ # ZigBee Transmit Status (0x8B) When a TX Request is completed, the module
312
+ # sends a TX Status message to indicate successful transfer or failure.
313
+ # +----------------------------+----------------------------------------------------------------------------+------+
314
+ # |___________Header___________|___________________________________Frame____________________________________| |
315
+ # | SDelim | DlenMSB | DlenLSB | Type | ID | Dest16 | TransmitRetryCount | DeliveryStatus | DiscoveryStatus | CSum |
316
+ # +--------+---------+---------+------+----+--------+--------------------+----------------+-----------------+------+
317
+ # | 0x7e | 0x00 | 0x07 | 0x8b |0x01| 0x7c84 | 0x00 | 0x00 | 0x01 | 0x72 |
318
+ # +--------+---------+---------+------+----+--------+--------------------+----------------+-----------------+------+
319
+ def test_zigbee_transmit_status_ok
320
+ Thread.fork(@server.accept) do |client|
321
+ f = [ 0x7e, 0x00, 0x07, 0x8b, 0x01, 0x7c, 0x84, 0x00, 0x00, 0x01, 0x72 ]
322
+ client.write(f.pack("c*"))
323
+ client.close
324
+ end
325
+
326
+ xbee_frame = XBee::Frame.new(@s)
327
+ assert_equal(0x8b, xbee_frame.api_identifier)
328
+ end
329
+
330
+ ##
331
+ # ZigBee Transmit Status (0x8B) with escaped payload
332
+ # +----------------------------+----------------------------------------------------------------------------+------+
333
+ # |___________Header___________|___________________________________Frame____________________________________| |
334
+ # | SDelim | DlenMSB | DlenLSB | Type | ID | Dest16 | TransmitRetryCount | DeliveryStatus | DiscoveryStatus | CSum |
335
+ # +--------+---------+---------+------+----+--------+--------------------+----------------+-----------------+------+
336
+ # | 0x7e | 0x00 | 0x07 | 0x8b |0x01| 0x7d84 | 0x00 | 0x00 | 0x01 | 0x71 |
337
+ # +--------+---------+---------+------+----+--------+--------------------+----------------+-----------------+------+
338
+ def test_zigbee_transmit_status_escaped_dataload
339
+ Thread.fork(@server.accept) do |client|
340
+ # 7d needs to be escaped 7d => 7d 5d
341
+ f = [ 0x7e, 0x00, 0x07, 0x8b, 0x01, 0x7d, 0x5d, 0x84, 0x00, 0x00, 0x01, 0x71 ]
342
+ client.write(f.pack("c*"))
343
+ client.close
344
+ end
345
+
346
+
347
+ xbee_frame = XBee::Frame.new(@s, :API2)
348
+ assert_equal("\x01\x7d\x84\x00\x00\x01".force_encoding("iso-8859-1"), xbee_frame.cmd_data.force_encoding("iso-8859-1"))
349
+ assert_equal(0x8b, xbee_frame.api_identifier)
350
+ end
351
+
352
+ ##
353
+ # ZigBee Receive Packet - (0x90) When the module receives an RF packet,
354
+ # it is sent out the UART with this message.
355
+ # +----------------------------+---------------------------------------------------------------+------+
356
+ # |___________Header___________|_____________________________Frame_____________________________| |
357
+ # | SDelim | DlenMSB | DlenLSB | Type | 64-bit SourceAddr | Src16 | Options | ReceivedData | CSum |
358
+ # +--------+---------+---------+------+--------------------+--------+---------+----------------+------+
359
+ # | 0x7e | 0x00 | 0x12 | 0x90 | 0x0013a20040522baa | 0x7d84 | 0x01 | 0x527844617461 | 0x0D |
360
+ # +--------+---------+---------+------+--------------------+--------+--------------------------+------+
361
+ def test_zigbee_receive_packet
362
+ # 13 is escaped to 7d 33
363
+ # 7d is escaped to 7d 5d
364
+ Thread.fork(@server.accept) do |client|
365
+ f = [ 0x7e, 0x00, 0x12, 0x90, 0x00, 0x7d, 0x33, 0xa2, 0x00, 0x40, 0x52, 0x2b,
366
+ 0xaa, 0x7d, 0x5d, 0x84, 0x01, 0x52, 0x78, 0x44, 0x61, 0x74, 0x61, 0x0D]
367
+ client.write(f.pack("c*"))
368
+ client.close
369
+ end
370
+
371
+ xbee_frame = XBee::Frame.new(@s, :API2)
372
+ assert_equal("\x00\x13\xa2\x00\x40\x52\x2b\xaa\x7d\x84\x01\x52\x78\x44\x61\x74\x61".force_encoding("iso-8859-1"), xbee_frame.cmd_data.force_encoding("iso-8859-1"))
373
+ assert_equal(0x90, xbee_frame.api_identifier)
374
+ end
375
+
376
+ ##
377
+ # ZigBee Receive Packet - (0x90) When the module receives an RF packet,
378
+ # it is sent out the UART with this message.
379
+ # We send this in API Mode 1 - API Operation (AP parameter = 1)
380
+ # +----------------------------+---------------------------------------------------------------+------+
381
+ # |___________Header___________|_____________________________Frame_____________________________| |
382
+ # | SDelim | DlenMSB | DlenLSB | Type | 64-bit SourceAddr | Src16 | Options | ReceivedData | CSum |
383
+ # +--------+---------+---------+------+--------------------+--------+---------+----------------+------+
384
+ # | 0x7e | 0x00 | 0x12 | 0x90 | 0x0013a20040522baa | 0x7d84 | 0x01 | 0x527844617461 | 0x0D |
385
+ # +--------+---------+---------+------+--------------------+--------+--------------------------+------+
386
+ def test_zigbee_receive_packet_api1
387
+ Thread.fork(@server.accept) do |client|
388
+ f = [ 0x7E, 0x00, 0x12, 0x90, 0x00, 0x13, 0xA2, 0x00, 0x40, 0x52, 0x2B, 0xAA,
389
+ 0x7D, 0x84, 0x01, 0x52, 0x78, 0x44, 0x61, 0x74, 0x61, 0x0D ]
390
+ client.write(f.pack("c*"))
391
+ client.close
392
+ end
393
+
394
+ xbee_frame = XBee::Frame.new(@s, :API1)
395
+ assert_equal("\x00\x13\xa2\x00\x40\x52\x2b\xaa\x7d\x84\x01\x52\x78\x44\x61\x74\x61".force_encoding("iso-8859-1"), xbee_frame.cmd_data.force_encoding("iso-8859-1"))
396
+ assert_equal(0x90, xbee_frame.api_identifier)
397
+ end
398
+
399
+ ##
400
+ # ZigBee Explicit Rx Indicator - (0x91) When the modem receives a ZigBee RF packet
401
+ # it is sent out the UART using this message type (when AO=1).
402
+ # +----------------------------+----------------------------------------------------------------------------------------------------------------+------+
403
+ # |___________Header___________|_____________________________________________________Frame______________________________________________________| |
404
+ # | SDelim | DlenMSB | DlenLSB | Type | 64-bit Source Addr | Src.16 | SrcEndPnt | DestEndPnt | ClusterID | ProfileID | Options | Data Payload | CSum |
405
+ # +--------+---------+---------+------+--------------------+--------+-----------+------------+-----------+-----------+---------+----------------+------+
406
+ # | 0x7E | 0x00 | 0x13 | 0x91 | 0x1234567890ABCDEF | 0x1234 | 0xE8 | 0xE8 | 0x0011 | 0xC105 | 0x01 | 0x43 | 0x32 |
407
+ # +--------+---------+---------+------+--------------------+--------+-----------+------------+-----------+-----------+---------+----------------+------+
408
+ # This frame is sent in response to type ZigBee Explicit Addressing Command (Frame Type: 0x11). The cluster 0x0011 is used by Digi as Virtual serial line
409
+ # And use for example in OTA firmware upgrade
410
+ def test_zigbee_explicit_rx_indicator
411
+ Thread.fork(@server.accept) do |client|
412
+ f = [ 0x7E, 0x00, 0x13, 0x91, 0x12, 0x34, 0x56, 0x78, 0x90, 0xAB, 0xCD, 0xEF,
413
+ 0x12, 0x34, 0xE8, 0xE8, 0x00, 0x11, 0xC1, 0x05, 0x01, 0x43, 0x32 ]
414
+ client.write(f.pack("c*"))
415
+ client.close
416
+ end
417
+
418
+
419
+ xbee_frame = XBee::Frame.new(@s)
420
+ assert_equal("\x12\x34\x56\x78\x90\xAB\xCD\xEF\x12\x34\xE8\xE8\x00\x11\xC1\x05\x01\x43".force_encoding("iso-8859-1"), xbee_frame.cmd_data.force_encoding("iso-8859-1"))
421
+ assert_equal(0x91, xbee_frame.api_identifier)
422
+ end
423
+
424
+ ##
425
+ # ZigBee IO Data Sample Rx Indicator (0x92)
426
+ # When the module receives an IO sample fram efrom remote device, it sends the
427
+ # sample out the UART using this frame (when AO=0). Only modules running API
428
+ # firmware will send IO samples out the UART. In a wireless sensor network
429
+ # this frame is probably the most important data carrier for sensory payloads.
430
+ # +----------------------------+
431
+ # |___________Header___________|
432
+ # | SDelim | DlenMSB | DlenLSB |
433
+ # +--------+---------+---------+
434
+ # | 0x7e | 0x00 | 0x14 |
435
+ # +--------+---------+---------+------------------------------------------------------------------------------------+------+
436
+ # |______________________________________________________Frame______________________________________________________| |
437
+ # | Type | 64-bitRemoteSource | SNet16 | ReceiveOptions | NoOfSamples | DChanlMask | AChanlMask | DSample | ASample | CSum |
438
+ # +------+--------------------+--------+----------------+-------------+------------+------------+---------+---------+------+
439
+ # | 0x92 | 0x0012a20040522baa | 0x7c84 | 0x01 | 0x01 | 0x001c | 0x02 | 0x0014 | 0x0225 | 0xf7 |
440
+ # +------+--------------------+--------+----------------+-------------+------------+------------+---------+---------+------+
441
+ def test_zigbee_io_data_sample_rx_indicator
442
+ Thread.fork(@server.accept) do |client|
443
+ f = [ 0x7e, 0x00, 0x14, 0x92, 0x00, 0x12, 0xa2, 0x00, 0x40, 0x52, 0x2b, 0xaa, 0x7c, 0x84, 0x01, 0x01, 0x00, 0x1c, 0x02, 0x00, 0x14, 0x02, 0x25, 0xf7 ]
444
+ client.write(f.pack("c*"))
445
+ client.close
446
+ end
447
+
448
+ xbee_frame = XBee::Frame.new(@s)
449
+ assert_equal("\x00\x12\xa2\x00\x40\x52\x2b\xaa\x7c\x84\x01\x01\x00\x1c\x02\x00\x14\x02\x25".force_encoding("iso-8859-1"), xbee_frame.cmd_data.force_encoding("iso-8859-1"))
450
+ assert_equal(0x92, xbee_frame.api_identifier)
451
+ end
452
+
453
+ ##
454
+ # Remote Command Response (0x97)
455
+ # If a module receives a remote command response RF data frame in response to a Remote AT Command Request,
456
+ # the module will send out a Remote AT Command response message back. Some commands can trigger sending back
457
+ # multiple frames, for example Node Discover (ND).
458
+ # +----------------------------+---------------------------------------------------------------------------+------+
459
+ # |___________Header___________|___________________________________Frame___________________________________| |
460
+ # | SDelim | DlenMSB | DlenLSB | Type | ID | 64-bitRemoteSource | SNet16 | A T | CStatus | CommandData | CSum |
461
+ # +--------+---------+---------+------+----+--------------------+--------+---------+---------+-------------+------+
462
+ # | 0x7e | 0x00 | 0x13 | 0x97 |0x04| 0x0012a20040522baa | 0x7c84 |0x53|0x4c| 0x00 | 0x40522baa | 0x43 |
463
+ # +--------+---------+---------+------+----+--------------------+--------+---------+---------+-------------+------+
464
+ def test_remote_command_response_ok
465
+ Thread.fork(@server.accept) do |client|
466
+ f = [ 0x7e, 0x00, 0x13, 0x97, 0x04, 0x00, 0x12, 0xa2, 0x00, 0x40, 0x52, 0x2b, 0xaa, 0x7c, 0x84, 0x53, 0x4c, 0x00, 0x40, 0x52, 0x2b, 0xaa, 0x43 ]
467
+ client.write(f.pack("c*"))
468
+ client.close
469
+ end
470
+
471
+ xbee_frame = XBee::Frame.new(@s)
472
+ assert_equal(0x97, xbee_frame.api_identifier)
473
+ end
474
+
475
+ ##
476
+ # Remote Command Response (0x97) - Remote Command Transmission Failed
477
+ # At the moment this is generic ReceivedFrame where api_identifier and cmd_data are populated
478
+ # +----------------------------+---------------------------------------------------------------------------+------+
479
+ # |___________Header___________|___________________________________Frame___________________________________| |
480
+ # | SDelim | DlenMSB | DlenLSB | Type | ID | 64-bitRemoteSource | SNet16 | A T | CStatus | CommandData | CSum |
481
+ # +--------+---------+---------+------+----+--------------------+--------+---------+---------+-------------+------+
482
+ # | 0x7e | 0x00 | 0x13 | 0x97 |0x04| 0x0012a20040522baa | 0x7c84 |0x53|0x4c| 0x04 | 0x40522baa | 0x3f |
483
+ # +--------+---------+---------+------+----+--------------------+--------+---------+---------+-------------+------+
484
+ def test_remote_command_response_transmission_failed
485
+ Thread.fork(@server.accept) do |client|
486
+ f = [ 0x7e, 0x00, 0x13, 0x97, 0x04, 0x00, 0x12, 0xa2, 0x00, 0x40, 0x52, 0x2b, 0xaa, 0x7c, 0x84, 0x53, 0x4c, 0x04, 0x40, 0x52, 0x2b, 0xaa, 0x3f ]
487
+ client.write(f.pack("c*"))
488
+ client.close
489
+ end
490
+
491
+ xbee_frame = XBee::Frame.new(@s)
492
+ assert_equal(0x97, xbee_frame.api_identifier)
493
+ assert_equal("\x04\x00\x12\xa2\x00\x40\x52\x2b\xaa\x7c\x84\x53\x4c\x04\x40\x52\x2b\xaa".force_encoding("iso-8859-1"), xbee_frame.cmd_data.force_encoding("iso-8859-1"))
494
+ end
495
+
496
+ ##
497
+ # Remote Command Response (0x97) - Invalid status byte
498
+ # At the moment this is generic ReceivedFrame where api_identifier and cmd_data are populated
499
+ # +----------------------------+---------------------------------------------------------------------------+------+
500
+ # |___________Header___________|___________________________________Frame___________________________________| |
501
+ # | SDelim | DlenMSB | DlenLSB | Type | ID | 64-bitRemoteSource | SNet16 | A T | CStatus | CommandData | CSum |
502
+ # +--------+---------+---------+------+----+--------------------+--------+---------+---------+-------------+------+
503
+ # | 0x7e | 0x00 | 0x13 | 0x97 |0x04| 0x0012a20040522baa | 0x7c84 |0x53|0x4c| 0x05 | 0x40522baa | 0x3e |
504
+ # +--------+---------+---------+------+----+--------------------+--------+---------+---------+-------------+------+
505
+ def test_remote_command_response_invalid_status_byte
506
+ Thread.fork(@server.accept) do |client|
507
+ f = [ 0x7e, 0x00, 0x13, 0x97, 0x04, 0x00, 0x12, 0xa2, 0x00, 0x40, 0x52, 0x2b, 0xaa, 0x7c, 0x84, 0x53, 0x4c, 0x05, 0x40, 0x52, 0x2b, 0xaa, 0x3e ]
508
+ client.write(f.pack("c*"))
509
+ client.close
510
+ end
511
+
512
+ runtimeerror_raised = assert_raises(RuntimeError) {
513
+ xbee_frame = XBee::Frame.new(@s)
514
+ assert_equal(0x97, xbee_frame.api_identifier)
515
+ }
516
+ assert_equal("AT Command Response frame appears to include an invalid status: 0x05", runtimeerror_raised.message)
517
+
518
+ end
519
+
520
+ ##
521
+ # Teardown
522
+ def teardown
523
+ @s.close
524
+ @server.close
525
+ unless ENV['OS'] == "Windows_NT"
526
+ File.delete( @unix_socket ) if FileTest.exists?( @unix_socket )
527
+ end
528
+ end
529
+
530
+ end
@@ -0,0 +1,52 @@
1
+ $: << File.dirname(__FILE__)
2
+ require 'test_helper'
3
+ require 'ruby-xbee'
4
+
5
+ ##
6
+ # The goal of these tests is simply to instantiate the main XBee class for
7
+ # API mode access. If a device is present and configured a simple association
8
+ # check retrieval is made.
9
+ class RubyXbeeApimodeSetup < MiniTest::Test
10
+ def setup
11
+ @xbee_missing = false
12
+ @uart_config = XBee::Config::XBeeUARTConfig.new()
13
+ @xbee_usbdev_str = TOPLEVEL_BINDING.eval('self').instance_variable_get(:@xbee_usbdev_str)
14
+ begin
15
+ @xbee = XBee::BaseAPIModeInterface.new(@xbee_usbdev_str, @uart_config, :API, :SYNC)
16
+ rescue
17
+ @xbee_missing = true
18
+ end
19
+ end
20
+
21
+ def test_uart
22
+ assert_kind_of String, @xbee_usbdev_str
23
+ assert_equal 9600, @uart_config.baud
24
+ assert_equal 8, @uart_config.data_bits
25
+ assert_equal 0, @uart_config.parity
26
+ assert_equal 1, @uart_config.stop_bits
27
+ end
28
+
29
+ def test_operation_mode
30
+ unless @xbee_missing
31
+ assert_equal :API, @xbee.operation_mode
32
+ @xbee.operation_mode = :AT
33
+ assert_equal :AT, @xbee.operation_mode
34
+ @xbee.operation_mode = :API
35
+ assert_equal :API, @xbee.operation_mode
36
+ end
37
+ end
38
+
39
+ def test_transmission_mode
40
+ unless @xbee_missing
41
+ assert_equal :SYNC, @xbee.transmission_mode
42
+ @xbee.transmission_mode = :ASYNC
43
+ assert_equal :ASYNC, @xbee.transmission_mode
44
+ @xbee.transmission_mode = :SYNC
45
+ assert_equal :SYNC, @xbee.transmission_mode
46
+ end
47
+ end
48
+
49
+ def test_association_indication
50
+ assert_equal 0, @xbee.association_indication unless @xbee_missing
51
+ end
52
+ end
@@ -3,7 +3,7 @@ require 'test_helper'
3
3
  require 'version'
4
4
 
5
5
  # The most simple test there can possibly BE, let's check constant for constant
6
- class RubyXbeeTest < MiniTest::Unit::TestCase
6
+ class RubyXbeeTest < MiniTest::Test
7
7
  def setup
8
8
  @xbee_version_major = ::XBee::Version::MAJOR
9
9
  @xbee_version_minor = ::XBee::Version::MINOR
@@ -13,8 +13,8 @@ class RubyXbeeTest < MiniTest::Unit::TestCase
13
13
 
14
14
  def test_version_matches_testsuite
15
15
  assert_equal 1, @xbee_version_major
16
- assert_equal 1, @xbee_version_minor
16
+ assert_equal 2, @xbee_version_minor
17
17
  assert_equal 0, @xbee_version_patch
18
- assert_equal '1.1.0', @xbee_version_string
18
+ assert_equal '1.2.0', @xbee_version_string
19
19
  end
20
20
  end
data/test/test_helper.rb CHANGED
@@ -1,22 +1,25 @@
1
- require 'rubygems'
2
1
  require 'versioncheck'
3
- require 'minitest/autorun'
4
- require 'minitest/reporters'
5
2
 
6
3
  rb_vc = VersionCheck.rubyversion
7
- if !rb_vc.have_version?(2,0)
4
+ if !rb_vc.have_version?(2,1)
8
5
  require 'simplecov'
9
6
  SimpleCov.command_name 'MiniTest'
10
7
  SimpleCov.start
11
8
  end
12
9
 
10
+ if ENV['TRAVIS'] == "true" && ENV['CI'] =="true"
11
+ require 'coveralls'
12
+ Coveralls.wear!
13
+ end
14
+
15
+ require 'rubygems'
16
+ require 'minitest/autorun'
17
+ require 'minitest/reporters'
18
+
13
19
  MiniTest::Reporters.use!
14
20
 
15
21
  $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
16
22
  $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'bin'))
17
23
  $LOAD_PATH.unshift(File.dirname(__FILE__))
18
24
 
19
- require 'ruby_xbee'
20
- require 'coveralls'
21
-
22
- Coveralls.wear!
25
+ require 'ruby_xbee'