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.
data/lib/module_config.rb CHANGED
@@ -73,5 +73,22 @@ module XBee
73
73
  super("NI", default)
74
74
  end
75
75
  end
76
+
77
+ class ApiEnableMode < RFModuleParameter
78
+ def initialize(default = 0x01)
79
+ unless default == 0x01 or default == 0x02
80
+ raise "XBee AP parameter range can be 1-2; 1 = API-enabled; 2 = API-enabled (with escaped control characters)"
81
+ end
82
+ super("AP", default)
83
+ end
84
+
85
+ def in_symbol
86
+ unless self.value == 0x01 or self.value == 0x02
87
+ raise "XBee AP parameter invalid range! Valid range 1-2; Set to: #{self.value}"
88
+ end
89
+ return :API1 if self.value == 0x01
90
+ return :API2 if self.value == 0x02
91
+ end
92
+ end
76
93
  end
77
94
  end
data/lib/ruby_xbee.rb CHANGED
@@ -66,12 +66,12 @@ module XBee
66
66
  # This is it, the base class where it all starts. Command mode or API mode, version 1 or version 2, all XBees descend
67
67
  # from this class.
68
68
  class RFModule
69
-
69
+
70
70
  VERSION = "2.1"
71
-
71
+
72
72
  include XBee
73
73
  include Config
74
- attr_accessor :xbee_serialport, :xbee_uart_config, :guard_time, :command_mode_timeout, :command_character, :node_discover_timeout, :node_identifier, :operation_mode, :transmission_mode
74
+ attr_accessor :xbee_serialport, :xbee_uart_config, :guard_time, :command_mode_timeout, :command_character, :node_discover_timeout, :node_identifier, :operation_mode, :api_mode, :transmission_mode
75
75
  attr_reader :serial_number, :hardware_rev, :firmware_rev
76
76
 
77
77
  def version
@@ -86,10 +86,10 @@ module XBee
86
86
  raise "uart_config must be an instance of XBeeUARTConfig for this to work"
87
87
  end
88
88
  unless operation_mode == :AT || operation_mode == :API
89
- raise "XBee operation_mode must be either AT or API"
89
+ raise "XBee operation_mode must be either :AT or :API"
90
90
  end
91
91
  unless transmission_mode == :SYNC || transmission_mode == :ASYNC
92
- raise "XBee transmission_mode must be either SYNC (Synchronous) or ASYNC (Asynchronous)"
92
+ raise "XBee transmission_mode must be either :SYNC (Synchronous) or :ASYNC (Asynchronous)"
93
93
  end
94
94
  self.xbee_uart_config = uart_config
95
95
  @xbee_serialport = SerialPort.new( xbee_usbdev_str, uart_config.baud, uart_config.data_bits, uart_config.stop_bits, uart_config.parity )
@@ -100,6 +100,7 @@ module XBee
100
100
  @node_discover_timeout = NodeDiscoverTimeout.new
101
101
  @node_identifier = NodeIdentifier.new
102
102
  @operation_mode = operation_mode
103
+ @api_mode = ApiEnableMode.new
103
104
  @transmission_mode = transmission_mode
104
105
  end
105
106
 
@@ -123,7 +124,7 @@ module XBee
123
124
  case type
124
125
  when :short
125
126
  1200
126
- when :long
127
+ when :long
127
128
  3000
128
129
  else 3000
129
130
  end
