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

Commit fa199d00 authored by Henri Chataing's avatar Henri Chataing Committed by Gerrit Code Review
Browse files

Merge "RootCanal: Implement additional LL tests"

parents 374df594 a1c07947
Loading
Loading
Loading
Loading
+20 −22
Original line number Diff line number Diff line
@@ -3123,7 +3123,8 @@ void LinkLayerController::ConnectIncomingLeLegacyAdvertisingPdu(
          initiating_address.GetAddressType()),
      static_cast<model::packets::AddressType>(
          advertising_address.GetAddressType()),
      initiator_.le_1m_phy.connection_interval_min,
      // The connection is created with the highest allowed
      // value for the connection interval and the latency.
      initiator_.le_1m_phy.connection_interval_max,
      initiator_.le_1m_phy.max_latency,
      initiator_.le_1m_phy.supervision_timeout));
@@ -3536,7 +3537,8 @@ void LinkLayerController::ConnectIncomingLeExtendedAdvertisingPdu(
          initiating_address.GetAddressType()),
      static_cast<model::packets::AddressType>(
          advertising_address.GetAddressType()),
      initiator_.le_1m_phy.connection_interval_min,
      // The connection is created with the highest allowed value
      // for the connection interval and the latency.
      initiator_.le_1m_phy.connection_interval_max,
      initiator_.le_1m_phy.max_latency,
      initiator_.le_1m_phy.supervision_timeout));
@@ -3870,9 +3872,8 @@ bool LinkLayerController::ProcessIncomingLegacyConnectRequest(

  (void)HandleLeConnection(
      initiating_address, advertising_address, bluetooth::hci::Role::PERIPHERAL,
      connect_ind.GetLeConnectionIntervalMax(),
      connect_ind.GetLeConnectionLatency(),
      connect_ind.GetLeConnectionSupervisionTimeout(), false);
      connect_ind.GetConnInterval(), connect_ind.GetConnPeripheralLatency(),
      connect_ind.GetConnSupervisionTimeout(), false);

  SendLeLinkLayerPacket(model::packets::LeConnectCompleteBuilder::Create(
      advertising_address.GetAddress(), initiating_address.GetAddress(),
@@ -3880,9 +3881,8 @@ bool LinkLayerController::ProcessIncomingLegacyConnectRequest(
          initiating_address.GetAddressType()),
      static_cast<model::packets::AddressType>(
          advertising_address.GetAddressType()),
      connect_ind.GetLeConnectionIntervalMax(),
      connect_ind.GetLeConnectionLatency(),
      connect_ind.GetLeConnectionSupervisionTimeout()));
      connect_ind.GetConnInterval(), connect_ind.GetConnPeripheralLatency(),
      connect_ind.GetConnSupervisionTimeout()));

  legacy_advertiser_.Disable();
  return true;
@@ -4003,9 +4003,8 @@ bool LinkLayerController::ProcessIncomingExtendedConnectRequest(

  uint16_t connection_handle = HandleLeConnection(
      initiating_address, advertising_address, bluetooth::hci::Role::PERIPHERAL,
      connect_ind.GetLeConnectionIntervalMax(),
      connect_ind.GetLeConnectionLatency(),
      connect_ind.GetLeConnectionSupervisionTimeout(), false);
      connect_ind.GetConnInterval(), connect_ind.GetConnPeripheralLatency(),
      connect_ind.GetConnSupervisionTimeout(), false);

  SendLeLinkLayerPacket(model::packets::LeConnectCompleteBuilder::Create(
      advertising_address.GetAddress(), initiating_address.GetAddress(),
@@ -4013,9 +4012,8 @@ bool LinkLayerController::ProcessIncomingExtendedConnectRequest(
          initiating_address.GetAddressType()),
      static_cast<model::packets::AddressType>(
          advertising_address.GetAddressType()),
      connect_ind.GetLeConnectionIntervalMax(),
      connect_ind.GetLeConnectionLatency(),
      connect_ind.GetLeConnectionSupervisionTimeout()));
      connect_ind.GetConnInterval(), connect_ind.GetConnPeripheralLatency(),
      connect_ind.GetConnSupervisionTimeout()));

  // If the advertising set is connectable and a connection gets created, an
  // HCI_LE_Connection_Complete or HCI_LE_Enhanced_Connection_Complete
