Merge lp:~cypressyew/checkbox/bt4-HOGP into lp:checkbox

Proposed by Po-Hsu Lin
Status: Rejected
Rejected by: Po-Hsu Lin
Proposed branch: lp:~cypressyew/checkbox/bt4-HOGP
Merge into: lp:checkbox
Diff against target: 283 lines (+267/-0)
2 files modified
providers/plainbox-provider-checkbox/bin/bt_connect (+221/-0)
providers/plainbox-provider-checkbox/jobs/bluetooth.txt.in (+46/-0)
To merge this branch: bzr merge lp:~cypressyew/checkbox/bt4-HOGP
Reviewer Review Type Date Requested Status
Yung Shen (community) Abstain
Ara Pulido (community) Needs Fixing
Chris Wayne Pending
Review via email: mp+288612@code.launchpad.net

Description of the change

Add a manifest request for asking tester about BT 4.x capability of this system.
Add a BT 4.x specific test case for HID devices (keyboard / mouse)

To post a comment you must log in.
Revision history for this message
Po-Hsu Lin (cypressyew) wrote :

The reason why we're only adding a new test case for HID is that, this HID Over GATT Profile is a new feature for Bluetooth 4.x devices. For those old profiles like obex, they are not a new stuff, so leave it as-is for back-ward compatibility test.

Revision history for this message
Ara Pulido (ara) wrote :

Can we do the test more automated, please?

Things that we can automate: The name of the device may be configurable, enabling bluetooth and selecting the configured BT device should be automated.

Thanks,
Ara.

review: Needs Fixing
Revision history for this message
Yung Shen (kaxing) wrote :

About the job naming with 4.x, there is a small quirk between versions: 4.1 is software upgrade but for 4.2 some feature requires hardware upgrade. It might be better to left the x for the future job.

Revision history for this message
Yung Shen (kaxing) wrote :

About automation, a note for HOGP devices, at least the two mouses that I've handed on, they will changing MAC address from each pairing reset.

And since this set of bluetooth jobs will be used on Desktop releases, I think the interactive part of testing would be more closer to real-life scenario.

Revision history for this message
Ara Pulido (ara) wrote :

We don't want to mimic real-life scenario. We want to be efficient in our testing.

lp:~cypressyew/checkbox/bt4-HOGP updated
4265. By Po-Hsu Lin

p-p-c: Add BT automated script for mouse, and corresponding test case.

Add BT automated script, which will ask tester to enter MAC address,
Split the BT4 HOGP test cases into 2, mouse and keyboard.
Improve the term "BT 4.x" with "Bluetooth Smart".

4266. By Po-Hsu Lin

p-p-c: Convert bt_connect script to python3.

Apply to try statement to convert this script to python3,
add some docstrings and change the todo list

4267. By Po-Hsu Lin

Merging Yung's patch to align Bluetooth Smart naming.

Aligning bluetooth 4.x naming

4268. By Po-Hsu Lin

Add scanning feature and improve the keyboard test case.

Add scanning feature and class code dictionary to determine which device to connect.
Improve the keyboard test case.

Revision history for this message
Po-Hsu Lin (cypressyew) wrote :

Hi Yung, please modify the executable base on Maciej's bt_helper
https://github.com/kissiel/bt_helper

Revision history for this message
Yung Shen (kaxing) wrote :
review: Abstain

