1# Copyright (c) 2013 The Chromium OS Authors. All rights reserved. 2# Use of this source code is governed by a BSD-style license that can be 3# found in the LICENSE file. 4 5from autotest_lib.client.common_lib import error 6from autotest_lib.server.cros.bluetooth import bluetooth_test 7import uuid 8 9class bluetooth_SDP_ServiceSearchRequestBasic(bluetooth_test.BluetoothTest): 10 """ 11 Verify the correct behaviour of the device when searching for services. 12 """ 13 version = 1 14 15 SDP_SERVER_CLASS_ID = 0x1000 16 NO_EXISTING_SERVICE_CLASS_ID = 0x0001 17 FAKE_SERVICES_CNT = 300 18 FAKE_SERVICES_PATH = '/autotest/fake_service_' 19 FAKE_SERVICES_CLASS_ID = 0xABCD 20 BLUETOOTH_BASE_UUID = 0x0000000000001000800000805F9B34FB 21 INVALID_PDU_SIZE = 9875 22 ERROR_CODE_INVALID_REQUEST_SYNTAX = 0x0003 23 ERROR_CODE_INVALID_PDU_SIZE = 0x0004 24 25 26 def correct_request(self): 27 """Search the existing service on the DUT using the Tester. 28 29 @return True if found, False if not found 30 31 """ 32 # connect to the DUT via L2CAP using SDP socket 33 self.tester.connect(self.adapter['Address']) 34 35 for size in 16, 32, 128: 36 # test case TP/SERVER/SS/BV-01-C: 37 # at least the SDP server service exists 38 resp = self.tester.service_search_request( 39 [self.SDP_SERVER_CLASS_ID], 3, size) 40 if resp != [0]: 41 return False 42 # test case TP/SERVER/SS/BV-04-C: 43 # Service with Class ID = 0x0001 should never exist, as this UUID is 44 # reserved as Bluetooth Core Specification UUID 45 resp = self.tester.service_search_request( 46 [self.NO_EXISTING_SERVICE_CLASS_ID], 3, size) 47 if resp != []: 48 return False 49 # test case TP/SERVER/SS/BV-03-C: 50 # request the fake services' Class ID to force SDP to use 51 # continuation state 52 resp = self.tester.service_search_request( 53 [self.FAKE_SERVICES_CLASS_ID], 54 self.FAKE_SERVICES_CNT * 2, 55 size) 56 if len(resp) != self.FAKE_SERVICES_CNT: 57 return False 58 # test case TP/SERVER/SS/BI-01-C: 59 # send a Service Search Request with intentionally invalid PDU size 60 resp = self.tester.service_search_request( 61 [self.SDP_SERVER_CLASS_ID], 3, size, 62 forced_pdu_size=self.INVALID_PDU_SIZE) 63 if resp != self.ERROR_CODE_INVALID_PDU_SIZE: 64 return False 65 # test case TP/SERVER/SS/BI-02-C: 66 # send a Service Search Request with invalid syntax 67 resp = self.tester.service_search_request( 68 [self.SDP_SERVER_CLASS_ID], 3, size, invalid_request=True) 69 if resp != self.ERROR_CODE_INVALID_REQUEST_SYNTAX: 70 return False 71 72 return True 73 74 75 def run_once(self): 76 # Reset the adapter to the powered on, discoverable state. 77 if not (self.device.reset_on() and 78 self.device.set_discoverable(True)): 79 raise error.TestFail('DUT could not be reset to initial state') 80 81 self.adapter = self.device.get_adapter_properties() 82 83 # Setup the tester as a generic computer. 84 if not self.tester.setup('computer'): 85 raise error.TestFail('Tester could not be initialized') 86 87 # Create many fake services with the same Class ID 88 for num in range(0, self.FAKE_SERVICES_CNT): 89 path_str = self.FAKE_SERVICES_PATH + str(num) 90 uuid128 = ((self.FAKE_SERVICES_CLASS_ID << 96) + 91 self.BLUETOOTH_BASE_UUID) 92 uuid_str = str(uuid.UUID(int=uuid128)) 93 self.device.register_profile(path_str, uuid_str, {}) 94 95 # Since radio is involved, this test is not 100% reliable; instead we 96 # repeat a few times until it succeeds. 97 for failed_attempts in range(0, 5): 98 if self.correct_request(): 99 break 100 else: 101 raise error.TestFail('Expected device was not found') 102 103 # Record how many attempts this took, hopefully we'll one day figure out 104 # a way to reduce this to zero and then the loop above can go away. 105 self.write_perf_keyval({'failed_attempts': failed_attempts }) 106