1# Copyright 2023 Google LLC
2#
3# Licensed under the Apache License, Version 2.0 (the "License");
4# you may not use this file except in compliance with the License.
5# You may obtain a copy of the License at
6#
7#     https://www.apache.org/licenses/LICENSE-2.0
8#
9# Unless required by applicable law or agreed to in writing, software
10# distributed under the License is distributed on an "AS IS" BASIS,
11# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12# See the License for the specific language governing permissions and
13# limitations under the License.
14
15from dataclasses import dataclass
16import hci_packets as hci
17import link_layer_packets as ll
18import unittest
19from hci_packets import ErrorCode
20from py.bluetooth import Address
21from py.controller import ControllerTest
22
23
24class Test(ControllerTest):
25
26    # LMP/LIH/BV-143-C [Rejected Role Switch Request]
27    async def test(self):
28        # Test parameters.
29        controller = self.controller
30        acl_connection_handle = 0xefe
31        peer_address = Address('11:22:33:44:55:66')
32
33        controller.send_cmd(hci.WriteScanEnable(scan_enable=hci.ScanEnable.PAGE_SCAN_ONLY))
34
35        await self.expect_evt(hci.WriteScanEnableComplete(status=ErrorCode.SUCCESS, num_hci_command_packets=1))
36
37        controller.send_ll(
38            ll.Page(source_address=peer_address, destination_address=controller.address, allow_role_switch=False))
39
40        await self.expect_evt(hci.ConnectionRequest(bd_addr=peer_address, link_type=hci.ConnectionRequestLinkType.ACL))
41
42        controller.send_cmd(
43            hci.AcceptConnectionRequest(bd_addr=peer_address, role=hci.AcceptConnectionRequestRole.REMAIN_PERIPHERAL))
44
45        await self.expect_evt(hci.AcceptConnectionRequestStatus(status=ErrorCode.SUCCESS, num_hci_command_packets=1))
46
47        await self.expect_ll(
48            ll.PageResponse(source_address=controller.address, destination_address=peer_address, try_role_switch=False))
49
50        await self.expect_evt(
51            hci.ConnectionComplete(status=ErrorCode.SUCCESS,
52                                   connection_handle=acl_connection_handle,
53                                   bd_addr=peer_address,
54                                   link_type=hci.LinkType.ACL,
55                                   encryption_enabled=hci.Enable.DISABLED))
56
57        controller.send_cmd(
58            hci.WriteLinkPolicySettings(connection_handle=acl_connection_handle,
59                                        link_policy_settings=hci.LinkPolicy.ENABLE_ROLE_SWITCH))
60
61        await self.expect_evt(
62            hci.WriteLinkPolicySettingsComplete(status=ErrorCode.SUCCESS,
63                                                num_hci_command_packets=1,
64                                                connection_handle=acl_connection_handle))
65
66        controller.send_cmd(hci.SwitchRole(bd_addr=peer_address, role=hci.Role.CENTRAL))
67
68        await self.expect_evt(hci.SwitchRoleStatus(status=ErrorCode.SUCCESS, num_hci_command_packets=1))
69
70        await self.expect_ll(ll.RoleSwitchRequest(source_address=controller.address, destination_address=peer_address))
71
72        controller.send_ll(
73            ll.RoleSwitchResponse(source_address=peer_address,
74                                  destination_address=controller.address,
75                                  status=ErrorCode.ROLE_CHANGE_NOT_ALLOWED))
76
77        await self.expect_evt(
78            hci.RoleChange(status=ErrorCode.ROLE_CHANGE_NOT_ALLOWED, bd_addr=peer_address,
79                           new_role=hci.Role.PERIPHERAL))
80
81        controller.send_cmd(hci.SwitchRole(bd_addr=peer_address, role=hci.Role.PERIPHERAL))
82
83        await self.expect_evt(hci.SwitchRoleStatus(status=ErrorCode.SUCCESS, num_hci_command_packets=1))
84
85        await self.expect_evt(
86            hci.RoleChange(status=ErrorCode.ROLE_SWITCH_FAILED, bd_addr=peer_address, new_role=hci.Role.PERIPHERAL))
87