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