@@ -4063,14 +4061,14 @@ void LinkLayerController::IncomingLeConnectCompletePacket(
      advertising_address.ToString().c_str(),
      advertising_address.GetAddressType());

  HandleLeConnection(
      advertising_address,
  HandleLeConnection(advertising_address,
                     AddressWithType(incoming.GetDestinationAddress(),
                                     static_cast<bluetooth::hci::AddressType>(
                                         complete.GetInitiatingAddressType())),
      bluetooth::hci::Role::CENTRAL, complete.GetLeConnectionInterval(),
      complete.GetLeConnectionLatency(),
      complete.GetLeConnectionSupervisionTimeout(), ExtendedAdvertising());
                     bluetooth::hci::Role::CENTRAL, complete.GetConnInterval(),
                     complete.GetConnPeripheralLatency(),
                     complete.GetConnSupervisionTimeout(),
                     ExtendedAdvertising());

  initiator_.pending_connect_request = {};
  initiator_.Disable();
+6 −7
Original line number Diff line number Diff line
@@ -193,18 +193,17 @@ packet LeExtendedAdvertisingPdu : LinkLayerPacket (type = LE_EXTENDED_ADVERTISIN
packet LeConnect : LinkLayerPacket (type = LE_CONNECT) {
  initiating_address_type : AddressType,
  advertising_address_type : AddressType,
  le_connection_interval_min : 16,
  le_connection_interval_max : 16,
  le_connection_latency : 16,
  le_connection_supervision_timeout : 16,
  conn_interval : 16,
  conn_peripheral_latency : 16,
  conn_supervision_timeout : 16,
}

packet LeConnectComplete : LinkLayerPacket (type = LE_CONNECT_COMPLETE) {
  initiating_address_type : AddressType,
  advertising_address_type : AddressType,
  le_connection_interval : 16,
  le_connection_latency : 16,
  le_connection_supervision_timeout : 16,
  conn_interval : 16,
  conn_peripheral_latency : 16,
  conn_supervision_timeout : 16,
}

packet LeScan : LinkLayerPacket (type = LE_SCAN) {
+3 −3
Original line number Diff line number Diff line
@@ -17,7 +17,7 @@ class Test(ControllerTest):
        LL_advertiser_Adv_Channel_Map = 0x7
        controller = self.controller
        peer_address = Address('aa:bb:cc:dd:ee:ff')
        invalid_scan_address = Address([
        invalid_local_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]
        ])
@@ -136,7 +136,7 @@ class Test(ControllerTest):
                                          advertising_data=[]))

            controller.send_ll(ll.LeScan(source_address=peer_address,
                                         destination_address=invalid_scan_address,
                                         destination_address=invalid_local_address,
                                         advertising_address_type=ll.AddressType.PUBLIC,
                                         scanning_address_type=ll.AddressType.PUBLIC),
                               rssi=0xf0)
@@ -164,7 +164,7 @@ class Test(ControllerTest):
                                          advertising_data=[]))

            controller.send_ll(ll.LeScan(source_address=peer_address,
                                         destination_address=invalid_scan_address,
                                         destination_address=invalid_local_address,
                                         advertising_address_type=ll.AddressType.PUBLIC,
                                         scanning_address_type=ll.AddressType.PUBLIC),
                               rssi=0xf0)