Unmerged revisions

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== added file 'providers/plainbox-provider-checkbox/bin/bt_connect'
--- providers/plainbox-provider-checkbox/bin/bt_connect 1970-01-01 00:00:00 +0000
+++ providers/plainbox-provider-checkbox/bin/bt_connect 2016-03-17 10:36:36 +0000
@@ -0,0 +1,221 @@
1#!/usr/bin/env python3
2# -*- coding: utf-8 -*-
3#
4# This file is part of Checkbox.
5#
6# Copyright 2016 Canonical Ltd.
7#
8# Authors:
9# Po-Hsu Lin <po-hsu.lin@canonical.com>
10# Yung Shen <yung.shen@canonical.com>
11#
12# Checkbox is free software: you can redistribute it and/or modify
13# it under the terms of the GNU General Public License version 3,
14# as published by the Free Software Foundation.
15#
16# Checkbox is distributed in the hope that it will be useful,
17# but WITHOUT ANY WARRANTY; without even the implied warranty of
18# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19# GNU General Public License for more details.
20#
21# You should have received a copy of the GNU General Public License
22# along with Checkbox. If not, see <http://www.gnu.org/licenses/>.
23
24# possibility to lockup, if it times out
25# TODO: 5. better exception handling (wrong PIN, authentication rejected)
26# 6. different PIN selection
27# 7. MAC address validator
28# 8. Use logging for information
29# 9. PEP8
30try:
31 from gi.repository import GObject
32except ImportError:
33 import gobject as GObject
34
35import time
36import dbus
37import dbus.service
38from dbus.mainloop.glib import DBusGMainLoop
39from argparse import ArgumentParser
40
41PIN = '0000'
42CLASS_CODE = {'mouse': [0x580, 0x2580], 'keyboard': [0x540, 0x2540]}
43mainloop = GObject.MainLoop()
44
45
46class Rejected(dbus.DBusException):
47 _dbus_error_name = "org.bluez.Error.Rejected"
48
49
50class Agent(dbus.service.Object):
51 exit_on_release = True
52
53 def set_exit_on_release(self, exit_on_release):
54 self.exit_on_release = exit_on_release
55
56 @dbus.service.method("org.bluez.Agent",
57 in_signature="", out_signature="")
58 def Release(self):
59 if self.exit_on_release:
60 mainloop.quit()
61
62 @dbus.service.method("org.bluez.Agent",
63 in_signature="os", out_signature="")
64 def Authorize(self, device, uuid):
65 print("Authorize {}, {}".format(device, uuid))
66 authorize = raw_input("Authorize connection (yes/no): ")
67 if (authorize == "yes"):
68 return
69 raise Rejected("Connection rejected by user")
70
71 @dbus.service.method("org.bluez.Agent",
72 in_signature="o", out_signature="s")
73 def RequestPinCode(self, device):
74 print("Sending PIN: {} to your device.".format(PIN))
75 if TARGET is not 'mouse':
76 print("For keyboard, please type this PIN on it and hit Enter.")
77 # need to figure out how to send 0000 / 1111 / 1234
78 return PIN
79 # return raw_input("Enter PIN Code: ")
80
81 @dbus.service.method("org.bluez.Agent",
82 in_signature="o", out_signature="u")
83 def RequestPasskey(self, device):
84 print("RequestPasskey {}".format(device))
85 passkey = raw_input("Enter passkey: ")
86 return dbus.UInt32(passkey)
87
88 @dbus.service.method("org.bluez.Agent",
89 in_signature="ou", out_signature="")
90 def DisplayPasskey(self, device, passkey):
91 print("Please enter the passkey: {} on your device".format(passkey))
92
93 @dbus.service.method("org.bluez.Agent",
94 in_signature="ou", out_signature="")
95 def RequestConfirmation(self, device, passkey):
96 print("RequestConfirmation {}, {})".format(device, passkey))
97 confirm = raw_input("Confirm passkey (yes/no): ")
98 if (confirm == "yes"):
99 return
100 raise Rejected("Passkey doesn't match")
101
102 @dbus.service.method("org.bluez.Agent",
103 in_signature="s", out_signature="")
104 def ConfirmModeChange(self, mode):
105 print("ConfirmModeChange {}".format(mode))
106 authorize = raw_input("Authorize mode change (yes/no): ")
107 if (authorize == "yes"):
108 return
109 raise Rejected("Mode change by user")
110
111 @dbus.service.method("org.bluez.Agent",
112 in_signature="", out_signature="")
113 def Cancel(self):
114 print("Cancel")
115
116
117def create_device_reply(device):
118 print("New device {}".format(device))
119 mainloop.quit()
120
121
122def create_device_error(error):
123 if error._dbus_error_name == 'org.bluez.Error.AuthenticationFailed':
124 print("ERROR: Passcode Authentication Failed, wrong passcode?")
125 else:
126 print("Creating device failed: {}".format(error))
127 mainloop.quit()
128
129
130def property_changed(name, value):
131 """handler function for "PropertyChanged" signal."""
132 if (name == "Discovering" and not value):
133 mainloop.quit()
134
135
136def device_found(address, properties):
137 global DEVICE_MAC
138 """handler function for "DeviceFound" signal."""
139 if properties['Class'] in CLASS_CODE[TARGET]:
140 print("Device found: {}".format(properties['Name']))
141 print("MAC address: {}".format(properties['Address']))
142 DEVICE_MAC = properties['Address']
143
144
145def main():
146 """Add argument parser here and do most of the job."""
147 global TARGET
148 global DEVICE_MAC
149 DEVICE_MAC = None
150 parser = ArgumentParser(description="Bluetooth auto paring and connect. Please select one option.")
151 group = parser.add_mutually_exclusive_group(required=True)
152 group.add_argument("--mac", type=str,
153 help="Pair with a given MAC, not using scan result,")
154 group.add_argument("--mouse", action="store_const",
155 const="mouse", dest='target',
156 help="Pair with the last mouse found from scan result.")
157 group.add_argument("--keyboard", action="store_const",
158 const="keyboard", dest='target',
159 help="Pair with the last keyboard found from scan result.")
160 parser.add_argument("-i", "--interface", type=str,
161 help="Device interface, e.g. hci0")
162 parser.add_argument("-c", "--capability", type=str, default="DisplayYesNo")
163 args = parser.parse_args()
164
165 DBusGMainLoop(set_as_default=True)
166 bus = dbus.SystemBus()
167 manager = dbus.Interface(bus.get_object("org.bluez", "/"),
168 "org.bluez.Manager")
169 if args.interface:
170 path = manager.FindAdapter(args.interface)
171 else:
172 path = manager.DefaultAdapter()
173
174 adapter = dbus.Interface(bus.get_object("org.bluez", path),
175 "org.bluez.Adapter")
176
177 path = "/test/agent"
178 agent = Agent(bus, path)
179 if not args.mac:
180 # Activate scan and auto pairing
181 TARGET = args.target
182 print("Trying to scan and pair with a {}.".format(TARGET))
183 bus.add_signal_receiver(device_found,
184 signal_name="DeviceFound",
185 dbus_interface="org.bluez.Adapter")
186 bus.add_signal_receiver(property_changed,
187 signal_name="PropertyChanged",
188 dbus_interface="org.bluez.Adapter")
189 adapter.StartDiscovery()
190 mainloop.run()
191 adapter.StopDiscovery()
192 if not DEVICE_MAC:
193 print("ERROR: No pairable device found, terminating")
194 return 1
195 else:
196 DEVICE_MAC = args.mac
197
198 # Try to remove the Device entry if exist
199 try:
200 device = adapter.FindDevice(DEVICE_MAC)
201 print("Device already exist, remove it first")
202 adapter.RemoveDevice(device)
203 except dbus.exceptions.DBusException:
204 print("Creating device entry")
205 agent.set_exit_on_release(False)
206 print("Paring device")
207 adapter.CreatePairedDevice(DEVICE_MAC, path, args.capability,
208 reply_handler=create_device_reply,
209 error_handler=create_device_error)
210
211 mainloop.run()
212
213 time.sleep(3)
214 print("Connecting device...")
215 device = adapter.FindDevice(DEVICE_MAC)
216 hid = dbus.Interface(bus.get_object("org.bluez", device),
217 "org.bluez.Input")
218 hid.Connect()
219
220if __name__ == "__main__":
221 main()
0222
=== modified file 'providers/plainbox-provider-checkbox/jobs/bluetooth.txt.in'
--- providers/plainbox-provider-checkbox/jobs/bluetooth.txt.in 2016-01-12 10:28:35 +0000
+++ providers/plainbox-provider-checkbox/jobs/bluetooth.txt.in 2016-03-17 10:36:36 +0000
@@ -1,3 +1,10 @@
1unit: manifest entry
2id: has_bt_smart
3_name: Bluetooth Smart (4.0 or later) Support
4requires:
5 device.category == 'BLUETOOTH'
6value-type: bool
7
1plugin: shell8plugin: shell
2category_id: 2013.com.canonical.plainbox::bluetooth9category_id: 2013.com.canonical.plainbox::bluetooth
3id: bluetooth/detect-output10id: bluetooth/detect-output
@@ -157,3 +164,42 @@
157 retrieves it again using Bluetooth and verifies the checksum to ensure the164 retrieves it again using Bluetooth and verifies the checksum to ensure the
158 transfer didn't corrupt the file.165 transfer didn't corrupt the file.
159166
167plugin: user-interact-verify
168category_id: 2013.com.canonical.plainbox::bluetooth
169id: bluetooth4/HOGP-mouse
170depends: bluetooth/detect-output
171requires:
172 manifest.has_bt_smart == 'True'
173 package.name == 'zenity'
174estimated_duration: 30.0
175command: bt_connect --mac `zenity --entry --title="device MAC" --text="Please enter the MAC address for testing"`
176_description:
177 PURPOSE:
178 This test will check that you can use a HID Over GATT Profile (HOGP) with your Bluetooth Smart mouse.
179 STEPS:
180 1. Enable a Bluetooth smart mouse, and put it into paring mode.
181 2. Use "hcitool scan" command in another terminal to get the MAC address of it.
182 3. Commence the test to do the auto-pairing, you will be asked to enter the MAC address.
183 4. After it's paired and connected, perform actions such as moving the pointer, right and left button clicks and double clicks.
184 VERIFICATION:
185 Did the Bluetooth Smart mouse work as expected?
186
187plugin: user-interact-verify
188category_id: 2013.com.canonical.plainbox::bluetooth
189id: bluetooth4/HOGP-keyboard
190depends: bluetooth/detect-output
191requires:
192 manifest.has_bt_smart == 'True'
193 package.name == 'zenity'
194estimated_duration: 30.0
195command: bt_connect --mac `zenity --entry --title="device MAC" --text="Please enter the MAC address for testing"` && keyboard_test
196_description:
197 PURPOSE:
198 This test will check that you can use a HID Over GATT Profile (HOGP) with your Bluetooth Smart keyboard.
199 STEPS:
200 1. Enable a Bluetooth Smart keyboard, and put it into paring mode.
201 2. Use "hcitool scan" command in another terminal to get the MAC address of it.
202 3. Commence the test to do the auto-pairing, you will be asked to enter the MAC address and PIN code.
203 4. After it's paired and connected, enter some text with your keyboard and close the small input test tool.
204 VERIFICATION:
205 Did the Bluetooth Smart keyboard work as expected?

Subscribers

People subscribed via source and target branches