Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit e2e089fa authored by Henri Chataing's avatar Henri Chataing
Browse files

RootCanal: Implement additional LL tests

Implement tests LL/DDI/ADV/BV-04-C and LL/DDI/ADV/BV-05-C.

Bug: 253523072
Test: atest --host rootcanal_ll_test
Change-Id: I6540ae6df91b53de83c803feec3abe1e60319112
parent 7a54b5e2
Loading
Loading
Loading
Loading
+6 −0
Original line number Diff line number Diff line
@@ -3187,6 +3187,12 @@ packet LeSetScanResponseData : LeAdvertisingCommand (op_code = LE_SET_SCAN_RESPO
  _padding_[31], // Zero padding to 31 bytes of advertising_data
}

packet LeSetScanResponseDataRaw : LeAdvertisingCommand (op_code = LE_SET_SCAN_RESPONSE_DATA) {
  _size_(advertising_data) : 8,
  advertising_data : 8[],
  _padding_[31], // Zero padding to 31 bytes of advertising_data
}

packet LeSetScanResponseDataComplete : CommandComplete (command_op_code = LE_SET_SCAN_RESPONSE_DATA) {
  status : ErrorCode,
}
+2 −6
Original line number Diff line number Diff line
@@ -258,12 +258,8 @@ python_test_host {
        ":hci_packets_python3_gen",
        ":link_layer_packets_python3_gen",
        "test/main.py",
        "test/LL/DDI/ADV/BV_01_C.py",
        "test/LL/DDI/ADV/BV_02_C.py",
        "test/LL/DDI/ADV/BV_03_C.py",
        "test/LL/DDI/SCN/BV_13_C.py",
        "test/LL/DDI/SCN/BV_14_C.py",
        "test/LL/DDI/SCN/BV_18_C.py",
        "test/LL/DDI/ADV/*.py",
        "test/LL/DDI/SCN/*.py",
    ],
    data: [
        ":lib_rootcanal_python3",
+6 −14
Original line number Diff line number Diff line
@@ -2112,29 +2112,21 @@ void DualModeController::LeReadAdvertisingPhysicalChannelTxPower(
}

void DualModeController::LeSetAdvertisingData(CommandView command) {
  auto command_view = gd_hci::LeSetAdvertisingDataView::Create(
  auto command_view = gd_hci::LeSetAdvertisingDataRawView::Create(
      gd_hci::LeAdvertisingCommandView::Create(command));
  auto payload = command.GetPayload();
  auto data_size = *payload.begin();
  auto first_data = payload.begin() + 1;
  std::vector<uint8_t> advertising_data{first_data, first_data + data_size};
  ASSERT_LOG(command_view.IsValid(), "%s command.size() = %zu",
             gd_hci::OpCodeText(command.GetOpCode()).c_str(), command.size());
  ASSERT(command_view.GetPayload().size() == 32);
  ErrorCode status =
      link_layer_controller_.LeSetAdvertisingData(advertising_data);
  ASSERT(command_view.IsValid());
  ErrorCode status = link_layer_controller_.LeSetAdvertisingData(
      command_view.GetAdvertisingData());
  send_event_(bluetooth::hci::LeSetAdvertisingDataCompleteBuilder::Create(
      kNumCommandPackets, status));
}

void DualModeController::LeSetScanResponseData(CommandView command) {
  auto command_view = gd_hci::LeSetScanResponseDataView::Create(
  auto command_view = gd_hci::LeSetScanResponseDataRawView::Create(
      gd_hci::LeAdvertisingCommandView::Create(command));
  ASSERT(command_view.IsValid());
  ASSERT(command_view.GetPayload().size() == 32);
  ErrorCode status = link_layer_controller_.LeSetScanResponseData(
      std::vector<uint8_t>(command_view.GetPayload().begin() + 1,
                           command_view.GetPayload().end()));
      command_view.GetAdvertisingData());
  send_event_(bluetooth::hci::LeSetScanResponseDataCompleteBuilder::Create(
      kNumCommandPackets, status));
}
+140 −0
Original line number Diff line number Diff line
import lib_rootcanal_python3 as rootcanal
import hci_packets as hci
import link_layer_packets as ll
import unittest
from hci_packets import ErrorCode
from py.bluetooth import Address
from py.controller import ControllerTest


class Test(ControllerTest):

    # LL/DDI/ADV/BV-04-C [Advertising Data: Undirected]
    async def test(self):
        # Test parameters.
        LL_advertiser_advInterval_MIN = 0x200
        LL_advertiser_advInterval_MAX = 0x200
        LL_advertiser_Adv_Channel_Map = 0x7
        controller = self.controller

        # 1. Configure Lower Tester to monitor advertising packets from the IUT.

        # 2. Upper Tester configures undirected advertising in the IUT using a selected advertising channel
        # and a selected advertising interval between the minimum and maximum advertising intervals.
        controller.send_cmd(
            hci.LeSetAdvertisingParameters(
                advertising_interval_min=LL_advertiser_advInterval_MIN,
                advertising_interval_max=LL_advertiser_advInterval_MAX,
                advertising_type=hci.AdvertisingType.ADV_IND,
                own_address_type=hci.OwnAddressType.PUBLIC_DEVICE_ADDRESS,
                advertising_channel_map=LL_advertiser_Adv_Channel_Map,
                advertising_filter_policy=hci.AdvertisingFilterPolicy.LISTED_SCAN_AND_CONNECT))

        await self.expect_evt(
            hci.LeSetAdvertisingParametersComplete(status=ErrorCode.SUCCESS, num_hci_command_packets=1))

        # 3. Upper Tester sends an HCI_LE_Set_Advertising_Data command to the IUT and receives an
        # HCI_Command_Complete in response. The data element used in the command is the length of
        # the data field. The data length is 1 byte.
        advertising_data = [1]
        controller.send_cmd(hci.LeSetAdvertisingDataRaw(advertising_data=advertising_data))

        await self.expect_evt(hci.LeSetAdvertisingDataComplete(status=ErrorCode.SUCCESS, num_hci_command_packets=1))

        # 4. Upper Tester sends an HCI_LE_Set_Advertising_Enable command to the IUT to enable
        # advertising and receives an HCI_Command_Complete event in response.
        controller.send_cmd(hci.LeSetAdvertisingEnable(advertising_enable=True))

        await self.expect_evt(hci.LeSetAdvertisingEnableComplete(status=ErrorCode.SUCCESS, num_hci_command_packets=1))

        # 5. Lower Tester expects the IUT to send ADV_IND packets including the data submitted in step 3
        # starting an event on the selected advertising channel.
        # 6. Expect the following event to start after advertising interval time calculating from the start of the
        # first packet.
        # 7. Repeat steps 5–6 until a number of advertising intervals (50) have been detected.
        for n in range(10):
            await self.expect_ll(ll.LeLegacyAdvertisingPdu(source_address=controller.address,
                                                           advertising_address_type=ll.AddressType.PUBLIC,
                                                           advertising_type=ll.LegacyAdvertisingType.ADV_IND,
                                                           advertising_data=advertising_data),
                                 timeout=5)

        # 8. Upper Tester sends an HCI_LE_Set_Advertising_Enable command to the IUT to disable
        # advertising function and receives an HCI_Command_Complete event in response.
        controller.send_cmd(hci.LeSetAdvertisingEnable(advertising_enable=False))

        await self.expect_evt(hci.LeSetAdvertisingEnableComplete(status=ErrorCode.SUCCESS, num_hci_command_packets=1))

        # 9. Upper Tester sends an HCI_LE_Set_Advertising_Data to configure the IUT to send advertising
        # packets without advertising data and receives an HCI_Command_Complete event in response.
        controller.send_cmd(hci.LeSetAdvertisingDataRaw(advertising_data=[]))

        await self.expect_evt(hci.LeSetAdvertisingDataComplete(status=ErrorCode.SUCCESS, num_hci_command_packets=1))

        # 10. Upper Tester sends an HCI_LE_Set_Advertising_Enable command to the IUT to enable
        # advertising and receives an HCI_Command_Complete event in response.
        controller.send_cmd(hci.LeSetAdvertisingEnable(advertising_enable=True))

        await self.expect_evt(hci.LeSetAdvertisingEnableComplete(status=ErrorCode.SUCCESS, num_hci_command_packets=1))

        # 11. Lower Tester expects the IUT to send ADV_IND packets including no advertising data starting an
        # event on the selected advertising channel.
        # 12. Expect the next event to start after advertising interval time calculating from the start of the first
        # packet.
        # 13. Repeat steps 11–12 until a number of advertising intervals (50) have been detected.
        for n in range(10):
            await self.expect_ll(ll.LeLegacyAdvertisingPdu(source_address=controller.address,
                                                           advertising_address_type=ll.AddressType.PUBLIC,
                                                           advertising_type=ll.LegacyAdvertisingType.ADV_IND,
                                                           advertising_data=[]),
                                 timeout=5)

        # 14. Upper Tester sends an HCI_LE_Set_Advertising_Enable command to the IUT to disable
        # advertising and receives an HCI_Command_Complete event in response.
        controller.send_cmd(hci.LeSetAdvertisingEnable(advertising_enable=False))

        await self.expect_evt(hci.LeSetAdvertisingEnableComplete(status=ErrorCode.SUCCESS, num_hci_command_packets=1))

        # 15. Upper Tester sends an HCI_LE_Set_Advertising_Data command to the IUT and receives an
        # HCI_Command_Complete in response. The data element is a number indicating the length of the
        # data field in the first octet encoded unsigned least significant bit first and the rest of the octets
        # zeroes. The data length is 31 bytes.
        advertising_data = [31] + [0] * 30
        controller.send_cmd(hci.LeSetAdvertisingDataRaw(advertising_data=advertising_data))

        await self.expect_evt(hci.LeSetAdvertisingDataComplete(status=ErrorCode.SUCCESS, num_hci_command_packets=1))

        controller.send_cmd(hci.LeSetAdvertisingEnable(advertising_enable=True))

        await self.expect_evt(hci.LeSetAdvertisingEnableComplete(status=ErrorCode.SUCCESS, num_hci_command_packets=1))

        # 16. Repeat steps 4–14.
        for n in range(10):
            await self.expect_ll(ll.LeLegacyAdvertisingPdu(source_address=controller.address,
                                                           advertising_address_type=ll.AddressType.PUBLIC,
                                                           advertising_type=ll.LegacyAdvertisingType.ADV_IND,
                                                           advertising_data=advertising_data),
                                 timeout=5)

        controller.send_cmd(hci.LeSetAdvertisingEnable(advertising_enable=False))

        await self.expect_evt(hci.LeSetAdvertisingEnableComplete(status=ErrorCode.SUCCESS, num_hci_command_packets=1))

        controller.send_cmd(hci.LeSetAdvertisingDataRaw(advertising_data=[]))

        await self.expect_evt(hci.LeSetAdvertisingDataComplete(status=ErrorCode.SUCCESS, num_hci_command_packets=1))

        controller.send_cmd(hci.LeSetAdvertisingEnable(advertising_enable=True))

        await self.expect_evt(hci.LeSetAdvertisingEnableComplete(status=ErrorCode.SUCCESS, num_hci_command_packets=1))

        for n in range(10):
            await self.expect_ll(ll.LeLegacyAdvertisingPdu(source_address=controller.address,
                                                           advertising_address_type=ll.AddressType.PUBLIC,
                                                           advertising_type=ll.LegacyAdvertisingType.ADV_IND,
                                                           advertising_data=[]),
                                 timeout=5)

        controller.send_cmd(hci.LeSetAdvertisingEnable(advertising_enable=False))

        await self.expect_evt(hci.LeSetAdvertisingEnableComplete(status=ErrorCode.SUCCESS, num_hci_command_packets=1))
+181 −0
Original line number Diff line number Diff line
import lib_rootcanal_python3 as rootcanal
import hci_packets as hci
import link_layer_packets as ll
import unittest
from hci_packets import ErrorCode
from py.bluetooth import Address
from py.controller import ControllerTest


class Test(ControllerTest):

    # LL/DDI/ADV/BV-05-C [Scan Request: Undirected Connectable]
    async def test(self):
        # Test parameters.
        LL_advertiser_advInterval_MIN = 0x200
        LL_advertiser_advInterval_MAX = 0x200
        LL_advertiser_Adv_Channel_Map = 0x7
        controller = self.controller
        peer_address = Address('aa:bb:cc:dd:ee:ff')
        invalid_scan_address = Address([
            controller.address.address[0] ^ 0xff, controller.address.address[1], controller.address.address[2],
            controller.address.address[3], controller.address.address[4], controller.address.address[5]
        ])

        # 1. Upper Tester configures undirected advertising in the IUT using all supported advertising
        # channels and a selected advertising interval between the minimum and maximum advertising
        # intervals.
        controller.send_cmd(
            hci.LeSetAdvertisingParameters(advertising_interval_min=LL_advertiser_advInterval_MIN,
                                           advertising_interval_max=LL_advertiser_advInterval_MAX,
                                           advertising_type=hci.AdvertisingType.ADV_IND,
                                           own_address_type=hci.OwnAddressType.PUBLIC_DEVICE_ADDRESS,
                                           advertising_channel_map=LL_advertiser_Adv_Channel_Map,
                                           advertising_filter_policy=hci.AdvertisingFilterPolicy.ALL_DEVICES))

        await self.expect_evt(
            hci.LeSetAdvertisingParametersComplete(status=ErrorCode.SUCCESS, num_hci_command_packets=1))

        # 2. Configure Lower Tester to monitor the advertising and scan response procedures of the IUT. The
        # Lower Tester will send an SCAN_REQ packet on a selected supported advertising channel
        # (defined as an IXIT) and using a common public device address as parameter.

        # 3. Configure Scan Response Data in the IUT using device name length of 0 as response data.
        scan_response_data = []
        controller.send_cmd(hci.LeSetScanResponseDataRaw(advertising_data=scan_response_data))

        await self.expect_evt(hci.LeSetScanResponseDataComplete(status=ErrorCode.SUCCESS, num_hci_command_packets=1))

        controller.send_cmd(hci.LeSetAdvertisingEnable(advertising_enable=True))

        await self.expect_evt(hci.LeSetAdvertisingEnableComplete(status=ErrorCode.SUCCESS, num_hci_command_packets=1))

        # 4. Lower Tester sends a SCAN_REQ packet on the selected advertising channel after receiving an
        # ADV_IND packet from IUT on the advertising channel configured in step 3. The SCAN_REQ is
        # sent T_IFS after the end of an ADV_IND packet.
        # 5. Lower Tester receives a SCAN_RSP packet from the IUT addressed to the Lower Tester T_IFS
        # after the end of the request packet.
        # 6. Repeat steps 4–5 30 times or until IUT sends a SCN_RSP.
        for n in range(10):
            await self.expect_ll(
                ll.LeLegacyAdvertisingPdu(source_address=controller.address,
                                          advertising_address_type=ll.AddressType.PUBLIC,
                                          advertising_type=ll.LegacyAdvertisingType.ADV_IND,
                                          advertising_data=[]))

            controller.send_ll(ll.LeScan(source_address=peer_address,
                                         destination_address=controller.address,
                                         advertising_address_type=ll.AddressType.PUBLIC,
                                         scanning_address_type=ll.AddressType.PUBLIC),
                               rssi=0xf0)

            await self.expect_ll(
                ll.LeScanResponse(source_address=controller.address,
                                  destination_address=peer_address,
                                  advertising_address_type=ll.AddressType.PUBLIC,
                                  scan_response_data=scan_response_data))

        # 7. Configure Scan Response Data in the IUT using device name length of 31 as response data.
        controller.send_cmd(hci.LeSetAdvertisingEnable(advertising_enable=False))

        await self.expect_evt(hci.LeSetAdvertisingEnableComplete(status=ErrorCode.SUCCESS, num_hci_command_packets=1))

        scan_response_data = [31] + [0] * 30
        controller.send_cmd(hci.LeSetScanResponseDataRaw(advertising_data=scan_response_data))

        await self.expect_evt(hci.LeSetScanResponseDataComplete(status=ErrorCode.SUCCESS, num_hci_command_packets=1))

        controller.send_cmd(hci.LeSetAdvertisingEnable(advertising_enable=True))

        await self.expect_evt(hci.LeSetAdvertisingEnableComplete(status=ErrorCode.SUCCESS, num_hci_command_packets=1))

        # 8. Repeat steps 4–6.
        for n in range(10):
            await self.expect_ll(
                ll.LeLegacyAdvertisingPdu(source_address=controller.address,
                                          advertising_address_type=ll.AddressType.PUBLIC,
                                          advertising_type=ll.LegacyAdvertisingType.ADV_IND,
                                          advertising_data=[]))

            controller.send_ll(ll.LeScan(source_address=peer_address,
                                         destination_address=controller.address,
                                         advertising_address_type=ll.AddressType.PUBLIC,
                                         scanning_address_type=ll.AddressType.PUBLIC),
                               rssi=0xf0)

            await self.expect_ll(
                ll.LeScanResponse(source_address=controller.address,
                                  destination_address=peer_address,
                                  advertising_address_type=ll.AddressType.PUBLIC,
                                  scan_response_data=scan_response_data))

        # 9. Configure Lower Tester to monitor the advertising and scan response procedures of the IUT. The
        # Lower Tester will send an SCAN_REQ packet on a selected supported advertising channel
        # (defined as an IXIT) and using a public device address that differs from the IUT address in the
        # most significant octet.

        # 10. Configure Scan Response Data in the IUT using device name length of 0 as response data.
        controller.send_cmd(hci.LeSetAdvertisingEnable(advertising_enable=False))

        await self.expect_evt(hci.LeSetAdvertisingEnableComplete(status=ErrorCode.SUCCESS, num_hci_command_packets=1))

        scan_response_data = []
        controller.send_cmd(hci.LeSetScanResponseDataRaw(advertising_data=scan_response_data))

        await self.expect_evt(hci.LeSetScanResponseDataComplete(status=ErrorCode.SUCCESS, num_hci_command_packets=1))

        controller.send_cmd(hci.LeSetAdvertisingEnable(advertising_enable=True))

        await self.expect_evt(hci.LeSetAdvertisingEnableComplete(status=ErrorCode.SUCCESS, num_hci_command_packets=1))
        # 11. Repeat steps 4–6.
        for n in range(10):
            await self.expect_ll(
                ll.LeLegacyAdvertisingPdu(source_address=controller.address,
                                          advertising_address_type=ll.AddressType.PUBLIC,
                                          advertising_type=ll.LegacyAdvertisingType.ADV_IND,
                                          advertising_data=[]))

            controller.send_ll(ll.LeScan(source_address=peer_address,
                                         destination_address=invalid_scan_address,
                                         advertising_address_type=ll.AddressType.PUBLIC,
                                         scanning_address_type=ll.AddressType.PUBLIC),
                               rssi=0xf0)

        # 12. Configure Scan Response Data in the IUT using device name length of 31 as response data.
        controller.send_cmd(hci.LeSetAdvertisingEnable(advertising_enable=False))

        await self.expect_evt(hci.LeSetAdvertisingEnableComplete(status=ErrorCode.SUCCESS, num_hci_command_packets=1))

        scan_response_data = [31] + [0] * 30
        controller.send_cmd(hci.LeSetScanResponseDataRaw(advertising_data=scan_response_data))

        await self.expect_evt(hci.LeSetScanResponseDataComplete(status=ErrorCode.SUCCESS, num_hci_command_packets=1))

        controller.send_cmd(hci.LeSetAdvertisingEnable(advertising_enable=True))

        await self.expect_evt(hci.LeSetAdvertisingEnableComplete(status=ErrorCode.SUCCESS, num_hci_command_packets=1))

        # 13. Repeat steps 4–6.
        for n in range(10):
            await self.expect_ll(
                ll.LeLegacyAdvertisingPdu(source_address=controller.address,
                                          advertising_address_type=ll.AddressType.PUBLIC,
                                          advertising_type=ll.LegacyAdvertisingType.ADV_IND,
                                          advertising_data=[]))

            controller.send_ll(ll.LeScan(source_address=peer_address,
                                         destination_address=invalid_scan_address,
                                         advertising_address_type=ll.AddressType.PUBLIC,
                                         scanning_address_type=ll.AddressType.PUBLIC),
                               rssi=0xf0)

        # Note: this last iteration is very redundant, not implementing it
        # to save on execution time.

        # 14. Configure Lower Tester to monitor the advertising and scan response procedures of the IUT. The
        # Lower Tester will send an SCAN_REQ packet on a selected supported advertising channel
        # (defined as an IXIT) and using a public device address that differs from the IUT address in the
        # most and least significant octets.
        # 15. Repeat steps 4–6.
        # 16. Configure Scan Response Data in the IUT using device name length of 31 as response data.
        # 17. Repeat steps 4–6.
Loading