@@ -0,0 +1,132 @@
1
+ $: << File.dirname(__FILE__)
2
+ require 'ruby_xbee_api_frame_test'
3
+ # Test cases for ZigBee Explicit Addressing Command (Frame Type: 0x11)
4
+ # Test cases to cover the construction/sending and receiving/decoding
5
+ # scenarios.
6
+ class ExplicitAddressingCommand < RubyXbeeApiFrameTest
7
+
8
+ ##
9
+ # Explicit Addressing ZigBee Command Frame (0x11)
10
+ # This allows ZigBee application layer fields (endpoint and cluster ID) to be specified for a data transmission.
11
+ # Here we send a valid OTA start request without encryption and OTA password set to broadcast destination network
12
+ # +----------------------------+--------------------------------------------------------------------------------------------------------------------------------+------+
13
+ # |___________Header___________|______________________________________________________________Frame_____________________________________________________________| |
14
+ # | SDelim | DlenMSB | DlenLSB | Type | ID | 64-bitDestination | Dest16 | SrcEndPnt | DestEndPnt | ClusterID | ProfileID | BCRadius | Options | Data Payload | CSum |
15
+ # +--------+---------+---------+------+----+--------------------+--------+-----------+------------+-----------+-----------+----------+---------+----------------+------+
16
+ # | 0x7e | 0x00 | 0x15 | 0x11 |0x10| 0x0101010101010ABC | 0xfffe | 0xE8 | 0xE8 | 0x1000 | 0xC105 | 0x00 | 0x00 | 0x00 | 0x6F |
17
+ # +--------+---------+---------+------+----+--------------------+--------+-----------+------------+-----------------------+----------+---------+----------------+------+
18
+ def test_eac_receive_ota_init_no_password
19
+ Thread.fork(@server.accept) do |client|
20
+ f = [ 0x7E, 0x00, 0x15, 0x11, 0x10, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x0A, 0xBC, 0xFF, 0xFE, 0xE8, 0xE8, 0x10, 0x00, 0xC1, 0x05, 0x00, 0x00, 0x00, 0x6F ]
21
+ client.write(f.pack("c*"))
22
+ client.close
23
+ end
24
+
25
+
26
+ xbee_frame = XBee::Frame.new(@s)
27
+ assert_equal("\x10\x01\x01\x01\x01\x01\x01\x0A\xBC\xFF\xFE\xE8\xE8\x10\x00\xC1\x05\x00\x00\x00".force_encoding("iso-8859-1"), xbee_frame.cmd_data.force_encoding("iso-8859-1"))
28
+ assert_equal(0x11, xbee_frame.api_identifier)
29
+ end
30
+
31
+ ##
32
+ # Explicit Addressing ZigBee Command Frame (0x11)
33
+ # This allows ZigBee application layer fields (endpoint and cluster ID) to be specified for a data transmission.
34
+ # Here we send a valid OTA start request without encryption and OTA password set to broadcast destination network
35
+ # +----------------------------+--------------------------------------------------------------------------------------------------------------------------------+------+
36
+ # |___________Header___________|______________________________________________________________Frame_____________________________________________________________| |
37
+ # | SDelim | DlenMSB | DlenLSB | Type | ID | 64-bitDestination | Dest16 | SrcEndPnt | DestEndPnt | ClusterID | ProfileID | BCRadius | Options | Data Payload | CSum |
38
+ # +--------+---------+---------+------+----+--------------------+--------+-----------+------------+-----------+-----------+----------+---------+----------------+------+
39
+ # | 0x7e | 0x00 | 0x15 | 0x11 |0x10| 0x0101010101010ABC | 0xfffe | 0xE8 | 0xE8 | 0x1000 | 0xC105 | 0x00 | 0x00 | 0x00 | 0x6F |
40
+ # +--------+---------+---------+------+----+--------------------+--------+-----------+------------+-----------------------+----------+---------+----------------+------+
41
+ def test_eac_create_ota_init_no_password_default_payload_pack
42
+ Thread.fork(@server.accept) do |client|
43
+ frame = XBee::Frame::ExplicitAddressingCommand.new(0x10, 0x0101010101010ABC, 0x0000fffe, 0xE8, 0xE8, 0x1000, 0xC105, 0x00, 0x00)
44
+ client.write(frame._dump)
45
+ client.close
46
+ end
47
+
48
+ xbee_frame = XBee::Frame.new(@s)
49
+ assert_equal("\x10\x01\x01\x01\x01\x01\x01\x0A\xBC\xFF\xFE\xE8\xE8\x10\x00\xC1\x05\x00\x00\x00".force_encoding("iso-8859-1"), xbee_frame.cmd_data.force_encoding("iso-8859-1"))
50
+ assert_equal(0x11, xbee_frame.api_identifier)
51
+
52
+ # Build the frame from the received data
53
+ frame = XBee::Frame::ExplicitAddressingCommand.new()
54
+ frame.cmd_data = xbee_frame.cmd_data
55
+
56
+ assert_equal 0x10, frame.frame_id
57
+ assert_equal 0x0101010101010ABC, frame.destination_address
58
+ assert_equal 0xfffe, frame.destination_network
59
+ assert_equal 0xE8, frame.source_endpoint
60
+ assert_equal 0xE8, frame.destination_endpoint
61
+ assert_equal 0x1000, frame.cluster_id
62
+ assert_equal 0xc105, frame.profile_id
63
+ assert_equal 0x00, frame.broadcast_radius
64
+ assert_equal 0x00, frame.transmit_options
65
+ assert_equal "\0", frame.payload
66
+
67
+ end
68
+
69
+ ##
70
+ # Explicit Addressing ZigBee Command Frame (0x11)
71
+ # This allows ZigBee application layer fields (endpoint and cluster ID) to be specified for a data transmission.
72
+ # Here we send a valid OTA start request without encryption and OTA password set to broadcast destination network
73
+ # +----------------------------+--------------------------------------------------------------------------------------------------------------------------------+------+
74
+ # |___________Header___________|______________________________________________________________Frame_____________________________________________________________| |
75
+ # | SDelim | DlenMSB | DlenLSB | Type | ID | 64-bitDestination | Dest16 | SrcEndPnt | DestEndPnt | ClusterID | ProfileID | BCRadius | Options | Data Payload | CSum |
76
+ # +--------+---------+---------+------+----+--------------------+--------+-----------+------------+-----------+-----------+----------+---------+----------------+------+
77
+ # | 0x7e | 0x00 | 0x15 | 0x11 |0x10| 0x0101010101010ABC | 0xfffe | 0xE8 | 0xE8 | 0x1000 | 0xC105 | 0x00 | 0x00 | 0x00 | 0x6F |
78
+ # +--------+---------+---------+------+----+--------------------+--------+-----------+------------+-----------------------+----------+---------+----------------+------+
79
+ # This is an interesting packet because in AP2 (with escaped control characters) The Frame Type gets escaped
80
+ def test_eac_create_ota_init_no_password_default_payload_pack_ap2
81
+ Thread.fork(@server.accept) do |client|
82
+ frame = XBee::Frame::ExplicitAddressingCommand.new(0x10, 0x0101010101010ABC, 0x0000fffe, 0xE8, 0xE8, 0x1000, 0xC105, 0x00, 0x00)
83
+ client.write(frame._dump(:API2))
84
+ client.close
85
+ end
86
+
87
+ xbee_frame = XBee::Frame.new(@s, :API2)
88
+ assert_equal("\x10\x01\x01\x01\x01\x01\x01\x0A\xBC\xFF\xFE\xE8\xE8\x10\x00\xC1\x05\x00\x00\x00".force_encoding("iso-8859-1"), xbee_frame.cmd_data.force_encoding("iso-8859-1"))
89
+ assert_equal(0x11, xbee_frame.api_identifier)
90
+
91
+ # Build the frame from the received data
92
+ frame = XBee::Frame::ExplicitAddressingCommand.new()
93
+ frame.cmd_data = xbee_frame.cmd_data
94
+
95
+ assert_equal 0x10, frame.frame_id
96
+ assert_equal 0x0101010101010ABC, frame.destination_address
97
+ assert_equal 0xfffe, frame.destination_network
98
+ assert_equal 0xE8, frame.source_endpoint
99
+ assert_equal 0xE8, frame.destination_endpoint
100
+ assert_equal 0x1000, frame.cluster_id
101
+ assert_equal 0xc105, frame.profile_id
102
+ assert_equal 0x00, frame.broadcast_radius
103
+ assert_equal 0x00, frame.transmit_options
104
+ assert_equal "\0", frame.payload
105
+
106
+ end
107
+
108
+ ##
109
+ # Explicit Addressing ZigBee Command Frame (0x11)
110
+ # This allows ZigBee application layer fields (endpoint and cluster ID) to be specified for a data transmission.
111
+ # Here we send a valid OTA start request without encryption and OTA password set to broadcast destination network
112
+ # +----------------------------+--------------------------------------------------------------------------------------------------------------------------------+------+
113
+ # |___________Header___________|______________________________________________________________Frame_____________________________________________________________| |
114
+ # | SDelim | DlenMSB | DlenLSB | Type | ID | 64-bitDestination | Dest16 | SrcEndPnt | DestEndPnt | ClusterID | ProfileID | BCRadius | Options | Data Payload | CSum |
115
+ # +--------+---------+---------+------+----+--------------------+--------+-----------+------------+-----------+-----------+----------+---------+----------------+------+
116
+ # | 0x7e | 0x00 | 0x15 | 0x11 |0x10| 0x0101010101010ABC | 0xfffe | 0xE8 | 0xE8 | 0x1000 | 0xC105 | 0x00 | 0x00 | 0x00 | 0x6F |
117
+ # +--------+---------+---------+------+----+--------------------+--------+-----------+------------+-----------------------+----------+---------+----------------+------+
118
+ # Here we send the packet in AP2 mode (escaped) but receive the packet in AP1 mode (unescaped) - the world should collapse because of bad checksum
119
+ def test_eac_create_ota_init_no_password_default_payload_pack_ap2
120
+ Thread.fork(@server.accept) do |client|
121
+ frame = XBee::Frame::ExplicitAddressingCommand.new(0x10, 0x0101010101010ABC, 0x0000fffe, 0xE8, 0xE8, 0x1000, 0xC105, 0x00, 0x00)
122
+ client.write(frame._dump(:API2))
123
+ client.close
124
+ end
125
+
126
+ runtimeerror_raised = assert_raises(RuntimeError) {
127
+ xbee_frame = XBee::Frame.new(@s)
128
+ }
129
+ assert_equal("Bad checksum - data discarded", runtimeerror_raised.message)
130
+
131
+ end
132
+ end
@@ -0,0 +1,54 @@
1
+ $: << File.dirname(__FILE__)
2
+ require 'ruby_xbee_api_frame_test'
3
+ # Test cases for ZigBee Explicit Rx Indicator (Frame Type: 0x91)
4
+ # Test cases to cover the construction/sending and receiving/decoding
5
+ # scenarios.
6
+ class ExplicitRxIndicator < RubyXbeeApiFrameTest
7
+ ##
8
+ # ZigBee Explicit Rx Indicator - (0x91) When the modem receives a ZigBee RF packet
9
+ # it is sent out the UART using this message type (when AO=1).
10
+ # +----------------------------+----------------------------------------------------------------------------------------------------------------+------+
11
+ # |___________Header___________|_____________________________________________________Frame______________________________________________________| |
12
+ # | SDelim | DlenMSB | DlenLSB | Type | 64-bit Source Addr | Src.16 | SrcEndPnt | DestEndPnt | ClusterID | ProfileID | Options | Data Payload | CSum |
13
+ # +--------+---------+---------+------+--------------------+--------+-----------+------------+-----------+-----------+---------+----------------+------+
14
+ # | 0x7E | 0x00 | 0x13 | 0x91 | 0x1234567890ABCDEF | 0x1234 | 0xE8 | 0xE8 | 0x0011 | 0xC105 | 0x01 | 0x43 | 0x32 |
15
+ # +--------+---------+---------+------+--------------------+--------+-----------+------------+-----------+-----------+---------+----------------+------+
16
+ # 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
17
+ # And use for example in OTA firmware upgrade
18
+ def test_zigbee_explicit_rx_indicator_xmodem_start
19
+ Thread.fork(@server.accept) do |client|
20
+ f = [ 0x7E, 0x00, 0x13, 0x91, 0x12, 0x34, 0x56, 0x78, 0x90, 0xAB, 0xCD, 0xEF,
21
+ 0x12, 0x34, 0xE8, 0xE8, 0x00, 0x11, 0xC1, 0x05, 0x01, 0x43, 0x32 ]
22
+ client.write(f.pack("c*"))
23
+ client.close
24
+ end
25
+
26
+ xbee_frame = XBee::Frame.new(@s)
27
+
28
+ assert_equal 0x91, xbee_frame.api_identifier
29
+ assert_equal 0x1234567890ABCDEF, xbee_frame.source_address
30
+ assert_equal 0x1234, xbee_frame.source_network
31
+ assert_equal 0xE8, xbee_frame.source_endpoint
32
+ assert_equal 0xE8, xbee_frame.destination_endpoint
33
+ assert_equal 0x0011, xbee_frame.cluster_id
34
+ assert_equal 0xc105, xbee_frame.profile_id
35
+ assert_equal 0x01, xbee_frame.receive_options
36
+ assert_equal "C".force_encoding("iso-8859-1"), xbee_frame.received_data.force_encoding("iso-8859-1")
37
+
38
+
39
+ # Let's construct a frame from scratch and use the data previously received
40
+ frame = XBee::Frame::ExplicitRxIndicator.new
41
+ frame.cmd_data = xbee_frame.cmd_data
42
+
43
+ assert_equal frame.api_identifier, xbee_frame.api_identifier
44
+ assert_equal frame.source_address, xbee_frame.source_address
45
+ assert_equal frame.source_network, xbee_frame.source_network
46
+ assert_equal frame.source_endpoint, xbee_frame.source_endpoint
47
+ assert_equal frame.destination_endpoint, xbee_frame.destination_endpoint
48
+ assert_equal frame.cluster_id, xbee_frame.cluster_id
49
+ assert_equal frame.profile_id, xbee_frame.profile_id
50
+ assert_equal frame.receive_options, xbee_frame.receive_options
51
+ assert_equal frame.received_data, xbee_frame.received_data
52
+
53
+ end
54
+ end