ruby-xbee 1.1.0 → 1.2.0

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.
@@ -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'