| # Copyright (c) 2013 The Chromium OS Authors. All rights reserved. |
| # Use of this source code is governed by a BSD-style license that can be |
| # found in the LICENSE file. |
| |
| from autotest_lib.client.common_lib import error |
| from autotest_lib.server.cros.bluetooth import bluetooth_test |
| import uuid |
| |
| class bluetooth_SDP_ServiceSearchRequestBasic(bluetooth_test.BluetoothTest): |
| """ |
| Verify the correct behaviour of the device when searching for services. |
| """ |
| version = 1 |
| |
| SDP_SERVER_CLASS_ID = 0x1000 |
| NO_EXISTING_SERVICE_CLASS_ID = 0x0001 |
| FAKE_SERVICES_CNT = 300 |
| FAKE_SERVICES_PATH = '/autotest/fake_service_' |
| FAKE_SERVICES_CLASS_ID = 0xABCD |
| BLUETOOTH_BASE_UUID = 0x0000000000001000800000805F9B34FB |
| INVALID_PDU_SIZE = 9875 |
| ERROR_CODE_INVALID_REQUEST_SYNTAX = 0x0003 |
| ERROR_CODE_INVALID_PDU_SIZE = 0x0004 |
| |
| |
| def correct_request(self): |
| """Search the existing service on the DUT using the Tester. |
| |
| @return True if found, False if not found |
| |
| """ |
| # connect to the DUT via L2CAP using SDP socket |
| self.tester.connect(self.adapter['Address']) |
| |
| for size in 16, 32, 128: |
| # test case TP/SERVER/SS/BV-01-C: |
| # at least the SDP server service exists |
| resp = self.tester.service_search_request( |
| [self.SDP_SERVER_CLASS_ID], 3, size) |
| if resp != [0]: |
| return False |
| # test case TP/SERVER/SS/BV-04-C: |
| # Service with Class ID = 0x0001 should never exist, as this UUID is |
| # reserved as Bluetooth Core Specification UUID |
| resp = self.tester.service_search_request( |
| [self.NO_EXISTING_SERVICE_CLASS_ID], 3, size) |
| if resp != []: |
| return False |
| # test case TP/SERVER/SS/BV-03-C: |
| # request the fake services' Class ID to force SDP to use |
| # continuation state |
| resp = self.tester.service_search_request( |
| [self.FAKE_SERVICES_CLASS_ID], |
| self.FAKE_SERVICES_CNT * 2, |
| size) |
| if len(resp) != self.FAKE_SERVICES_CNT: |
| return False |
| # test case TP/SERVER/SS/BI-01-C: |
| # send a Service Search Request with intentionally invalid PDU size |
| resp = self.tester.service_search_request( |
| [self.SDP_SERVER_CLASS_ID], 3, size, |
| forced_pdu_size=self.INVALID_PDU_SIZE) |
| if resp != self.ERROR_CODE_INVALID_PDU_SIZE: |
| return False |
| # test case TP/SERVER/SS/BI-02-C: |
| # send a Service Search Request with invalid syntax |
| resp = self.tester.service_search_request( |
| [self.SDP_SERVER_CLASS_ID], 3, size, invalid_request=True) |
| if resp != self.ERROR_CODE_INVALID_REQUEST_SYNTAX: |
| return False |
| |
| return True |
| |
| |
| def run_once(self): |
| # Reset the adapter to the powered on, discoverable state. |
| if not (self.device.reset_on() and |
| self.device.set_discoverable(True)): |
| raise error.TestFail('DUT could not be reset to initial state') |
| |
| self.adapter = self.device.get_adapter_properties() |
| |
| # Setup the tester as a generic computer. |
| if not self.tester.setup('computer'): |
| raise error.TestFail('Tester could not be initialized') |
| |
| # Create many fake services with the same Class ID |
| for num in range(0, self.FAKE_SERVICES_CNT): |
| path_str = self.FAKE_SERVICES_PATH + str(num) |
| uuid128 = ((self.FAKE_SERVICES_CLASS_ID << 96) + |
| self.BLUETOOTH_BASE_UUID) |
| uuid_str = str(uuid.UUID(int=uuid128)) |
| self.device.register_profile(path_str, uuid_str, {}) |
| |
| # Since radio is involved, this test is not 100% reliable; instead we |
| # repeat a few times until it succeeds. |
| for failed_attempts in range(0, 5): |
| if self.correct_request(): |
| break |
| else: |
| raise error.TestFail('Expected device was not found') |
| |
| # Record how many attempts this took, hopefully we'll one day figure out |
| # a way to reduce this to zero and then the loop above can go away. |
| self.write_perf_keyval({'failed_attempts': failed_attempts }) |