+157 −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-06-C [Connection Request]
    async def test(self):
        # Test parameters.
        LL_advertiser_advInterval_MIN = 0x200
        LL_advertiser_advInterval_MAX = 0x200
        LL_initiator_connInterval = 0x200
        LL_initiator_connPeripheralLatency = 0x200
        LL_initiator_connSupervisionTimeout = 0x200
        LL_advertiser_Adv_Channel_Map = 0x7
        controller = self.controller
        peer_address = Address('aa:bb:cc:dd:ee:ff')
        invalid_local_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]
        ])
        connection_handle = 0xefe

        # 1. Upper Tester enables 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))

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

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

        # 2. Configure Lower Tester to monitor the advertising and connection procedures of the IUT and
        # send a CONNECT_IND packet on the first supported advertising channel.
        # 3. Configure Lower Tester to use a public device address as parameter of CONNECT_IND.

        # 4. The Lower Tester receives an ADV_IND packet from the IUT and responds with a
        # CONNECT_IND packet T_IFS after the end of the advertising packet.
        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.LeConnect(source_address=peer_address,
                                        destination_address=controller.address,
                                        initiating_address_type=ll.AddressType.PUBLIC,
                                        advertising_address_type=ll.AddressType.PUBLIC,
                                        conn_interval=LL_initiator_connInterval,
                                        conn_peripheral_latency=LL_initiator_connPeripheralLatency,
                                        conn_supervision_timeout=LL_initiator_connSupervisionTimeout),
                           rssi=0xf0)

        # 5. The Lower Tester receives no ADV_IND packet after the advertising interval from the IUT. Wait
        # for a time equal to 4 advertising intervals to check that no ADV_IND is received.
        # Note: Link layer sends LeConnectComplete here.
        await self.expect_ll(
            ll.LeConnectComplete(source_address=controller.address,
                                 destination_address=peer_address,
                                 conn_interval=LL_initiator_connInterval,
                                 conn_peripheral_latency=LL_initiator_connPeripheralLatency,
                                 conn_supervision_timeout=LL_initiator_connSupervisionTimeout))

        # 6. Upper Tester receives an HCI_LE_Connection_Complete event from the IUT including the
        # parameters sent to the IUT in step 4.
        await self.expect_evt(
            hci.LeEnhancedConnectionComplete(status=ErrorCode.SUCCESS,
                                             connection_handle=connection_handle,
                                             role=hci.Role.PERIPHERAL,
                                             peer_address_type=hci.AddressType.PUBLIC_DEVICE_ADDRESS,
                                             peer_address=peer_address,
                                             conn_interval=LL_initiator_connInterval,
                                             conn_latency=LL_initiator_connPeripheralLatency,
                                             supervision_timeout=LL_initiator_connSupervisionTimeout,
                                             central_clock_accuracy=hci.ClockAccuracy.PPM_500))

        # 7. The Upper Tester sends an HCI_Disconnect command to the IUT with the Connection_Handle
        # and receives a successful HCI_Command_Status event in return.
        controller.send_cmd(
            hci.Disconnect(connection_handle=connection_handle,
                           reason=hci.DisconnectReason.REMOTE_USER_TERMINATED_CONNECTION))

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

        # Note: Link layer sends Disconnect here.
        await self.expect_ll(
            ll.Disconnect(source_address=controller.address,
                          destination_address=peer_address,
                          reason=int(hci.DisconnectReason.REMOTE_USER_TERMINATED_CONNECTION)))

        # 8. The IUT sends an HCI_Disconnect_Complete event to the Upper Tester.
        await self.expect_evt(
            hci.DisconnectionComplete(status=ErrorCode.SUCCESS,
                                      connection_handle=connection_handle,
                                      reason=hci.DisconnectReason.REMOTE_USER_TERMINATED_CONNECTION))

        # 9. Configure Lower Tester to use a public device address that differs from the IUT address in the
        # most significant octet as parameter of CONNECT_IND.
        # 10. Repeat steps 4–8.
        controller.send_cmd(hci.LeSetAdvertisingEnable(advertising_enable=True))

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

        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.LeConnect(source_address=peer_address,
                                        destination_address=invalid_local_address,
                                        initiating_address_type=ll.AddressType.PUBLIC,
                                        advertising_address_type=ll.AddressType.PUBLIC,
                                        conn_interval=LL_initiator_connInterval,
                                        conn_peripheral_latency=LL_initiator_connPeripheralLatency,
                                        conn_supervision_timeout=LL_initiator_connSupervisionTimeout),
                           rssi=0xf0)

        # Connect rejected, another ADV_IND event should be received.
        await self.expect_ll(
            ll.LeLegacyAdvertisingPdu(source_address=controller.address,
                                      advertising_address_type=ll.AddressType.PUBLIC,
                                      advertising_type=ll.LegacyAdvertisingType.ADV_IND,
                                      advertising_data=[]))

        # 11. Configure Lower Tester to use a public device address that differs from the IUT address in the
        # least significant octet as parameter of CONNECT_IND.

        # 12. Repeat steps 4–8.

        # 13. Configure Lower Tester to use a public device address that differs from the IUT address in the
        # most and least significant octets as parameter of CONNECT_IND.

        # 14. Repeat steps 4–8.

        # 15. Configure Lower Tester to monitor the advertising and connection procedures of the IUT and
        # send a CONNECT_IND packet on the second supported advertising channel.

        # 16. Repeat steps 3–14.

        # 17. Configure Lower Tester to monitor the advertising and connection procedures of the IUT and
        # send a CONNECT_IND packet on the third supported advertising channel.

        # 18. Repeat steps 3–14.
