summaryrefslogtreecommitdiff
path: root/test
diff options
context:
space:
mode:
authorInga Stotland <inga.stotland@intel.com>2020-05-13 19:20:33 -0700
committerBrian Gix <brian.gix@intel.com>2020-05-14 06:51:44 -0700
commit17dc8d1fd803896c22d0611f0c9e1800cae875d6 (patch)
tree803817258fe6ed90e4b66d6371b3ba6414627699 /test
parent572f0eb599f6ecbcff6df6440863573321f7ac73 (diff)
downloadbluez-17dc8d1fd803896c22d0611f0c9e1800cae875d6.tar.gz
test: Fix payload and model opcode packing in test-mesh
Use correct packing of multi-byte values in message payload bytearray. For example, a 2-byte opcode 0x8204 is packed as 0x82 0x04, i.e. in natural order. Add transaction ID parameter to "set" commands of generic On/Off model. Server will ignore the identical commands with the same transaction ID, source and destination during a timeout period of 6 seconds.
Diffstat (limited to 'test')
-rwxr-xr-xtest/test-mesh94
1 files changed, 69 insertions, 25 deletions
diff --git a/test/test-mesh b/test/test-mesh
index 66055e2de..38f0c0a74 100755
--- a/test/test-mesh
+++ b/test/test-mesh
@@ -146,6 +146,8 @@ APP_VERSION_ID = 0x0001
VENDOR_ID_NONE = 0xffff
+TRANSACTION_TIMEOUT = 6
+
app = None
bus = None
mainloop = None
@@ -330,7 +332,7 @@ def print_state(state):
print('ON')
else:
print('UNKNOWN')
-class PubTimer():
+class ModTimer():
def __init__(self):
self.seconds = None
self.func = None
@@ -473,18 +475,18 @@ class Element(dbus.service.Object):
@dbus.service.method(MESH_ELEMENT_IFACE,
in_signature="qqvay", out_signature="")
- def MessageReceived(self, source, key, destination, data):
+ def MessageReceived(self, source, key, dest, data):
print(('Message Received on Element %02x') % self.index, end='')
print(', src=', format(source, '04x'), end='')
- if isinstance(destination, int):
- print(', dst=%04x' % destination)
- elif isinstance(destination, dbus.Array):
- dst_str = array_to_string(destination)
+ if isinstance(dest, int):
+ print(', dst=%04x' % dest)
+ elif isinstance(dest, dbus.Array):
+ dst_str = array_to_string(dest)
print(', dst=' + dst_str)
for model in self.models:
- model.process_message(source, key, data)
+ model.process_message(source, dest, key, data)
@dbus.service.method(MESH_ELEMENT_IFACE,
in_signature="qa{sv}", out_signature="")
@@ -528,7 +530,7 @@ class Model():
def get_vendor(self):
return self.vendor
- def process_message(self, source, key, data):
+ def process_message(self, source, dest, key, data):
return
def set_publication(self, period):
@@ -576,6 +578,9 @@ class Model():
class OnOffServer(Model):
def __init__(self, model_id):
Model.__init__(self, model_id)
+ self.tid = None
+ self.last_src = 0x0000
+ self.last_dst = 0x0000
self.cmd_ops = { 0x8201, # get
0x8202, # set
0x8203, # set unacknowledged
@@ -584,48 +589,74 @@ class OnOffServer(Model):
print("OnOff Server ")
self.state = 0
print_state(self.state)
- self.timer = PubTimer()
+ self.pub_timer = ModTimer()
+ self.t_timer = ModTimer()
- def process_message(self, source, key, data):
+ def process_message(self, source, dest, key, data):
datalen = len(data)
- if datalen != 2 and datalen != 3:
+ if datalen != 2 and datalen != 4:
# The opcode is not recognized by this model
return
if datalen == 2:
- op_tuple=struct.unpack('<H',bytes(data))
+ op_tuple=struct.unpack('>H',bytes(data))
opcode = op_tuple[0]
+
if opcode != 0x8201:
# The opcode is not recognized by this model
return
print('Get state')
- elif datalen == 3:
- opcode,self.state=struct.unpack('<HB',bytes(data))
+ elif datalen == 4:
+ opcode,self.state, tid = struct.unpack('>HBB',
+ bytes(data))
+
if opcode != 0x8202 and opcode != 0x8203:
# The opcode is not recognized by this model
return
print_state(self.state)
- rsp_data = struct.pack('<HB', 0x8204, self.state)
+ if (self.tid != None and self.tid == tid and
+ self.last_src == source and
+ self.last_dst == dest):
+ # Ignore duplicate transaction
+ return
+
+ self.t_timer.cancel()
+ self.tid = tid
+ self.last_src = source
+ self.last_dst = dest
+ self.t_timer.start(TRANSACTION_TIMEOUT, self.t_track)
+
+ # Unacknowledged "set"
+ if opcode == 0x8203:
+ return
+
+ rsp_data = struct.pack('>HB', 0x8204, self.state)
self.send_message(source, key, rsp_data)
+ def t_track(self):
+ self.t_timer.cancel()
+ self.tid = None
+ self.last_src = 0x0000
+ self.last_dst = 0x0000
+
def set_publication(self, period):
self.pub_period = period
if period == 0:
- self.timer.cancel()
+ self.pub_timer.cancel()
return
# We do not handle ms in this example
if period < 1000:
return
- self.timer.start(period/1000, self.publish)
+ self.pub_timer.start(period/1000, self.publish)
def publish(self):
print('Publish')
- data = struct.pack('<HB', 0x8204, self.state)
+ data = struct.pack('>HB', 0x8204, self.state)
self.send_publication(data)
########################
@@ -634,6 +665,8 @@ class OnOffServer(Model):
class OnOffClient(Model):
def __init__(self, model_id):
Model.__init__(self, model_id)
+ self.tid = 0
+ self.data = None
self.cmd_ops = { 0x8201, # get
0x8202, # set
0x8203, # set unacknowledged
@@ -646,16 +679,23 @@ class OnOffClient(Model):
def get_state(self, dest, key):
opcode = 0x8201
- data = struct.pack('<H', opcode)
- self._send_message(dest, key, data)
+ self.data = struct.pack('>H', opcode)
+ self._send_message(dest, key, self.data)
def set_state(self, dest, key, state):
opcode = 0x8202
print('Set state:', state)
- data = struct.pack('<HB', opcode, state)
- self._send_message(dest, key, data)
+ self.data = struct.pack('>HBB', opcode, state, self.tid)
+ self.tid = (self.tid + 1) % 255
+ self._send_message(dest, key, self.data)
+
+ def repeat(self, dest, key):
+ if self.data != None:
+ self._send_message(dest, key, self.data)
+ else:
+ print('No previous command stored')
- def process_message(self, source, key, data):
+ def process_message(self, source, dest, key, data):
print('OnOffClient process message len = ', end = '')
datalen = len(data)
print(datalen)
@@ -664,7 +704,7 @@ class OnOffClient(Model):
# The opcode is not recognized by this model
return
- opcode, state = struct.unpack('<HB',bytes(data))
+ opcode, state = struct.unpack('>HB',bytes(data))
if opcode != 0x8204 :
# The opcode is not recognized by this model
@@ -919,12 +959,14 @@ class ClientMenu(Menu):
self.__cmd_set_state_off),
'on': MenuItem(' - set state ON',
self.__cmd_set_state_on),
+ 'repeat': MenuItem(' - repeat last command',
+ self.__cmd_repeat_transaction),
'back': MenuItem(' - back to main menu',
self.__cmd_main_menu),
'quit': MenuItem(' - exit the test', app_exit)
}
- Menu.__init__(self, 'On/Off Clien Menu', menu_items)
+ Menu.__init__(self, 'On/Off Client Menu', menu_items)
def __cmd_main_menu(self):
switch_menu(MAIN_MENU)
@@ -938,6 +980,8 @@ class ClientMenu(Menu):
def __cmd_set_state_on(self):
app.elements[1].models[0].set_state(dst_addr, app_idx, 1)
+ def __cmd_repeat_transaction(self):
+ app.elements[1].models[0].repeat(dst_addr, app_idx)
def set_value(str_value, min, max):