Loading system/gd/hci/cert/le_advertising_manager_test_lib.py +55 −0 Original line number Diff line number Diff line Loading @@ -112,6 +112,61 @@ class LeAdvertisingManagerTestBase(): self.cert_hci.send_command( hci_packets.LeSetScanEnableBuilder(hci_packets.Enable.DISABLED, hci_packets.Enable.DISABLED)) def test_extended_create_advertises(self): self.set_address_policy_with_static_address() self.cert_hci.register_for_le_events(hci_packets.SubeventCode.ADVERTISING_REPORT, hci_packets.SubeventCode.EXTENDED_ADVERTISING_REPORT) # CERT Scans self.cert_hci.send_command(hci_packets.LeSetRandomAddressBuilder('0C:05:04:03:02:01')) scan_parameters = hci_packets.PhyScanParameters() scan_parameters.le_scan_type = hci_packets.LeScanType.ACTIVE scan_parameters.le_scan_interval = 40 scan_parameters.le_scan_window = 20 self.cert_hci.send_command( hci_packets.LeSetExtendedScanParametersBuilder(hci_packets.OwnAddressType.RANDOM_DEVICE_ADDRESS, hci_packets.LeScanningFilterPolicy.ACCEPT_ALL, 1, [scan_parameters])) self.cert_hci.send_command( hci_packets.LeSetExtendedScanEnableBuilder(hci_packets.Enable.ENABLED, hci_packets.FilterDuplicates.DISABLED, 0, 0)) gap_name = hci_packets.GapData() gap_name.data_type = hci_packets.GapDataType.COMPLETE_LOCAL_NAME gap_name.data = list(bytes(b'Im_The_DUT')) gap_data = le_advertising_facade.GapDataMsg(data=bytes(gap_name.Serialize())) config = le_advertising_facade.AdvertisingConfig( advertisement=[gap_data], interval_min=512, interval_max=768, advertising_type=le_advertising_facade.AdvertisingEventType.ADV_IND, own_address_type=common.USE_RANDOM_DEVICE_ADDRESS, channel_map=7, filter_policy=le_advertising_facade.AdvertisingFilterPolicy.ALL_DEVICES) extended_config = le_advertising_facade.ExtendedAdvertisingConfig( advertising_config=config, connectable=True, scannable=False, directed=False, high_duty_directed_connectable=False, legacy_pdus=True, anonymous=False, include_tx_power=True, use_le_coded_phy=False, secondary_max_skip=0x00, secondary_advertising_phy=0x01, sid=0x00, enable_scan_request_notifications=0x00) request = le_advertising_facade.ExtendedCreateAdvertiserRequest(config=extended_config) create_response = self.dut.hci_le_advertising_manager.ExtendedCreateAdvertiser(request) assertThat(self.cert_hci.get_le_event_stream()).emits(lambda packet: b'Im_The_DUT' in packet.payload) remove_request = le_advertising_facade.RemoveAdvertiserRequest(advertiser_id=create_response.advertiser_id) self.dut.hci_le_advertising_manager.RemoveAdvertiser(remove_request) self.cert_hci.send_command( hci_packets.LeSetScanEnableBuilder(hci_packets.Enable.DISABLED, hci_packets.Enable.DISABLED)) def test_advertising_set_started_callback(self): self.set_address_policy_with_static_address() create_response = self.create_advertiser() Loading system/gd/hci/facade/le_advertising_manager_facade.cc +48 −4 Original line number Diff line number Diff line Loading @@ -51,7 +51,7 @@ hci::GapData GapDataFromProto(const GapDataMsg& gap_data_proto) { return gap_data; } bool AdvertisingConfigFromProto(const AdvertisingConfig& config_proto, hci::AdvertisingConfig* config) { bool AdvertisingConfigFromProto(const AdvertisingConfig& config_proto, hci::ExtendedAdvertisingConfig* config) { for (const auto& elem : config_proto.advertisement()) { config->advertisement.push_back(GapDataFromProto(elem)); } Loading Loading @@ -94,6 +94,30 @@ bool AdvertisingConfigFromProto(const AdvertisingConfig& config_proto, hci::Adve config->filter_policy = static_cast<hci::AdvertisingFilterPolicy>(config_proto.filter_policy()); config->tx_power = static_cast<uint8_t>(config_proto.tx_power()); config->legacy_pdus = true; return true; } bool ExtendedAdvertisingConfigFromProto( const ExtendedAdvertisingConfig& config_proto, hci::ExtendedAdvertisingConfig* config) { if (!AdvertisingConfigFromProto(config_proto.advertising_config(), config)) { LOG_WARN("Error parsing advertising config"); return false; } config->connectable = config_proto.connectable(); config->scannable = config_proto.scannable(); config->directed = config_proto.directed(); config->high_duty_directed_connectable = config_proto.high_duty_directed_connectable(); config->legacy_pdus = config_proto.legacy_pdus(); config->anonymous = config_proto.anonymous(); config->include_tx_power = config_proto.include_tx_power(); config->use_le_coded_phy = config_proto.use_le_coded_phy(); config->secondary_max_skip = static_cast<uint8_t>(config_proto.secondary_max_skip()); config->secondary_advertising_phy = static_cast<hci::SecondaryPhyType>(config_proto.secondary_advertising_phy()); config->sid = static_cast<uint8_t>(config_proto.sid()); config->enable_scan_request_notifications = static_cast<hci::Enable>(config_proto.enable_scan_request_notifications()); return true; } Loading Loading @@ -173,9 +197,29 @@ class LeAdvertisingManagerFacadeService : public LeAdvertisingManagerFacade::Ser ::grpc::Status ExtendedCreateAdvertiser(::grpc::ServerContext* context, const ExtendedCreateAdvertiserRequest* request, ExtendedCreateAdvertiserResponse* response) override { LOG_WARN("ExtendedCreateAdvertiser is not implemented"); hci::ExtendedAdvertisingConfig config = {}; if (!ExtendedAdvertisingConfigFromProto(request->config(), &config)) { LOG_WARN("Error parsing advertising config %s", request->SerializeAsString().c_str()); response->set_advertiser_id(LeAdvertisingManager::kInvalidId); return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, "ExtendedCreateAdvertiser is not implemented"); return ::grpc::Status(::grpc::StatusCode::INVALID_ARGUMENT, "Error while parsing advertising config"); } LeAdvertiser le_advertiser(config); auto advertiser_id = le_advertising_manager_->ExtendedCreateAdvertiser( 0, config, common::Bind(&LeAdvertiser::ScanCallback, common::Unretained(&le_advertiser)), common::Bind(&LeAdvertiser::TerminatedCallback, common::Unretained(&le_advertiser)), 0, 0, facade_handler_); if (advertiser_id != LeAdvertisingManager::kInvalidId) { le_advertiser.SetAdvertiserId(advertiser_id); le_advertisers_.push_back(le_advertiser); } else { LOG_WARN("Failed to create advertiser"); } response->set_advertiser_id(advertiser_id); return ::grpc::Status::OK; } ::grpc::Status EnableAdvertiser( Loading system/gd/hci/facade/le_advertising_manager_facade.proto +3 −2 Original line number Diff line number Diff line Loading @@ -80,10 +80,10 @@ message ExtendedAdvertisingConfig { bool anonymous = 7; bool include_tx_power = 8; bool use_le_coded_phy = 9; int32 secondary_map_skip = 10; int32 secondary_max_skip = 10; int32 secondary_advertising_phy = 11; int32 sid = 12; bool enable_scan_request_notification = 13; bool enable_scan_request_notifications = 13; } message PeriodicAdvertisingParameters { Loading @@ -106,6 +106,7 @@ message ExtendedCreateAdvertiserRequest { } message ExtendedCreateAdvertiserResponse { // -1 on error int32 advertiser_id = 1; } Loading Loading
system/gd/hci/cert/le_advertising_manager_test_lib.py +55 −0 Original line number Diff line number Diff line Loading @@ -112,6 +112,61 @@ class LeAdvertisingManagerTestBase(): self.cert_hci.send_command( hci_packets.LeSetScanEnableBuilder(hci_packets.Enable.DISABLED, hci_packets.Enable.DISABLED)) def test_extended_create_advertises(self): self.set_address_policy_with_static_address() self.cert_hci.register_for_le_events(hci_packets.SubeventCode.ADVERTISING_REPORT, hci_packets.SubeventCode.EXTENDED_ADVERTISING_REPORT) # CERT Scans self.cert_hci.send_command(hci_packets.LeSetRandomAddressBuilder('0C:05:04:03:02:01')) scan_parameters = hci_packets.PhyScanParameters() scan_parameters.le_scan_type = hci_packets.LeScanType.ACTIVE scan_parameters.le_scan_interval = 40 scan_parameters.le_scan_window = 20 self.cert_hci.send_command( hci_packets.LeSetExtendedScanParametersBuilder(hci_packets.OwnAddressType.RANDOM_DEVICE_ADDRESS, hci_packets.LeScanningFilterPolicy.ACCEPT_ALL, 1, [scan_parameters])) self.cert_hci.send_command( hci_packets.LeSetExtendedScanEnableBuilder(hci_packets.Enable.ENABLED, hci_packets.FilterDuplicates.DISABLED, 0, 0)) gap_name = hci_packets.GapData() gap_name.data_type = hci_packets.GapDataType.COMPLETE_LOCAL_NAME gap_name.data = list(bytes(b'Im_The_DUT')) gap_data = le_advertising_facade.GapDataMsg(data=bytes(gap_name.Serialize())) config = le_advertising_facade.AdvertisingConfig( advertisement=[gap_data], interval_min=512, interval_max=768, advertising_type=le_advertising_facade.AdvertisingEventType.ADV_IND, own_address_type=common.USE_RANDOM_DEVICE_ADDRESS, channel_map=7, filter_policy=le_advertising_facade.AdvertisingFilterPolicy.ALL_DEVICES) extended_config = le_advertising_facade.ExtendedAdvertisingConfig( advertising_config=config, connectable=True, scannable=False, directed=False, high_duty_directed_connectable=False, legacy_pdus=True, anonymous=False, include_tx_power=True, use_le_coded_phy=False, secondary_max_skip=0x00, secondary_advertising_phy=0x01, sid=0x00, enable_scan_request_notifications=0x00) request = le_advertising_facade.ExtendedCreateAdvertiserRequest(config=extended_config) create_response = self.dut.hci_le_advertising_manager.ExtendedCreateAdvertiser(request) assertThat(self.cert_hci.get_le_event_stream()).emits(lambda packet: b'Im_The_DUT' in packet.payload) remove_request = le_advertising_facade.RemoveAdvertiserRequest(advertiser_id=create_response.advertiser_id) self.dut.hci_le_advertising_manager.RemoveAdvertiser(remove_request) self.cert_hci.send_command( hci_packets.LeSetScanEnableBuilder(hci_packets.Enable.DISABLED, hci_packets.Enable.DISABLED)) def test_advertising_set_started_callback(self): self.set_address_policy_with_static_address() create_response = self.create_advertiser() Loading
system/gd/hci/facade/le_advertising_manager_facade.cc +48 −4 Original line number Diff line number Diff line Loading @@ -51,7 +51,7 @@ hci::GapData GapDataFromProto(const GapDataMsg& gap_data_proto) { return gap_data; } bool AdvertisingConfigFromProto(const AdvertisingConfig& config_proto, hci::AdvertisingConfig* config) { bool AdvertisingConfigFromProto(const AdvertisingConfig& config_proto, hci::ExtendedAdvertisingConfig* config) { for (const auto& elem : config_proto.advertisement()) { config->advertisement.push_back(GapDataFromProto(elem)); } Loading Loading @@ -94,6 +94,30 @@ bool AdvertisingConfigFromProto(const AdvertisingConfig& config_proto, hci::Adve config->filter_policy = static_cast<hci::AdvertisingFilterPolicy>(config_proto.filter_policy()); config->tx_power = static_cast<uint8_t>(config_proto.tx_power()); config->legacy_pdus = true; return true; } bool ExtendedAdvertisingConfigFromProto( const ExtendedAdvertisingConfig& config_proto, hci::ExtendedAdvertisingConfig* config) { if (!AdvertisingConfigFromProto(config_proto.advertising_config(), config)) { LOG_WARN("Error parsing advertising config"); return false; } config->connectable = config_proto.connectable(); config->scannable = config_proto.scannable(); config->directed = config_proto.directed(); config->high_duty_directed_connectable = config_proto.high_duty_directed_connectable(); config->legacy_pdus = config_proto.legacy_pdus(); config->anonymous = config_proto.anonymous(); config->include_tx_power = config_proto.include_tx_power(); config->use_le_coded_phy = config_proto.use_le_coded_phy(); config->secondary_max_skip = static_cast<uint8_t>(config_proto.secondary_max_skip()); config->secondary_advertising_phy = static_cast<hci::SecondaryPhyType>(config_proto.secondary_advertising_phy()); config->sid = static_cast<uint8_t>(config_proto.sid()); config->enable_scan_request_notifications = static_cast<hci::Enable>(config_proto.enable_scan_request_notifications()); return true; } Loading Loading @@ -173,9 +197,29 @@ class LeAdvertisingManagerFacadeService : public LeAdvertisingManagerFacade::Ser ::grpc::Status ExtendedCreateAdvertiser(::grpc::ServerContext* context, const ExtendedCreateAdvertiserRequest* request, ExtendedCreateAdvertiserResponse* response) override { LOG_WARN("ExtendedCreateAdvertiser is not implemented"); hci::ExtendedAdvertisingConfig config = {}; if (!ExtendedAdvertisingConfigFromProto(request->config(), &config)) { LOG_WARN("Error parsing advertising config %s", request->SerializeAsString().c_str()); response->set_advertiser_id(LeAdvertisingManager::kInvalidId); return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, "ExtendedCreateAdvertiser is not implemented"); return ::grpc::Status(::grpc::StatusCode::INVALID_ARGUMENT, "Error while parsing advertising config"); } LeAdvertiser le_advertiser(config); auto advertiser_id = le_advertising_manager_->ExtendedCreateAdvertiser( 0, config, common::Bind(&LeAdvertiser::ScanCallback, common::Unretained(&le_advertiser)), common::Bind(&LeAdvertiser::TerminatedCallback, common::Unretained(&le_advertiser)), 0, 0, facade_handler_); if (advertiser_id != LeAdvertisingManager::kInvalidId) { le_advertiser.SetAdvertiserId(advertiser_id); le_advertisers_.push_back(le_advertiser); } else { LOG_WARN("Failed to create advertiser"); } response->set_advertiser_id(advertiser_id); return ::grpc::Status::OK; } ::grpc::Status EnableAdvertiser( Loading
system/gd/hci/facade/le_advertising_manager_facade.proto +3 −2 Original line number Diff line number Diff line Loading @@ -80,10 +80,10 @@ message ExtendedAdvertisingConfig { bool anonymous = 7; bool include_tx_power = 8; bool use_le_coded_phy = 9; int32 secondary_map_skip = 10; int32 secondary_max_skip = 10; int32 secondary_advertising_phy = 11; int32 sid = 12; bool enable_scan_request_notification = 13; bool enable_scan_request_notifications = 13; } message PeriodicAdvertisingParameters { Loading @@ -106,6 +106,7 @@ message ExtendedCreateAdvertiserRequest { } message ExtendedCreateAdvertiserResponse { // -1 on error int32 advertiser_id = 1; } Loading