+121 −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-07-C [Scan Request Connection Request]
    async def test(self):
        # Test parameters.
        LL_advertiser_advInterval_MIN = 0x200
        LL_advertiser_advInterval_MAX = 0x200
        LL_initiator_connInterval = 0x200
        LL_initiator_connPeripheralLatency = 0x200
        LL_initiator_connSupervisionTimeout = 0x200
        LL_advertiser_Adv_Channel_Map = 0x7
        controller = self.controller
        peer_address = Address('aa:bb:cc:dd:ee:ff')
        connection_handle = 0xefe

        # 1. Upper Tester enables undirected advertising in the IUT using all supported advertising channels,
        # a selected advertising interval between the minimum and maximum advertising intervals, and
        # filtering policy set to ‘Allow Scan Request from Any, Allow Connect Request from Any (Default)
        # (0x00)’.
        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. Upper Tester sends an HCI_LE_Set_Scan_Response_Data command with data set to “IUT” and
        # receives an HCI_Command_Complete event from the IUT.
        scan_response_data = [ord('I'), ord('U'), ord('T')]
        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))

        # 3. Configure Lower Tester to monitor the advertising, scan response and connection procedures of
        # the IUT, sending a SCAN_REQ and a CONNECT_IND packet on a supported advertising
        # channel (defined as an IXIT).

        # 4. Lower Tester receives an ADV_IND packet from the IUT on the selected advertising channel and
        # responds with an SCAN_REQ packet on the selected advertising channel T_IFS after the end of
        # an advertising packet.
        # 5. Lower Tester receives an 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 SCAN_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. Lower Tester receives an ADV_IND packet from the IUT on the selected advertising channel and
        # responds with a CONNECT_IND packet T_IFS after the end of the advertising packet.
        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.LeConnect(source_address=peer_address,
                                        destination_address=controller.address,
                                        initiating_address_type=ll.AddressType.PUBLIC,
                                        advertising_address_type=ll.AddressType.PUBLIC,
                                        conn_interval=LL_initiator_connInterval,
                                        conn_peripheral_latency=LL_initiator_connPeripheralLatency,
                                        conn_supervision_timeout=LL_initiator_connSupervisionTimeout),
                           rssi=0xf0)

        # 8. The Lower Tester receives no ADV_IND packet after advertising interval from the IUT after
        # sending the connection request to indicate that the IUT has stopped advertising.
        # Note: Link layer sends LeConnectComplete here.
        await self.expect_ll(
            ll.LeConnectComplete(source_address=controller.address,
                                 destination_address=peer_address,
                                 conn_interval=LL_initiator_connInterval,
                                 conn_peripheral_latency=LL_initiator_connPeripheralLatency,
                                 conn_supervision_timeout=LL_initiator_connSupervisionTimeout))

        # 9. Upper Tester receives an HCI_LE_Connection_Complete event from the IUT including the
        # parameters sent to the IUT.
        await self.expect_evt(
            hci.LeEnhancedConnectionComplete(status=ErrorCode.SUCCESS,
                                             connection_handle=connection_handle,
                                             role=hci.Role.PERIPHERAL,
                                             peer_address_type=hci.AddressType.PUBLIC_DEVICE_ADDRESS,
                                             peer_address=peer_address,
                                             conn_interval=LL_initiator_connInterval,
                                             conn_latency=LL_initiator_connPeripheralLatency,
                                             supervision_timeout=LL_initiator_connSupervisionTimeout,
                                             central_clock_accuracy=hci.ClockAccuracy.PPM_500))

        # 10. Peripheral Connection Terminated (connection interval, Peripheral latency, timeout, channel map,
        # un-encrypted, connection handle from step 9).
Loading