From 295c1b256a2717151574e24d05377ebf0a6193bb Mon Sep 17 00:00:00 2001 From: Ayushi Khopkar Date: Thu, 19 May 2022 06:32:58 +0000 Subject: [PATCH 0001/2405] btcore_property_fuzzer: Bug Fix Resolved 'Missing Library' error for android.hardware.bluetooth.audio-V2-ndk.so Test: ./btcore_property_fuzzer Bug: 216476246 Ignore-AOSP-First: Code of git_master is ahead of AOSP master Change-Id: I8485a6ce391a021975fa6123e4d5932ba9aa8f5d --- system/btcore/fuzzer/Android.bp | 1 + 1 file changed, 1 insertion(+) diff --git a/system/btcore/fuzzer/Android.bp b/system/btcore/fuzzer/Android.bp index 2b19ea40822..83cb78c455c 100644 --- a/system/btcore/fuzzer/Android.bp +++ b/system/btcore/fuzzer/Android.bp @@ -28,6 +28,7 @@ cc_defaults { shared_libs: [ "android.hardware.bluetooth@1.0", "android.hardware.bluetooth@1.1", + "android.hardware.bluetooth.audio-V2-ndk", "libcrypto", "libstatslog_bt", ], -- GitLab From 010f679afe8ee8cdfdb53a762d6374017c36a1bb Mon Sep 17 00:00:00 2001 From: Sonny Sasaka Date: Mon, 5 Dec 2022 11:49:13 -0800 Subject: [PATCH 0002/2405] Floss: Notify OnScannerRegistered when RegisterScanner fails Client needs to know if RegisterScanner fails, so we should still call OnScannerRegisteredCallback when it fails. Bug: 217273154 Tag: #floss Test: Build Floss on Linux Change-Id: I9c9cf4189aee970594d53eb0117be6b05a3511f3 --- system/gd/rust/linux/stack/src/bluetooth_gatt.rs | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/system/gd/rust/linux/stack/src/bluetooth_gatt.rs b/system/gd/rust/linux/stack/src/bluetooth_gatt.rs index 0d4c4dedfbd..6eef0c34cc0 100644 --- a/system/gd/rust/linux/stack/src/bluetooth_gatt.rs +++ b/system/gd/rust/linux/stack/src/bluetooth_gatt.rs @@ -2454,12 +2454,6 @@ impl BtifGattScannerCallbacks for BluetoothGatt { status ); - if status != GattStatus::Success { - log::error!("Error registering scanner UUID {}", uuid); - self.scanners.lock().unwrap().remove(&uuid); - return; - } - let mut scanners_lock = self.scanners.lock().unwrap(); let scanner_info = scanners_lock.get_mut(&uuid); @@ -2477,6 +2471,11 @@ impl BtifGattScannerCallbacks for BluetoothGatt { uuid ); } + + if status != GattStatus::Success { + log::error!("Error registering scanner UUID {}", uuid); + scanners_lock.remove(&uuid); + } } fn on_scan_result( -- GitLab From c58747f972dd31a65836f13f3b6d0ebf43059a17 Mon Sep 17 00:00:00 2001 From: kunal rai Date: Fri, 9 Dec 2022 14:39:10 +0530 Subject: [PATCH 0003/2405] Updated fuzzers for libbt-audio-hal-interface This patch updates fuzzers to only feed valid pcm parameters to libbt-audio-hal-interface and add checks for successful completion of a2dp::init() and a2dp::setup_codec() methods Test: ./libbt_audio_hal_a2dp_encoding_fuzzer exec/s for libbt_audio_hal_a2dp_encoding_fuzzer: 58 Test: ./libbt_audio_hal_le_audio_software_fuzzer exec/s for libbt_audio_hal_le_audio_software_fuzzer: 72 Test: ./libbt_audio_hal_hearing_aid_software_encoding_fuzzer exec/s for libbt_audio_hal_hearing_aid_software_encoding_fuzzer: 125 Test: ./libbt_audio_hal_client_interface_fuzzer exec/s for libbt_audio_hal_client_interface_fuzzer: 95 Bug: 220381921 Bug: 220329620 Change-Id: Id4293d0ed44101081d576aa8fca61e43bf04139e --- .../libbt_audio_hal_a2dp_encoding_fuzzer.cpp | 10 ++++++++-- ...libbt_audio_hal_le_audio_software_fuzzer.cpp | 17 +++++++++-------- 2 files changed, 17 insertions(+), 10 deletions(-) diff --git a/system/audio_hal_interface/fuzzer/libbt_audio_hal_a2dp_encoding_fuzzer.cpp b/system/audio_hal_interface/fuzzer/libbt_audio_hal_a2dp_encoding_fuzzer.cpp index 1a33b5b39e6..4f7954e01c1 100644 --- a/system/audio_hal_interface/fuzzer/libbt_audio_hal_a2dp_encoding_fuzzer.cpp +++ b/system/audio_hal_interface/fuzzer/libbt_audio_hal_a2dp_encoding_fuzzer.cpp @@ -93,8 +93,14 @@ void A2dpEncodingFuzzer::process(const uint8_t* data, size_t size) { uint16_t delayReport = fdp.ConsumeIntegral(); bluetooth::audio::a2dp::set_remote_delay(delayReport); - (void)bluetooth::audio::a2dp::init(&messageLoopThread); - (void)bluetooth::audio::a2dp::setup_codec(); + if (!bluetooth::audio::a2dp::init(&messageLoopThread)) { + return; + } + + if (!bluetooth::audio::a2dp::setup_codec()) { + return; + } + bluetooth::audio::a2dp::start_session(); tA2DP_CTRL_ACK status = fdp.PickValueInArray(kCtrlAckStatus); diff --git a/system/audio_hal_interface/fuzzer/libbt_audio_hal_le_audio_software_fuzzer.cpp b/system/audio_hal_interface/fuzzer/libbt_audio_hal_le_audio_software_fuzzer.cpp index bf24b176ae1..006c7a0fa37 100644 --- a/system/audio_hal_interface/fuzzer/libbt_audio_hal_le_audio_software_fuzzer.cpp +++ b/system/audio_hal_interface/fuzzer/libbt_audio_hal_le_audio_software_fuzzer.cpp @@ -24,12 +24,11 @@ using ::bluetooth::audio::le_audio::LeAudioClientInterface; constexpr int32_t kRandomStringLength = 256; -constexpr uint8_t kBitsPerSample[] = {0, 16, 24, 32}; +constexpr uint8_t kBitsPerSample[] = {16, 24, 32}; -constexpr uint8_t kChannelCount[] = {0, 1, 2}; +constexpr uint8_t kChannelCount[] = {1, 2}; -constexpr uint32_t kSampleRates[] = {0, 8000, 16000, 24000, 32000, 44100, - 48000, 88200, 96000, 176400, 192000}; +constexpr uint32_t kSampleRates[] = {16000, 24000, 44100, 48000, 88200, 96000}; extern "C" { struct android_namespace_t* android_get_exported_namespace(const char*) { @@ -65,15 +64,16 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) { LeAudioClientInterface::Source* source = interface->GetSource(streamCb, &messageLoopThread); if (source != nullptr) { - source->StartSession(); uint16_t delay = fdp.ConsumeIntegral(); source->SetRemoteDelay(delay); LeAudioClientInterface::PcmParameters params; - params.data_interval_us = fdp.ConsumeIntegral(); + params.data_interval_us = fdp.ConsumeIntegralInRange( + 1000, std::numeric_limits::max()); params.sample_rate = fdp.PickValueInArray(kSampleRates); params.bits_per_sample = fdp.PickValueInArray(kBitsPerSample); params.channels_count = fdp.PickValueInArray(kChannelCount); source->SetPcmParameters(params); + source->StartSession(); source->StopSession(); source->Cleanup(); } @@ -84,15 +84,16 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) { LeAudioClientInterface::Sink* sink = interface->GetSink(streamCb, &messageLoopThread, false); if (sink != nullptr) { - sink->StartSession(); uint16_t delay = fdp.ConsumeIntegral(); sink->SetRemoteDelay(delay); LeAudioClientInterface::PcmParameters params; - params.data_interval_us = fdp.ConsumeIntegral(); + params.data_interval_us = fdp.ConsumeIntegralInRange( + 1000, std::numeric_limits::max()); params.sample_rate = fdp.PickValueInArray(kSampleRates); params.bits_per_sample = fdp.PickValueInArray(kBitsPerSample); params.channels_count = fdp.PickValueInArray(kChannelCount); sink->SetPcmParameters(params); + sink->StartSession(); sink->StopSession(); sink->Cleanup(); } -- GitLab From 0730e80b4c278c2cc44f5c5492d2bf75610eda7c Mon Sep 17 00:00:00 2001 From: Brian Delwiche Date: Thu, 22 Dec 2022 00:01:21 +0000 Subject: [PATCH 0004/2405] Fix fuzzer testcase Fuzzer reports show memory leaks emanating from fuzz_alarm.cc. On investigation these are invalid and stem from problems with memory and flow management in the fuzzer implementation. Fix those issues. Bug: 262875478 Test: fuzz Tag: #security Ignore-AOSP-First: Security Change-Id: I3db039f3841bb19be52957fdb968ff09c9327e7f --- system/osi/test/fuzzers/alarm/fuzz_alarm.cc | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/system/osi/test/fuzzers/alarm/fuzz_alarm.cc b/system/osi/test/fuzzers/alarm/fuzz_alarm.cc index c432f8c5c1d..d449c7f4d3c 100644 --- a/system/osi/test/fuzzers/alarm/fuzz_alarm.cc +++ b/system/osi/test/fuzzers/alarm/fuzz_alarm.cc @@ -107,6 +107,7 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t* Data, size_t Size) { // Alarm must be non-null, or set() will trigger assert if (alarm) { if (!fuzz_set_alarm(alarm, MAX_ALARM_DURATION, cb, &dataProvider)) { + alarm_free(alarm); return 0; } alarm_cancel(alarm); @@ -122,8 +123,9 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t* Data, size_t Size) { for (int i = 0; i < num_alarms; i++) { uint64_t interval = dataProvider.ConsumeIntegralInRange(0, MAX_ALARM_DURATION); - if (fuzz_set_alarm(alarm, interval, cb, &dataProvider)) { - return 0; + if (!fuzz_set_alarm(alarm, interval, cb, &dataProvider)) { + num_alarms = i; + break; } alarm_get_remaining_ms(alarm); } -- GitLab From e64e87dda5a6e9a4135d32e7ed76f384c9b89473 Mon Sep 17 00:00:00 2001 From: Chih-Hung Hsieh Date: Wed, 18 Jan 2023 16:44:51 -0800 Subject: [PATCH 0005/2405] Fix sizeof warnings on calloc * This calloc just needs hdr_size bytes, not an array of uint8_t. * Applied clang-format. Bug: 261919363 Test: presubmit; tidy-packages-modules-Bluetooth-system-stack-test-fuzzers_subset Change-Id: I83230f081d797a65f7839a603ca9d98ec8ee121f --- .../stack/test/fuzzers/a2dp/codec/a2dpCodecHelperFunctions.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/system/stack/test/fuzzers/a2dp/codec/a2dpCodecHelperFunctions.h b/system/stack/test/fuzzers/a2dp/codec/a2dpCodecHelperFunctions.h index 81887e0d6c0..28356deca2b 100644 --- a/system/stack/test/fuzzers/a2dp/codec/a2dpCodecHelperFunctions.h +++ b/system/stack/test/fuzzers/a2dp/codec/a2dpCodecHelperFunctions.h @@ -132,8 +132,8 @@ std::shared_ptr getArbitraryBtHdr(FuzzedDataProvider* fdp) { } uint16_t hdr_size = bytes.size() + sizeof(BT_HDR); - std::shared_ptr bt_hdr( - reinterpret_cast(calloc(hdr_size, sizeof(uint8_t))), free); + std::shared_ptr bt_hdr(reinterpret_cast(calloc(1, hdr_size)), + free); bt_hdr->event = fdp->ConsumeIntegral(); bt_hdr->len = bytes.size(); -- GitLab From 56291415103815bbe8e5fc86876e83e2e4fa9b17 Mon Sep 17 00:00:00 2001 From: Bill Yi Date: Tue, 21 Feb 2023 09:13:25 -0800 Subject: [PATCH 0006/2405] Import translations. DO NOT MERGE ANYWHERE Auto-generated-cl: translation import Change-Id: Icfdad0b8884db54d34ca20f31520f6a1057dbe0c --- android/app/res/values-af/strings_pbap.xml | 4 ++++ android/app/res/values-am/strings_pbap.xml | 4 ++++ android/app/res/values-ar/strings_pbap.xml | 4 ++++ android/app/res/values-as/strings_pbap.xml | 4 ++++ android/app/res/values-az/strings_pbap.xml | 4 ++++ android/app/res/values-b+sr+Latn/strings_pbap.xml | 2 ++ android/app/res/values-be/strings_pbap.xml | 4 ++++ android/app/res/values-bg/strings_pbap.xml | 4 ++++ android/app/res/values-bn/strings_pbap.xml | 4 ++++ android/app/res/values-bs/strings_pbap.xml | 2 ++ android/app/res/values-ca/strings_pbap.xml | 4 ++++ android/app/res/values-cs/strings_pbap.xml | 4 ++++ android/app/res/values-da/strings_pbap.xml | 4 ++++ android/app/res/values-de/strings_pbap.xml | 4 ++++ android/app/res/values-el/strings_pbap.xml | 2 ++ android/app/res/values-en-rAU/strings_pbap.xml | 2 ++ android/app/res/values-en-rCA/strings_pbap.xml | 2 ++ android/app/res/values-en-rGB/strings_pbap.xml | 2 ++ android/app/res/values-en-rIN/strings_pbap.xml | 2 ++ android/app/res/values-en-rXC/strings_pbap.xml | 2 ++ android/app/res/values-es-rUS/strings_pbap.xml | 4 ++++ android/app/res/values-es/strings_pbap.xml | 4 ++++ android/app/res/values-et/strings_pbap.xml | 4 ++++ android/app/res/values-eu/strings_pbap.xml | 4 ++++ android/app/res/values-fa/strings_pbap.xml | 4 ++++ android/app/res/values-fi/strings_pbap.xml | 4 ++++ android/app/res/values-fr-rCA/strings_pbap.xml | 4 ++++ android/app/res/values-fr/strings_pbap.xml | 4 ++++ android/app/res/values-gl/strings_pbap.xml | 4 ++++ android/app/res/values-gu/strings_pbap.xml | 4 ++++ android/app/res/values-hi/strings_pbap.xml | 4 ++++ android/app/res/values-hr/strings_pbap.xml | 2 ++ android/app/res/values-hu/strings_pbap.xml | 4 ++++ android/app/res/values-hy/strings_pbap.xml | 2 ++ android/app/res/values-in/strings_pbap.xml | 4 ++++ android/app/res/values-is/strings_pbap.xml | 4 ++++ android/app/res/values-it/strings_pbap.xml | 2 ++ android/app/res/values-iw/strings_pbap.xml | 4 ++++ android/app/res/values-ja/strings_pbap.xml | 4 ++++ android/app/res/values-ka/strings_pbap.xml | 4 ++++ android/app/res/values-kk/strings_pbap.xml | 4 ++++ android/app/res/values-km/strings_pbap.xml | 4 ++++ android/app/res/values-kn/strings_pbap.xml | 4 ++++ android/app/res/values-ko/strings_pbap.xml | 4 ++++ android/app/res/values-ky/strings_pbap.xml | 4 ++++ android/app/res/values-lo/strings_pbap.xml | 4 ++++ android/app/res/values-lt/strings_pbap.xml | 4 ++++ android/app/res/values-lv/strings_pbap.xml | 4 ++++ android/app/res/values-mk/strings_pbap.xml | 4 ++++ android/app/res/values-ml/strings_pbap.xml | 2 ++ android/app/res/values-mn/strings_pbap.xml | 4 ++++ android/app/res/values-mr/strings_pbap.xml | 4 ++++ android/app/res/values-ms/strings_pbap.xml | 4 ++++ android/app/res/values-my/strings_pbap.xml | 4 ++++ android/app/res/values-nb/strings_pbap.xml | 4 ++++ android/app/res/values-ne/strings_pbap.xml | 4 ++++ android/app/res/values-nl/strings_pbap.xml | 4 ++++ android/app/res/values-or/strings_pbap.xml | 4 ++++ android/app/res/values-pa/strings_pbap.xml | 4 ++++ android/app/res/values-pl/strings_pbap.xml | 4 ++++ android/app/res/values-pt-rPT/strings_pbap.xml | 6 ++++-- android/app/res/values-pt/strings_pbap.xml | 6 ++++-- android/app/res/values-ro/strings_pbap.xml | 4 ++++ android/app/res/values-ru/strings_pbap.xml | 2 ++ android/app/res/values-si/strings_pbap.xml | 4 ++++ android/app/res/values-sk/strings_pbap.xml | 4 ++++ android/app/res/values-sl/strings_pbap.xml | 4 ++++ android/app/res/values-sq/strings_pbap.xml | 4 ++++ android/app/res/values-sr/strings_pbap.xml | 2 ++ android/app/res/values-sv/strings_pbap.xml | 4 ++++ android/app/res/values-sw/strings_pbap.xml | 4 ++++ android/app/res/values-ta/strings_pbap.xml | 4 ++++ android/app/res/values-te/strings_pbap.xml | 4 ++++ android/app/res/values-th/strings_pbap.xml | 2 ++ android/app/res/values-tl/strings_pbap.xml | 4 ++++ android/app/res/values-tr/strings_pbap.xml | 4 ++++ android/app/res/values-uk/strings_pbap.xml | 4 ++++ android/app/res/values-ur/strings_pbap.xml | 4 ++++ android/app/res/values-uz/strings_pbap.xml | 2 ++ android/app/res/values-vi/strings_pbap.xml | 4 ++++ android/app/res/values-zh-rCN/strings_pbap.xml | 4 ++++ android/app/res/values-zh-rHK/strings_pbap.xml | 4 ++++ android/app/res/values-zh-rTW/strings_pbap.xml | 4 ++++ android/app/res/values-zu/strings_pbap.xml | 4 ++++ 84 files changed, 304 insertions(+), 4 deletions(-) diff --git a/android/app/res/values-af/strings_pbap.xml b/android/app/res/values-af/strings_pbap.xml index 65bffa555e8..ac5e6e52b28 100644 --- a/android/app/res/values-af/strings_pbap.xml +++ b/android/app/res/values-af/strings_pbap.xml @@ -13,4 +13,8 @@ "My naam" "000000" "Bluetooth-kontakdeling" + + + + diff --git a/android/app/res/values-am/strings_pbap.xml b/android/app/res/values-am/strings_pbap.xml index 132be0f6d2d..e3f1b4e6ebd 100644 --- a/android/app/res/values-am/strings_pbap.xml +++ b/android/app/res/values-am/strings_pbap.xml @@ -13,4 +13,8 @@ "የእኔ ስም" "000000" "ብሉቱዝ የእውቂያ መጋራት" + + + + diff --git a/android/app/res/values-ar/strings_pbap.xml b/android/app/res/values-ar/strings_pbap.xml index acab2fa3846..4903d956f8a 100644 --- a/android/app/res/values-ar/strings_pbap.xml +++ b/android/app/res/values-ar/strings_pbap.xml @@ -13,4 +13,8 @@ "اسمي" "000000" "مشاركة جهات الاتصال عبر البلوتوث" + + + + diff --git a/android/app/res/values-as/strings_pbap.xml b/android/app/res/values-as/strings_pbap.xml index 65f55573159..01061c4c4ef 100644 --- a/android/app/res/values-as/strings_pbap.xml +++ b/android/app/res/values-as/strings_pbap.xml @@ -13,4 +13,8 @@ "মোৰ নাম" "০০০০০০" "ব্লুটুথ সম্পৰ্ক শ্বেয়াৰ" + + + + diff --git a/android/app/res/values-az/strings_pbap.xml b/android/app/res/values-az/strings_pbap.xml index 8bb340b37ca..bf4abacf810 100644 --- a/android/app/res/values-az/strings_pbap.xml +++ b/android/app/res/values-az/strings_pbap.xml @@ -13,4 +13,8 @@ "Mənim adım" "000000" "Bluetooth Kontakt paylaşımı" + + + + diff --git a/android/app/res/values-b+sr+Latn/strings_pbap.xml b/android/app/res/values-b+sr+Latn/strings_pbap.xml index 4e7ee77aef9..78f6961c9b1 100644 --- a/android/app/res/values-b+sr+Latn/strings_pbap.xml +++ b/android/app/res/values-b+sr+Latn/strings_pbap.xml @@ -13,4 +13,6 @@ "Moje ime" "000000" "Deljenje kontakata preko Bluetooth-a" + "Podržana je napredna funkcija telefonskog imenika" + "Ponovno uparivanje za naprednu funkciju telefonskog imenika" diff --git a/android/app/res/values-be/strings_pbap.xml b/android/app/res/values-be/strings_pbap.xml index 87a85ac08c4..87a3f45c395 100644 --- a/android/app/res/values-be/strings_pbap.xml +++ b/android/app/res/values-be/strings_pbap.xml @@ -13,4 +13,8 @@ "Маё імя" "000000" "Абагульванне кантактаў праз Bluetooth" + + + + diff --git a/android/app/res/values-bg/strings_pbap.xml b/android/app/res/values-bg/strings_pbap.xml index 004c9f190a6..04a6befe089 100644 --- a/android/app/res/values-bg/strings_pbap.xml +++ b/android/app/res/values-bg/strings_pbap.xml @@ -13,4 +13,8 @@ "Моето име" "000000" "Споделяне на контакта през Bluetooth" + + + + diff --git a/android/app/res/values-bn/strings_pbap.xml b/android/app/res/values-bn/strings_pbap.xml index d93abb6921c..f1ca862b333 100644 --- a/android/app/res/values-bn/strings_pbap.xml +++ b/android/app/res/values-bn/strings_pbap.xml @@ -13,4 +13,8 @@ "আমার নাম" "০০০০০০" "ব্লুটুথ পরিচিতির সাথে শেয়ার করা" + + + + diff --git a/android/app/res/values-bs/strings_pbap.xml b/android/app/res/values-bs/strings_pbap.xml index 2f94d05ef75..74b17568424 100644 --- a/android/app/res/values-bs/strings_pbap.xml +++ b/android/app/res/values-bs/strings_pbap.xml @@ -13,4 +13,6 @@ "Moje ime" "000000" "Dijeljenje kontakata putem Bluetootha" + "Podržana je napredna značajka telefonskog imenika" + "Popravak napredne značajke telefonskog imenika" diff --git a/android/app/res/values-ca/strings_pbap.xml b/android/app/res/values-ca/strings_pbap.xml index f8dcebfdef7..c9280888e07 100644 --- a/android/app/res/values-ca/strings_pbap.xml +++ b/android/app/res/values-ca/strings_pbap.xml @@ -13,4 +13,8 @@ "El meu nom" "000000" "Compartir contactes amb Bluetooth" + + + + diff --git a/android/app/res/values-cs/strings_pbap.xml b/android/app/res/values-cs/strings_pbap.xml index f004613f97a..cb2ec1a1f96 100644 --- a/android/app/res/values-cs/strings_pbap.xml +++ b/android/app/res/values-cs/strings_pbap.xml @@ -13,4 +13,8 @@ "Mé jméno" "000000" "Sdílení kontaktu přes Bluetooth" + + + + diff --git a/android/app/res/values-da/strings_pbap.xml b/android/app/res/values-da/strings_pbap.xml index 8199d355bcc..32ef096cfa7 100644 --- a/android/app/res/values-da/strings_pbap.xml +++ b/android/app/res/values-da/strings_pbap.xml @@ -13,4 +13,8 @@ "Mit navn" "000000" "Deling af kontakter via Bluetooth" + + + + diff --git a/android/app/res/values-de/strings_pbap.xml b/android/app/res/values-de/strings_pbap.xml index 01e4b441ac1..c30e6a9886b 100644 --- a/android/app/res/values-de/strings_pbap.xml +++ b/android/app/res/values-de/strings_pbap.xml @@ -13,4 +13,8 @@ "Mein Name" "000000" "Kontakte über Bluetooth teilen" + + + + diff --git a/android/app/res/values-el/strings_pbap.xml b/android/app/res/values-el/strings_pbap.xml index a68c25b3b3b..4f67d317e94 100644 --- a/android/app/res/values-el/strings_pbap.xml +++ b/android/app/res/values-el/strings_pbap.xml @@ -13,4 +13,6 @@ "Το όνομα μου" "000000" "Κοινοποίηση επαφών μέσω Bluetooth" + "Η σύνθετη λειτουργία τηλεφωνικού καταλόγου υποστηρίζεται" + "Επιδιόρθωση για τη σύνθετη λειτουργία τηλεφωνικού καταλόγου" diff --git a/android/app/res/values-en-rAU/strings_pbap.xml b/android/app/res/values-en-rAU/strings_pbap.xml index c7b8dc853ba..f296a30d551 100644 --- a/android/app/res/values-en-rAU/strings_pbap.xml +++ b/android/app/res/values-en-rAU/strings_pbap.xml @@ -13,4 +13,6 @@ "My name" "000000" "Bluetooth Contact share" + "Phonebook advance feature supported" + "Re-pair for advance phonebook feature" diff --git a/android/app/res/values-en-rCA/strings_pbap.xml b/android/app/res/values-en-rCA/strings_pbap.xml index eb205ce2487..943172eca5c 100644 --- a/android/app/res/values-en-rCA/strings_pbap.xml +++ b/android/app/res/values-en-rCA/strings_pbap.xml @@ -13,4 +13,6 @@ "My name" "000000" "Bluetooth Contact share" + "Phonebook Advance Feature Supported" + "Re-pair for Advance Phonebook Feature" diff --git a/android/app/res/values-en-rGB/strings_pbap.xml b/android/app/res/values-en-rGB/strings_pbap.xml index c7b8dc853ba..f296a30d551 100644 --- a/android/app/res/values-en-rGB/strings_pbap.xml +++ b/android/app/res/values-en-rGB/strings_pbap.xml @@ -13,4 +13,6 @@ "My name" "000000" "Bluetooth Contact share" + "Phonebook advance feature supported" + "Re-pair for advance phonebook feature" diff --git a/android/app/res/values-en-rIN/strings_pbap.xml b/android/app/res/values-en-rIN/strings_pbap.xml index c7b8dc853ba..f296a30d551 100644 --- a/android/app/res/values-en-rIN/strings_pbap.xml +++ b/android/app/res/values-en-rIN/strings_pbap.xml @@ -13,4 +13,6 @@ "My name" "000000" "Bluetooth Contact share" + "Phonebook advance feature supported" + "Re-pair for advance phonebook feature" diff --git a/android/app/res/values-en-rXC/strings_pbap.xml b/android/app/res/values-en-rXC/strings_pbap.xml index 39160fdcc6b..ce608a5251f 100644 --- a/android/app/res/values-en-rXC/strings_pbap.xml +++ b/android/app/res/values-en-rXC/strings_pbap.xml @@ -13,4 +13,6 @@ "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‎‎‎‏‏‏‎‏‏‏‏‏‏‏‏‏‏‏‏‎‏‎‎‎‏‏‏‎‎‎‎‏‏‎‏‎‎‎‎‏‎‏‏‏‎‎‏‏‏‎‏‎‎‏‎‏‎‏‏‏‎‎‎‏‏‏‏‏‏‎‏‏‏‎‎‎‎My name‎‏‎‎‏‎" "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‎‎‎‏‏‏‎‏‏‏‏‏‏‏‎‎‏‎‏‎‎‎‏‏‏‎‏‎‏‏‎‎‏‏‏‏‏‏‏‏‏‏‎‎‎‎‏‎‎‎‏‏‎‏‎‎‏‎‎‏‎‏‏‎‏‎‏‎‎‎‏‎‏‏‏‎‎000000‎‏‎‎‏‎" "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‎‎‎‏‏‏‎‏‏‏‏‏‎‏‏‏‎‏‎‏‎‎‎‎‎‎‏‎‏‏‏‏‏‏‎‎‎‎‎‏‏‏‏‏‎‎‏‏‏‎‏‎‎‏‎‎‎‏‏‏‎‏‎‏‏‏‎‎‎‏‎‎‏‎‏‎Bluetooth Contact share‎‏‎‎‏‎" + "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‎‎‎‏‏‏‎‏‏‏‏‏‏‏‏‏‎‎‎‎‏‏‎‏‎‎‎‏‏‏‏‏‏‎‎‏‎‏‏‎‏‏‎‏‏‎‏‎‎‏‏‏‎‏‎‏‎‎‏‏‏‏‏‏‎‏‏‎‏‎‏‎‏‎‎‎‎Phonebook Advance Feature Supported‎‏‎‎‏‎" + "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‎‎‎‏‏‏‎‏‏‏‏‏‎‏‏‎‎‎‎‎‏‏‎‏‏‏‎‎‏‎‎‎‎‎‎‏‏‎‎‎‏‎‎‎‏‎‎‏‏‏‎‎‏‏‎‎‏‎‎‎‏‏‎‏‏‎‎‎‎‏‏‏‏‏‏‎Re-pair for Advance Phonebook Feature‎‏‎‎‏‎" diff --git a/android/app/res/values-es-rUS/strings_pbap.xml b/android/app/res/values-es-rUS/strings_pbap.xml index 674bcc0a529..53dcd006972 100644 --- a/android/app/res/values-es-rUS/strings_pbap.xml +++ b/android/app/res/values-es-rUS/strings_pbap.xml @@ -13,4 +13,8 @@ "Mi nombre" "000000" "Compartir contactos por Bluetooth" + + + + diff --git a/android/app/res/values-es/strings_pbap.xml b/android/app/res/values-es/strings_pbap.xml index bd40f7a8161..c8236009f7d 100644 --- a/android/app/res/values-es/strings_pbap.xml +++ b/android/app/res/values-es/strings_pbap.xml @@ -13,4 +13,8 @@ "Mi nombre" "000000" "Compartir contactos por Bluetooth" + + + + diff --git a/android/app/res/values-et/strings_pbap.xml b/android/app/res/values-et/strings_pbap.xml index a25075fd98c..18173cfefd6 100644 --- a/android/app/res/values-et/strings_pbap.xml +++ b/android/app/res/values-et/strings_pbap.xml @@ -13,4 +13,8 @@ "Minu nimi" "000000" "Bluetoothi kontakti jagamine" + + + + diff --git a/android/app/res/values-eu/strings_pbap.xml b/android/app/res/values-eu/strings_pbap.xml index db17ca9fa49..e07ffb98bf2 100644 --- a/android/app/res/values-eu/strings_pbap.xml +++ b/android/app/res/values-eu/strings_pbap.xml @@ -13,4 +13,8 @@ "Nire izena" "000000" "Kontaktuak Bluetooth bidez partekatzeko aukera" + + + + diff --git a/android/app/res/values-fa/strings_pbap.xml b/android/app/res/values-fa/strings_pbap.xml index 539a39d1163..95b4eb8da92 100644 --- a/android/app/res/values-fa/strings_pbap.xml +++ b/android/app/res/values-fa/strings_pbap.xml @@ -13,4 +13,8 @@ "نام من" "000000" "اشتراک‌گذاری مخاطبین ازطریق بلوتوث" + + + + diff --git a/android/app/res/values-fi/strings_pbap.xml b/android/app/res/values-fi/strings_pbap.xml index 9174326acca..03b8dccd274 100644 --- a/android/app/res/values-fi/strings_pbap.xml +++ b/android/app/res/values-fi/strings_pbap.xml @@ -13,4 +13,8 @@ "Oma nimeni" "000000" "Bluetooth-yhteyden jako" + + + + diff --git a/android/app/res/values-fr-rCA/strings_pbap.xml b/android/app/res/values-fr-rCA/strings_pbap.xml index 96556e880ff..b35cc6e9e35 100644 --- a/android/app/res/values-fr-rCA/strings_pbap.xml +++ b/android/app/res/values-fr-rCA/strings_pbap.xml @@ -13,4 +13,8 @@ "Mon nom" "000000" "Partage de contacts par Bluetooth" + + + + diff --git a/android/app/res/values-fr/strings_pbap.xml b/android/app/res/values-fr/strings_pbap.xml index 75521885924..bd8367fa6f9 100644 --- a/android/app/res/values-fr/strings_pbap.xml +++ b/android/app/res/values-fr/strings_pbap.xml @@ -13,4 +13,8 @@ "Mon nom" "000000" "Partage de contact Bluetooth" + + + + diff --git a/android/app/res/values-gl/strings_pbap.xml b/android/app/res/values-gl/strings_pbap.xml index 07446a28d47..abca13d9207 100644 --- a/android/app/res/values-gl/strings_pbap.xml +++ b/android/app/res/values-gl/strings_pbap.xml @@ -13,4 +13,8 @@ "O meu nome" "000000" "Compartir contactos por Bluetooth" + + + + diff --git a/android/app/res/values-gu/strings_pbap.xml b/android/app/res/values-gu/strings_pbap.xml index 594db2b8ae7..af95c9e897a 100644 --- a/android/app/res/values-gu/strings_pbap.xml +++ b/android/app/res/values-gu/strings_pbap.xml @@ -13,4 +13,8 @@ "મારું નામ" "000000" "બ્લૂટૂથ સંપર્ક શેર કરો" + + + + diff --git a/android/app/res/values-hi/strings_pbap.xml b/android/app/res/values-hi/strings_pbap.xml index ded519c4ba7..cb594770f0c 100644 --- a/android/app/res/values-hi/strings_pbap.xml +++ b/android/app/res/values-hi/strings_pbap.xml @@ -13,4 +13,8 @@ "मेरा नाम" "000000" "ब्लूटूथ संपर्क शेयर करें" + + + + diff --git a/android/app/res/values-hr/strings_pbap.xml b/android/app/res/values-hr/strings_pbap.xml index 77f668ca8e5..1adca2dcd57 100644 --- a/android/app/res/values-hr/strings_pbap.xml +++ b/android/app/res/values-hr/strings_pbap.xml @@ -13,4 +13,6 @@ "Moje ime" "000000" "Dijeljenje kontakata Bluetoothom" + "Podržana je napredna značajka telefonskog imenika" + "Popravak napredne značajke telefonskog imenika" diff --git a/android/app/res/values-hu/strings_pbap.xml b/android/app/res/values-hu/strings_pbap.xml index 6d0f727c785..620b0921ff9 100644 --- a/android/app/res/values-hu/strings_pbap.xml +++ b/android/app/res/values-hu/strings_pbap.xml @@ -13,4 +13,8 @@ "Telefon neve" "000000" "Bluetooth-névjegymegosztás" + + + + diff --git a/android/app/res/values-hy/strings_pbap.xml b/android/app/res/values-hy/strings_pbap.xml index 26b005da9d2..de86e212824 100644 --- a/android/app/res/values-hy/strings_pbap.xml +++ b/android/app/res/values-hy/strings_pbap.xml @@ -13,4 +13,6 @@ "Իմ անունը" "000000" "Bluetooth կոնտակտների համօգտագործում" + "Աջակցվում են հեռախոսագրքի ընդլայնված գործառույթը" + "Վերազուգակցում հեռախոսագրքի ընդլայնված գործառույթի համար" diff --git a/android/app/res/values-in/strings_pbap.xml b/android/app/res/values-in/strings_pbap.xml index 0ce6bd6faab..3a9fd944e2a 100644 --- a/android/app/res/values-in/strings_pbap.xml +++ b/android/app/res/values-in/strings_pbap.xml @@ -13,4 +13,8 @@ "Nama saya" "000000" "Berbagi Kontak Bluetooth" + + + + diff --git a/android/app/res/values-is/strings_pbap.xml b/android/app/res/values-is/strings_pbap.xml index 53d6029cad0..f0d69830f72 100644 --- a/android/app/res/values-is/strings_pbap.xml +++ b/android/app/res/values-is/strings_pbap.xml @@ -13,4 +13,8 @@ "Nafnið mitt" "000000" "Tengiliðum deilt með Bluetooth" + + + + diff --git a/android/app/res/values-it/strings_pbap.xml b/android/app/res/values-it/strings_pbap.xml index 33a6d71074b..c4324101463 100644 --- a/android/app/res/values-it/strings_pbap.xml +++ b/android/app/res/values-it/strings_pbap.xml @@ -13,4 +13,6 @@ "Il mio nome" "000000" "Condivisione dei contatti tramite Bluetooth" + "Funzionalità avanzata della rubrica supportata" + "Nuovo accoppiamento per funzionalità avanzata della rubrica" diff --git a/android/app/res/values-iw/strings_pbap.xml b/android/app/res/values-iw/strings_pbap.xml index 6a7b006213e..d749c298649 100644 --- a/android/app/res/values-iw/strings_pbap.xml +++ b/android/app/res/values-iw/strings_pbap.xml @@ -13,4 +13,8 @@ "השם שלי" "000000" "‏שיתוף אנשי קשר באמצעות Bluetooth" + + + + diff --git a/android/app/res/values-ja/strings_pbap.xml b/android/app/res/values-ja/strings_pbap.xml index 673efabb2a6..632cdac71bb 100644 --- a/android/app/res/values-ja/strings_pbap.xml +++ b/android/app/res/values-ja/strings_pbap.xml @@ -13,4 +13,8 @@ "名前" "000000" "Bluetooth での連絡先の共有" + + + + diff --git a/android/app/res/values-ka/strings_pbap.xml b/android/app/res/values-ka/strings_pbap.xml index f54c28f446c..21a53de92a0 100644 --- a/android/app/res/values-ka/strings_pbap.xml +++ b/android/app/res/values-ka/strings_pbap.xml @@ -13,4 +13,8 @@ "ჩემი სახელი" "000000" "Bluetooth კონტაქტის გაზიარება" + + + + diff --git a/android/app/res/values-kk/strings_pbap.xml b/android/app/res/values-kk/strings_pbap.xml index cbc15e9e41f..107e51de769 100644 --- a/android/app/res/values-kk/strings_pbap.xml +++ b/android/app/res/values-kk/strings_pbap.xml @@ -13,4 +13,8 @@ "Mені атым" "000000" "Bluetooth арқылы контактіні бөлісу" + + + + diff --git a/android/app/res/values-km/strings_pbap.xml b/android/app/res/values-km/strings_pbap.xml index 37e1aac2b49..068fa26dd77 100644 --- a/android/app/res/values-km/strings_pbap.xml +++ b/android/app/res/values-km/strings_pbap.xml @@ -13,4 +13,8 @@ "ឈ្មោះ​របស់​ខ្ញុំ" "000000" "ការចែករំលែក​ទំនាក់ទំនង​ប៊្លូធូស" + + + + diff --git a/android/app/res/values-kn/strings_pbap.xml b/android/app/res/values-kn/strings_pbap.xml index 5f75060c9cf..c7f550eca23 100644 --- a/android/app/res/values-kn/strings_pbap.xml +++ b/android/app/res/values-kn/strings_pbap.xml @@ -13,4 +13,8 @@ "ನನ್ನ ಹೆಸರು" "000000" "ಬ್ಲೂಟೂತ್ ಸಂಪರ್ಕ ಹಂಚಿಕೆ" + + + + diff --git a/android/app/res/values-ko/strings_pbap.xml b/android/app/res/values-ko/strings_pbap.xml index 9e2a557f4c8..acd4a91b19d 100644 --- a/android/app/res/values-ko/strings_pbap.xml +++ b/android/app/res/values-ko/strings_pbap.xml @@ -13,4 +13,8 @@ "내 이름" "000000" "블루투스 연락처 공유" + + + + diff --git a/android/app/res/values-ky/strings_pbap.xml b/android/app/res/values-ky/strings_pbap.xml index ae35e4e3d49..ac8af0cb4fc 100644 --- a/android/app/res/values-ky/strings_pbap.xml +++ b/android/app/res/values-ky/strings_pbap.xml @@ -13,4 +13,8 @@ "Менин атым" "000000" "Байланыштарды Bluetooth аркылуу бөлүшүү" + + + + diff --git a/android/app/res/values-lo/strings_pbap.xml b/android/app/res/values-lo/strings_pbap.xml index 7bd4b12788b..fe460896144 100644 --- a/android/app/res/values-lo/strings_pbap.xml +++ b/android/app/res/values-lo/strings_pbap.xml @@ -13,4 +13,8 @@ "ຊື່ຂອງຂ້ອຍ" "000000" "ການແບ່ງປັນລາຍຊື່ຜູ້ຕິດຕໍ່ຜ່ານ Bluetooth" + + + + diff --git a/android/app/res/values-lt/strings_pbap.xml b/android/app/res/values-lt/strings_pbap.xml index 39d3fe688ca..23283bac71c 100644 --- a/android/app/res/values-lt/strings_pbap.xml +++ b/android/app/res/values-lt/strings_pbap.xml @@ -13,4 +13,8 @@ "Mano vardas" "000000" "„Bluetooth“ kontaktų bendrinimas" + + + + diff --git a/android/app/res/values-lv/strings_pbap.xml b/android/app/res/values-lv/strings_pbap.xml index d34161d0d84..4e6c47a36d2 100644 --- a/android/app/res/values-lv/strings_pbap.xml +++ b/android/app/res/values-lv/strings_pbap.xml @@ -13,4 +13,8 @@ "Mans vārds" "000000" "Kontaktpersonu kopīgošana, izmantojot Bluetooth" + + + + diff --git a/android/app/res/values-mk/strings_pbap.xml b/android/app/res/values-mk/strings_pbap.xml index 888f4bab0f9..fe221c67a34 100644 --- a/android/app/res/values-mk/strings_pbap.xml +++ b/android/app/res/values-mk/strings_pbap.xml @@ -13,4 +13,8 @@ "Моето име" "000000" "Споделување контакти преку Bluetooth" + + + + diff --git a/android/app/res/values-ml/strings_pbap.xml b/android/app/res/values-ml/strings_pbap.xml index 47fa21305be..06cc65058a1 100644 --- a/android/app/res/values-ml/strings_pbap.xml +++ b/android/app/res/values-ml/strings_pbap.xml @@ -13,4 +13,6 @@ "എന്റെ പേര്" "000000" "Bluetooth കോണ്‍‌ടാക്റ്റ് പങ്കിടൽ" + "ഫോൺബുക്കിന്റെ വിപുലമായ ഫീച്ചറുകൾ പിന്തുണയ്ക്കുന്നു" + "ഫോൺബുക്കിന്റെ വിപുലമായ ഫീച്ചറിനായി വീണ്ടും ജോടിയാക്കുക" diff --git a/android/app/res/values-mn/strings_pbap.xml b/android/app/res/values-mn/strings_pbap.xml index d0a45423f84..3064425ed76 100644 --- a/android/app/res/values-mn/strings_pbap.xml +++ b/android/app/res/values-mn/strings_pbap.xml @@ -13,4 +13,8 @@ "Миний нэр" "000000" "Bluetooth харилцагч хуваалцах" + + + + diff --git a/android/app/res/values-mr/strings_pbap.xml b/android/app/res/values-mr/strings_pbap.xml index c711268d2e4..beb1f7936e8 100644 --- a/android/app/res/values-mr/strings_pbap.xml +++ b/android/app/res/values-mr/strings_pbap.xml @@ -13,4 +13,8 @@ "माझे नाव" "000000" "ब्लूटूथ संपर्क शेअर" + + + + diff --git a/android/app/res/values-ms/strings_pbap.xml b/android/app/res/values-ms/strings_pbap.xml index 46c7a091116..bb1bc6ec6b3 100644 --- a/android/app/res/values-ms/strings_pbap.xml +++ b/android/app/res/values-ms/strings_pbap.xml @@ -13,4 +13,8 @@ "Nama saya" "000000" "Perkongsian Kenalan melalui Bluetooth" + + + + diff --git a/android/app/res/values-my/strings_pbap.xml b/android/app/res/values-my/strings_pbap.xml index 6d8d3f7409f..81ea012760f 100644 --- a/android/app/res/values-my/strings_pbap.xml +++ b/android/app/res/values-my/strings_pbap.xml @@ -13,4 +13,8 @@ "ကျွန်ုပ်နာမည်" "၀၀၀၀၀၀" "ဘလူးတုသ်ဖြင့် အဆက်အသွယ်မျှဝေခြင်း" + + + + diff --git a/android/app/res/values-nb/strings_pbap.xml b/android/app/res/values-nb/strings_pbap.xml index 863aad9ebbe..d719b0c0fe8 100644 --- a/android/app/res/values-nb/strings_pbap.xml +++ b/android/app/res/values-nb/strings_pbap.xml @@ -13,4 +13,8 @@ "Navnet mitt" "000000" "Bluetooth Contact-deling" + + + + diff --git a/android/app/res/values-ne/strings_pbap.xml b/android/app/res/values-ne/strings_pbap.xml index 6c544648b5f..17412360f32 100644 --- a/android/app/res/values-ne/strings_pbap.xml +++ b/android/app/res/values-ne/strings_pbap.xml @@ -13,4 +13,8 @@ "मेरो नाम" "००००००" "ब्लुटुथमार्फत सम्पर्कको आदान प्रदान" + + + + diff --git a/android/app/res/values-nl/strings_pbap.xml b/android/app/res/values-nl/strings_pbap.xml index 393a675c169..dc61f0198b9 100644 --- a/android/app/res/values-nl/strings_pbap.xml +++ b/android/app/res/values-nl/strings_pbap.xml @@ -13,4 +13,8 @@ "Mijn naam" "000000" "Contacten delen via bluetooth" + + + + diff --git a/android/app/res/values-or/strings_pbap.xml b/android/app/res/values-or/strings_pbap.xml index 914f58745d9..3263f359111 100644 --- a/android/app/res/values-or/strings_pbap.xml +++ b/android/app/res/values-or/strings_pbap.xml @@ -13,4 +13,8 @@ "ମୋର ନାମ" "000000" "ବ୍ଲୁଟୂଥ କଣ୍ଟାକ୍ଟ ସେୟାର କରନ୍ତୁ" + + + + diff --git a/android/app/res/values-pa/strings_pbap.xml b/android/app/res/values-pa/strings_pbap.xml index 3b4280a631d..0f5a00734c1 100644 --- a/android/app/res/values-pa/strings_pbap.xml +++ b/android/app/res/values-pa/strings_pbap.xml @@ -13,4 +13,8 @@ "ਮੇਰਾ ਨਾਮ" "000000" "ਬਲੂਟੁੱਥ ਸੰਪਰਕ ਸਾਂਝਾਕਰਨ" + + + + diff --git a/android/app/res/values-pl/strings_pbap.xml b/android/app/res/values-pl/strings_pbap.xml index f6bdde786a8..f24be42c19c 100644 --- a/android/app/res/values-pl/strings_pbap.xml +++ b/android/app/res/values-pl/strings_pbap.xml @@ -13,4 +13,8 @@ "Moja nazwa" "000000" "Udostępnianie kontaktu przez Bluetooth" + + + + diff --git a/android/app/res/values-pt-rPT/strings_pbap.xml b/android/app/res/values-pt-rPT/strings_pbap.xml index e61726684f7..1509de227e2 100644 --- a/android/app/res/values-pt-rPT/strings_pbap.xml +++ b/android/app/res/values-pt-rPT/strings_pbap.xml @@ -13,6 +13,8 @@ "O meu nome" "000000" "Partilha de contactos por Bluetooth" - Recurso Avançado da Lista Telefônica Suportado - Re-par para Recurso Avançado Agenda + + + + diff --git a/android/app/res/values-pt/strings_pbap.xml b/android/app/res/values-pt/strings_pbap.xml index b0c906715ee..fda933e5019 100644 --- a/android/app/res/values-pt/strings_pbap.xml +++ b/android/app/res/values-pt/strings_pbap.xml @@ -13,6 +13,8 @@ "Meu nome" "000000" "Compartilhamento de contato via Bluetooth" - Recurso Avançado da Lista Telefônica Suportado - Re-par para Recurso Avançado Agenda + + + + diff --git a/android/app/res/values-ro/strings_pbap.xml b/android/app/res/values-ro/strings_pbap.xml index 2aa6358ad1d..c02e4219825 100644 --- a/android/app/res/values-ro/strings_pbap.xml +++ b/android/app/res/values-ro/strings_pbap.xml @@ -13,4 +13,8 @@ "Numele meu" "000000" "Distribuirea persoanei de contact prin Bluetooth" + + + + diff --git a/android/app/res/values-ru/strings_pbap.xml b/android/app/res/values-ru/strings_pbap.xml index a8b1b727677..46ad6c5652c 100644 --- a/android/app/res/values-ru/strings_pbap.xml +++ b/android/app/res/values-ru/strings_pbap.xml @@ -13,4 +13,6 @@ "Мое название" "000000" "Передача контактов по Bluetooth" + "Поддерживается продвинутая функция телефонной книги" + "Восстановление продвинутой функции телефонной книги" diff --git a/android/app/res/values-si/strings_pbap.xml b/android/app/res/values-si/strings_pbap.xml index f6e6d010b57..25c6a36b7f3 100644 --- a/android/app/res/values-si/strings_pbap.xml +++ b/android/app/res/values-si/strings_pbap.xml @@ -13,4 +13,8 @@ "මගේ නම" "000000" "බ්ලූටූත් සම්බන්ධතා බෙදා ගැනීම" + + + + diff --git a/android/app/res/values-sk/strings_pbap.xml b/android/app/res/values-sk/strings_pbap.xml index 829e720af91..f3f478a3067 100644 --- a/android/app/res/values-sk/strings_pbap.xml +++ b/android/app/res/values-sk/strings_pbap.xml @@ -13,4 +13,8 @@ "Moje meno" "000000" "Zdieľanie kontaktov cez Bluetooth" + + + + diff --git a/android/app/res/values-sl/strings_pbap.xml b/android/app/res/values-sl/strings_pbap.xml index 9ac34346923..e56ac85f333 100644 --- a/android/app/res/values-sl/strings_pbap.xml +++ b/android/app/res/values-sl/strings_pbap.xml @@ -13,4 +13,8 @@ "Moje ime" "000000" "Deljenje stikov z drugimi prek Bluetootha" + + + + diff --git a/android/app/res/values-sq/strings_pbap.xml b/android/app/res/values-sq/strings_pbap.xml index 0c0da34c596..10ae5ec7910 100644 --- a/android/app/res/values-sq/strings_pbap.xml +++ b/android/app/res/values-sq/strings_pbap.xml @@ -13,4 +13,8 @@ "Emri im" "000000" "Ndarja e kontakteve me Bluetooth" + + + + diff --git a/android/app/res/values-sr/strings_pbap.xml b/android/app/res/values-sr/strings_pbap.xml index 1fd8464d6c9..5a28f8c8bdd 100644 --- a/android/app/res/values-sr/strings_pbap.xml +++ b/android/app/res/values-sr/strings_pbap.xml @@ -13,4 +13,6 @@ "Моје име" "000000" "Дељење контаката преко Bluetooth-а" + "Подржана је напредна функција телефонског именика" + "Поновно упаривање за напредну функцију телефонског именика" diff --git a/android/app/res/values-sv/strings_pbap.xml b/android/app/res/values-sv/strings_pbap.xml index e5908af9958..6e770f0bbb2 100644 --- a/android/app/res/values-sv/strings_pbap.xml +++ b/android/app/res/values-sv/strings_pbap.xml @@ -13,4 +13,8 @@ "Mitt namn" "000000" "Kontaktdelning via Bluetooth" + + + + diff --git a/android/app/res/values-sw/strings_pbap.xml b/android/app/res/values-sw/strings_pbap.xml index 0c38faf14b2..60b47fd0238 100644 --- a/android/app/res/values-sw/strings_pbap.xml +++ b/android/app/res/values-sw/strings_pbap.xml @@ -13,4 +13,8 @@ "Jina langu" "000000" "Kushiriki Anwani kupitia Bluetooth" + + + + diff --git a/android/app/res/values-ta/strings_pbap.xml b/android/app/res/values-ta/strings_pbap.xml index 99e5477a393..b0039078766 100644 --- a/android/app/res/values-ta/strings_pbap.xml +++ b/android/app/res/values-ta/strings_pbap.xml @@ -13,4 +13,8 @@ "எனது பெயர்" "000000" "புளூடூத் தொடர்புப் பகிர்தல்" + + + + diff --git a/android/app/res/values-te/strings_pbap.xml b/android/app/res/values-te/strings_pbap.xml index fa300302bcf..c70f8c954b9 100644 --- a/android/app/res/values-te/strings_pbap.xml +++ b/android/app/res/values-te/strings_pbap.xml @@ -13,4 +13,8 @@ "నా పేరు" "000000" "బ్లూటూత్ కాంటాక్ట్ షేర్" + + + + diff --git a/android/app/res/values-th/strings_pbap.xml b/android/app/res/values-th/strings_pbap.xml index 06805da436d..6692631cf2e 100644 --- a/android/app/res/values-th/strings_pbap.xml +++ b/android/app/res/values-th/strings_pbap.xml @@ -13,4 +13,6 @@ "ชื่อของฉัน" "000000" "การแชร์รายชื่อติดต่อทางบลูทูธ" + "รองรับฟีเจอร์สมุดโทรศัพท์ขั้นสูง" + "จับคู่อีกครั้งเพื่อใช้ฟีเจอร์สมุดโทรศัพท์ขั้นสูง" diff --git a/android/app/res/values-tl/strings_pbap.xml b/android/app/res/values-tl/strings_pbap.xml index 7854825bd01..7985c1e500a 100644 --- a/android/app/res/values-tl/strings_pbap.xml +++ b/android/app/res/values-tl/strings_pbap.xml @@ -13,4 +13,8 @@ "Aking pangalan" "000000" "Pagbabahagi ng Contact sa Bluetooth" + + + + diff --git a/android/app/res/values-tr/strings_pbap.xml b/android/app/res/values-tr/strings_pbap.xml index e7ed7b85a45..d405b49dfe6 100644 --- a/android/app/res/values-tr/strings_pbap.xml +++ b/android/app/res/values-tr/strings_pbap.xml @@ -13,4 +13,8 @@ "Adım" "000000" "Bluetooth Kişi paylaşımı" + + + + diff --git a/android/app/res/values-uk/strings_pbap.xml b/android/app/res/values-uk/strings_pbap.xml index f7922afe6ad..8ce619cd559 100644 --- a/android/app/res/values-uk/strings_pbap.xml +++ b/android/app/res/values-uk/strings_pbap.xml @@ -13,4 +13,8 @@ "Моє ім\'я" "000000" "Надсилання контактів Bluetooth" + + + + diff --git a/android/app/res/values-ur/strings_pbap.xml b/android/app/res/values-ur/strings_pbap.xml index 29818443a96..5467532d0c9 100644 --- a/android/app/res/values-ur/strings_pbap.xml +++ b/android/app/res/values-ur/strings_pbap.xml @@ -13,4 +13,8 @@ "میرا نام" "000000" "بلوٹوتھ رابطہ اشتراک" + + + + diff --git a/android/app/res/values-uz/strings_pbap.xml b/android/app/res/values-uz/strings_pbap.xml index 0800a6e1a36..37304692bdb 100644 --- a/android/app/res/values-uz/strings_pbap.xml +++ b/android/app/res/values-uz/strings_pbap.xml @@ -13,4 +13,6 @@ "Ismim" "000000" "Kontaktlarni Bluetooth orqali yuborish" + "Telefon kitobchasi kengaytirilgan funksiyalari ishlaydi" + "Telefon kitobchasi kengaytirilgan funksiyalarini tuzatish" diff --git a/android/app/res/values-vi/strings_pbap.xml b/android/app/res/values-vi/strings_pbap.xml index fb57f04384c..6e680ed7248 100644 --- a/android/app/res/values-vi/strings_pbap.xml +++ b/android/app/res/values-vi/strings_pbap.xml @@ -13,4 +13,8 @@ "Tên của tôi" "000000" "Chia sẻ liên hệ qua Bluetooth" + + + + diff --git a/android/app/res/values-zh-rCN/strings_pbap.xml b/android/app/res/values-zh-rCN/strings_pbap.xml index 67a14d2a11c..d7b338bca98 100644 --- a/android/app/res/values-zh-rCN/strings_pbap.xml +++ b/android/app/res/values-zh-rCN/strings_pbap.xml @@ -13,4 +13,8 @@ "我的名字" "000000" "通过蓝牙分享联系人" + + + + diff --git a/android/app/res/values-zh-rHK/strings_pbap.xml b/android/app/res/values-zh-rHK/strings_pbap.xml index c1b6af5fdd5..4592b368047 100644 --- a/android/app/res/values-zh-rHK/strings_pbap.xml +++ b/android/app/res/values-zh-rHK/strings_pbap.xml @@ -13,4 +13,8 @@ "我的姓名" "000000" "藍牙聯絡人分享" + + + + diff --git a/android/app/res/values-zh-rTW/strings_pbap.xml b/android/app/res/values-zh-rTW/strings_pbap.xml index d11dff893cb..3e4be4f6937 100644 --- a/android/app/res/values-zh-rTW/strings_pbap.xml +++ b/android/app/res/values-zh-rTW/strings_pbap.xml @@ -13,4 +13,8 @@ "我的名稱" "000000" "藍牙聯絡人分享" + + + + diff --git a/android/app/res/values-zu/strings_pbap.xml b/android/app/res/values-zu/strings_pbap.xml index fb554a2fb0c..719c43d89d4 100644 --- a/android/app/res/values-zu/strings_pbap.xml +++ b/android/app/res/values-zu/strings_pbap.xml @@ -13,4 +13,8 @@ "Igama lami" "000000" "Ukwabelana koxhumana nabo kwe-Bluetooth" + + + + -- GitLab From c6574d5df5f49e74ec20826a476b6f95c4b5b2ea Mon Sep 17 00:00:00 2001 From: Bill Yi Date: Mon, 27 Feb 2023 05:17:53 -0800 Subject: [PATCH 0007/2405] Import translations. DO NOT MERGE ANYWHERE Auto-generated-cl: translation import Change-Id: I298d0bee58f3d23512e4cd02d6eca45ade48cf54 --- android/app/res/values-af/strings_pbap.xml | 6 ++---- android/app/res/values-ar/strings_pbap.xml | 6 ++---- android/app/res/values-as/strings_pbap.xml | 6 ++---- android/app/res/values-az/strings_pbap.xml | 6 ++---- android/app/res/values-be/strings_pbap.xml | 6 ++---- android/app/res/values-bg/strings_pbap.xml | 6 ++---- android/app/res/values-bn/strings_pbap.xml | 6 ++---- android/app/res/values-bs/strings_pbap.xml | 4 ++-- android/app/res/values-ca/strings_pbap.xml | 6 ++---- android/app/res/values-cs/strings_pbap.xml | 6 ++---- android/app/res/values-da/strings_pbap.xml | 6 ++---- android/app/res/values-de/strings_pbap.xml | 6 ++---- android/app/res/values-es-rUS/strings_pbap.xml | 6 ++---- android/app/res/values-es/strings_pbap.xml | 6 ++---- android/app/res/values-et/strings_pbap.xml | 6 ++---- android/app/res/values-fa/strings_pbap.xml | 6 ++---- android/app/res/values-fi/strings_pbap.xml | 6 ++---- android/app/res/values-fr/strings_pbap.xml | 6 ++---- android/app/res/values-gl/strings_pbap.xml | 6 ++---- android/app/res/values-gu/strings_pbap.xml | 6 ++---- android/app/res/values-hi/strings_pbap.xml | 6 ++---- android/app/res/values-hu/strings_pbap.xml | 6 ++---- android/app/res/values-in/strings_pbap.xml | 6 ++---- android/app/res/values-is/strings_pbap.xml | 6 ++---- android/app/res/values-iw/strings_pbap.xml | 6 ++---- android/app/res/values-ja/strings_pbap.xml | 6 ++---- android/app/res/values-ka/strings_pbap.xml | 6 ++---- android/app/res/values-kk/strings_pbap.xml | 6 ++---- android/app/res/values-km/strings_pbap.xml | 6 ++---- android/app/res/values-kn/strings_pbap.xml | 6 ++---- android/app/res/values-ko/strings_pbap.xml | 6 ++---- android/app/res/values-ky/strings_pbap.xml | 6 ++---- android/app/res/values-lo/strings_pbap.xml | 6 ++---- android/app/res/values-lt/strings_pbap.xml | 6 ++---- android/app/res/values-lv/strings_pbap.xml | 6 ++---- android/app/res/values-mk/strings_pbap.xml | 6 ++---- android/app/res/values-mn/strings_pbap.xml | 6 ++---- android/app/res/values-mr/strings_pbap.xml | 6 ++---- android/app/res/values-ms/strings_pbap.xml | 6 ++---- android/app/res/values-my/strings_pbap.xml | 6 ++---- android/app/res/values-nb/strings_pbap.xml | 6 ++---- android/app/res/values-ne/strings_pbap.xml | 6 ++---- android/app/res/values-nl/strings_pbap.xml | 6 ++---- android/app/res/values-or/strings_pbap.xml | 6 ++---- android/app/res/values-pa/strings_pbap.xml | 6 ++---- android/app/res/values-pl/strings_pbap.xml | 6 ++---- android/app/res/values-pt-rPT/strings_pbap.xml | 6 ++---- android/app/res/values-pt/strings_pbap.xml | 6 ++---- android/app/res/values-ro/strings_pbap.xml | 6 ++---- android/app/res/values-si/strings_pbap.xml | 6 ++---- android/app/res/values-sk/strings_pbap.xml | 6 ++---- android/app/res/values-sl/strings_pbap.xml | 6 ++---- android/app/res/values-sq/strings_pbap.xml | 6 ++---- android/app/res/values-sv/strings_pbap.xml | 6 ++---- android/app/res/values-sw/strings_pbap.xml | 6 ++---- android/app/res/values-te/strings_pbap.xml | 6 ++---- android/app/res/values-tl/strings_pbap.xml | 6 ++---- android/app/res/values-tr/strings_pbap.xml | 6 ++---- android/app/res/values-uk/strings_pbap.xml | 6 ++---- android/app/res/values-ur/strings_pbap.xml | 6 ++---- android/app/res/values-vi/strings_pbap.xml | 6 ++---- android/app/res/values-zh-rCN/strings_pbap.xml | 6 ++---- android/app/res/values-zh-rHK/strings_pbap.xml | 6 ++---- android/app/res/values-zh-rTW/strings_pbap.xml | 6 ++---- android/app/res/values-zu/strings_pbap.xml | 6 ++---- 65 files changed, 130 insertions(+), 258 deletions(-) diff --git a/android/app/res/values-af/strings_pbap.xml b/android/app/res/values-af/strings_pbap.xml index ac5e6e52b28..0fa903b172d 100644 --- a/android/app/res/values-af/strings_pbap.xml +++ b/android/app/res/values-af/strings_pbap.xml @@ -13,8 +13,6 @@ "My naam" "000000" "Bluetooth-kontakdeling" - - - - + "Foonboek se gevorderde kenmerk word gesteun" + "Bind weer saam met Foonboek se gevorderde kenmerk" diff --git a/android/app/res/values-ar/strings_pbap.xml b/android/app/res/values-ar/strings_pbap.xml index 4903d956f8a..198c8c087c5 100644 --- a/android/app/res/values-ar/strings_pbap.xml +++ b/android/app/res/values-ar/strings_pbap.xml @@ -13,8 +13,6 @@ "اسمي" "000000" "مشاركة جهات الاتصال عبر البلوتوث" - - - - + "إتاحة الميزات المتقدّمة لدليل الهاتف" + "إصلاح الميزات المتقدّمة لدليل الهاتف" diff --git a/android/app/res/values-as/strings_pbap.xml b/android/app/res/values-as/strings_pbap.xml index 01061c4c4ef..70014fbe4e0 100644 --- a/android/app/res/values-as/strings_pbap.xml +++ b/android/app/res/values-as/strings_pbap.xml @@ -13,8 +13,6 @@ "মোৰ নাম" "০০০০০০" "ব্লুটুথ সম্পৰ্ক শ্বেয়াৰ" - - - - + "ফ’নবুকৰ উচ্চখাপৰ সুবিধা সমৰ্থন কৰা হয়" + "ফ’নবুকৰ উচ্চখাপৰ সুবিধাৰ বাবে পুনৰ পেয়াৰ কৰক" diff --git a/android/app/res/values-az/strings_pbap.xml b/android/app/res/values-az/strings_pbap.xml index bf4abacf810..5a88b01a8f6 100644 --- a/android/app/res/values-az/strings_pbap.xml +++ b/android/app/res/values-az/strings_pbap.xml @@ -13,8 +13,6 @@ "Mənim adım" "000000" "Bluetooth Kontakt paylaşımı" - - - - + "Telefon Kitabçasının Təkmil Funksiyası Dəstəklənir" + "Təkmil Telefon Kitabçası Funksiyası üçün yenidən əlaqələndirin" diff --git a/android/app/res/values-be/strings_pbap.xml b/android/app/res/values-be/strings_pbap.xml index 87a3f45c395..569f6e824ee 100644 --- a/android/app/res/values-be/strings_pbap.xml +++ b/android/app/res/values-be/strings_pbap.xml @@ -13,8 +13,6 @@ "Маё імя" "000000" "Абагульванне кантактаў праз Bluetooth" - - - - + "Падтрымліваюцца пашыраныя функцыі тэлефоннай кнігі" + "Для выкарыстання пашыраных функцый тэлефоннай кнігі выканайце спалучэнне яшчэ раз" diff --git a/android/app/res/values-bg/strings_pbap.xml b/android/app/res/values-bg/strings_pbap.xml index 04a6befe089..cfc0d5463e1 100644 --- a/android/app/res/values-bg/strings_pbap.xml +++ b/android/app/res/values-bg/strings_pbap.xml @@ -13,8 +13,6 @@ "Моето име" "000000" "Споделяне на контакта през Bluetooth" - - - - + "Поддържа се разширената функция за телефонен указател" + "Извършете повторно сдвояване за разширената функция за телефонен указател" diff --git a/android/app/res/values-bn/strings_pbap.xml b/android/app/res/values-bn/strings_pbap.xml index f1ca862b333..d1869ed1d37 100644 --- a/android/app/res/values-bn/strings_pbap.xml +++ b/android/app/res/values-bn/strings_pbap.xml @@ -13,8 +13,6 @@ "আমার নাম" "০০০০০০" "ব্লুটুথ পরিচিতির সাথে শেয়ার করা" - - - - + "ফোনবুক উন্নত ফিচার কাজ করবে" + "উন্নত ফোনবুক ফিচারের জন্য আবার পেয়ার করুন" diff --git a/android/app/res/values-bs/strings_pbap.xml b/android/app/res/values-bs/strings_pbap.xml index 74b17568424..4672149f3ae 100644 --- a/android/app/res/values-bs/strings_pbap.xml +++ b/android/app/res/values-bs/strings_pbap.xml @@ -13,6 +13,6 @@ "Moje ime" "000000" "Dijeljenje kontakata putem Bluetootha" - "Podržana je napredna značajka telefonskog imenika" - "Popravak napredne značajke telefonskog imenika" + "Podržane su napredne funkcije za telefonski imenik" + "Ponovno uparivanje za naprednu funkciju telefonskog imenika" diff --git a/android/app/res/values-ca/strings_pbap.xml b/android/app/res/values-ca/strings_pbap.xml index c9280888e07..add1ee228d6 100644 --- a/android/app/res/values-ca/strings_pbap.xml +++ b/android/app/res/values-ca/strings_pbap.xml @@ -13,8 +13,6 @@ "El meu nom" "000000" "Compartir contactes amb Bluetooth" - - - - + "Funció avançada de l\'agenda telefònica admesa" + "Torna a vincular la funció avançada de l\'agenda telefònica" diff --git a/android/app/res/values-cs/strings_pbap.xml b/android/app/res/values-cs/strings_pbap.xml index cb2ec1a1f96..d296e577289 100644 --- a/android/app/res/values-cs/strings_pbap.xml +++ b/android/app/res/values-cs/strings_pbap.xml @@ -13,8 +13,6 @@ "Mé jméno" "000000" "Sdílení kontaktu přes Bluetooth" - - - - + "Je podporována pokročilá funkce telefonního seznamu" + "Pro funkci pokročilého telefonního seznamu opakujte spárování" diff --git a/android/app/res/values-da/strings_pbap.xml b/android/app/res/values-da/strings_pbap.xml index 32ef096cfa7..40ad73884e1 100644 --- a/android/app/res/values-da/strings_pbap.xml +++ b/android/app/res/values-da/strings_pbap.xml @@ -13,8 +13,6 @@ "Mit navn" "000000" "Deling af kontakter via Bluetooth" - - - - + "Avanceret funktion til telefonbogen understøttes" + "Parring af avanceret funktion til telefonbogen" diff --git a/android/app/res/values-de/strings_pbap.xml b/android/app/res/values-de/strings_pbap.xml index c30e6a9886b..f02a6b919a3 100644 --- a/android/app/res/values-de/strings_pbap.xml +++ b/android/app/res/values-de/strings_pbap.xml @@ -13,8 +13,6 @@ "Mein Name" "000000" "Kontakte über Bluetooth teilen" - - - - + "Erweitertes Telefonbuch wird unterstützt" + "Für Nutzung des erweiterten Telefonbuchs wieder koppeln" diff --git a/android/app/res/values-es-rUS/strings_pbap.xml b/android/app/res/values-es-rUS/strings_pbap.xml index 53dcd006972..9a67653219e 100644 --- a/android/app/res/values-es-rUS/strings_pbap.xml +++ b/android/app/res/values-es-rUS/strings_pbap.xml @@ -13,8 +13,6 @@ "Mi nombre" "000000" "Compartir contactos por Bluetooth" - - - - + "Compatibilidad con las funciones avanzadas de la agenda telefónica" + "Volver a vincular para acceder a las funciones avanzadas de la agenda telefónica" diff --git a/android/app/res/values-es/strings_pbap.xml b/android/app/res/values-es/strings_pbap.xml index c8236009f7d..7ec3a65a8a7 100644 --- a/android/app/res/values-es/strings_pbap.xml +++ b/android/app/res/values-es/strings_pbap.xml @@ -13,8 +13,6 @@ "Mi nombre" "000000" "Compartir contactos por Bluetooth" - - - - + "Compatible con la función avanzada de agenda de contactos" + "Volver a emparejar para la función avanzada de agenda de contactos" diff --git a/android/app/res/values-et/strings_pbap.xml b/android/app/res/values-et/strings_pbap.xml index 18173cfefd6..1d2a2df8e0d 100644 --- a/android/app/res/values-et/strings_pbap.xml +++ b/android/app/res/values-et/strings_pbap.xml @@ -13,8 +13,6 @@ "Minu nimi" "000000" "Bluetoothi kontakti jagamine" - - - - + "Toetatud on telefoniraamatu täiustatud funktsioon" + "Täiustatud telefoniraamatufunktsiooni kasutamiseks siduge seade uuesti" diff --git a/android/app/res/values-fa/strings_pbap.xml b/android/app/res/values-fa/strings_pbap.xml index 95b4eb8da92..917f5b59414 100644 --- a/android/app/res/values-fa/strings_pbap.xml +++ b/android/app/res/values-fa/strings_pbap.xml @@ -13,8 +13,6 @@ "نام من" "000000" "اشتراک‌گذاری مخاطبین ازطریق بلوتوث" - - - - + "از ویژگی پیشرفته دفترچه تلفن پشتیبانی می‌شود" + "برای ویژگی پیشرفته دفترچه تلفن دوباره مرتبط کنید" diff --git a/android/app/res/values-fi/strings_pbap.xml b/android/app/res/values-fi/strings_pbap.xml index 03b8dccd274..b8b149e266d 100644 --- a/android/app/res/values-fi/strings_pbap.xml +++ b/android/app/res/values-fi/strings_pbap.xml @@ -13,8 +13,6 @@ "Oma nimeni" "000000" "Bluetooth-yhteyden jako" - - - - + "Puhelinluettelo-lisäominaisuuden tuki" + "Puhelinluettelo-lisäominaisuuden yhdistäminen uudelleen" diff --git a/android/app/res/values-fr/strings_pbap.xml b/android/app/res/values-fr/strings_pbap.xml index bd8367fa6f9..c3bddbcea0d 100644 --- a/android/app/res/values-fr/strings_pbap.xml +++ b/android/app/res/values-fr/strings_pbap.xml @@ -13,8 +13,6 @@ "Mon nom" "000000" "Partage de contact Bluetooth" - - - - + "Fonctionnalité avancée de l\'annuaire téléphonique prise en charge" + "Nouvelle association de la fonctionnalité avancée de l\'annuaire téléphonique" diff --git a/android/app/res/values-gl/strings_pbap.xml b/android/app/res/values-gl/strings_pbap.xml index abca13d9207..7b333458d04 100644 --- a/android/app/res/values-gl/strings_pbap.xml +++ b/android/app/res/values-gl/strings_pbap.xml @@ -13,8 +13,6 @@ "O meu nome" "000000" "Compartir contactos por Bluetooth" - - - - + "Compatible coa función avanzada de axenda telefónica" + "Volve vincular para activar a función avanzada de axenda telefónica" diff --git a/android/app/res/values-gu/strings_pbap.xml b/android/app/res/values-gu/strings_pbap.xml index af95c9e897a..c19ddf2e644 100644 --- a/android/app/res/values-gu/strings_pbap.xml +++ b/android/app/res/values-gu/strings_pbap.xml @@ -13,8 +13,6 @@ "મારું નામ" "000000" "બ્લૂટૂથ સંપર્ક શેર કરો" - - - - + "ફોનબુકની વિગતવાર સુવિધાને સપોર્ટ કરવામાં આવે છે" + "ફોનબુકની વિગતવાર સુવિધા માટે ફરીથી જોડાણ કરો" diff --git a/android/app/res/values-hi/strings_pbap.xml b/android/app/res/values-hi/strings_pbap.xml index cb594770f0c..e624202da0b 100644 --- a/android/app/res/values-hi/strings_pbap.xml +++ b/android/app/res/values-hi/strings_pbap.xml @@ -13,8 +13,6 @@ "मेरा नाम" "000000" "ब्लूटूथ संपर्क शेयर करें" - - - - + "फ़ोनबुक की बेहतर सुविधा उपलब्ध है" + "फ़ोनबुक की बेहतर सुविधा इस्तेमाल करने के लिए, ब्लूटूथ को फिर से कनेक्ट करें" diff --git a/android/app/res/values-hu/strings_pbap.xml b/android/app/res/values-hu/strings_pbap.xml index 620b0921ff9..a6af6163b20 100644 --- a/android/app/res/values-hu/strings_pbap.xml +++ b/android/app/res/values-hu/strings_pbap.xml @@ -13,8 +13,6 @@ "Telefon neve" "000000" "Bluetooth-névjegymegosztás" - - - - + "A telefonkönyv speciális funkcióinak támogatása" + "Újrapárosítás a telefon speciális funkciójának támogatásához" diff --git a/android/app/res/values-in/strings_pbap.xml b/android/app/res/values-in/strings_pbap.xml index 3a9fd944e2a..b6ee6642a17 100644 --- a/android/app/res/values-in/strings_pbap.xml +++ b/android/app/res/values-in/strings_pbap.xml @@ -13,8 +13,6 @@ "Nama saya" "000000" "Berbagi Kontak Bluetooth" - - - - + "Fitur Lanjutan Daftar Kontak Didukung" + "Sambungkan Ulang untuk mendapatkan Fitur Lanjutan Daftar Kontak" diff --git a/android/app/res/values-is/strings_pbap.xml b/android/app/res/values-is/strings_pbap.xml index f0d69830f72..baf503e6968 100644 --- a/android/app/res/values-is/strings_pbap.xml +++ b/android/app/res/values-is/strings_pbap.xml @@ -13,8 +13,6 @@ "Nafnið mitt" "000000" "Tengiliðum deilt með Bluetooth" - - - - + "Ítareiginleikar símaskrár studdir" + "Lagfæring á ítareiginleikum símaskrár" diff --git a/android/app/res/values-iw/strings_pbap.xml b/android/app/res/values-iw/strings_pbap.xml index d749c298649..db117984e08 100644 --- a/android/app/res/values-iw/strings_pbap.xml +++ b/android/app/res/values-iw/strings_pbap.xml @@ -13,8 +13,6 @@ "השם שלי" "000000" "‏שיתוף אנשי קשר באמצעות Bluetooth" - - - - + "יש תמיכה בתכונה המתקדמת של ספר הטלפונים" + "יש להתאים מחדש כדי להשתמש בתכונה המתקדמת של ספר הטלפונים" diff --git a/android/app/res/values-ja/strings_pbap.xml b/android/app/res/values-ja/strings_pbap.xml index 632cdac71bb..5ad560c387b 100644 --- a/android/app/res/values-ja/strings_pbap.xml +++ b/android/app/res/values-ja/strings_pbap.xml @@ -13,8 +13,6 @@ "名前" "000000" "Bluetooth での連絡先の共有" - - - - + "高度な電話帳機能に対応" + "高度な電話帳機能に合わせて再度ペア設定" diff --git a/android/app/res/values-ka/strings_pbap.xml b/android/app/res/values-ka/strings_pbap.xml index 21a53de92a0..625b0e18976 100644 --- a/android/app/res/values-ka/strings_pbap.xml +++ b/android/app/res/values-ka/strings_pbap.xml @@ -13,8 +13,6 @@ "ჩემი სახელი" "000000" "Bluetooth კონტაქტის გაზიარება" - - - - + "სატელეფონო წიგნის მხარდაჭერილი გაფართოებული ფუნქციები" + "შეკეთება სატელეფონო წიგნის გაფართოებული ფუნქციისთვის" diff --git a/android/app/res/values-kk/strings_pbap.xml b/android/app/res/values-kk/strings_pbap.xml index 107e51de769..c092d2c124d 100644 --- a/android/app/res/values-kk/strings_pbap.xml +++ b/android/app/res/values-kk/strings_pbap.xml @@ -13,8 +13,6 @@ "Mені атым" "000000" "Bluetooth арқылы контактіні бөлісу" - - - - + "Телефон кітапшасының қолдау көрсетілетін кеңейтілген функциясы" + "Телефон кітапшасының кеңейтілген функциясын қайта жұптау" diff --git a/android/app/res/values-km/strings_pbap.xml b/android/app/res/values-km/strings_pbap.xml index 068fa26dd77..33f9a3f17ec 100644 --- a/android/app/res/values-km/strings_pbap.xml +++ b/android/app/res/values-km/strings_pbap.xml @@ -13,8 +13,6 @@ "ឈ្មោះ​របស់​ខ្ញុំ" "000000" "ការចែករំលែក​ទំនាក់ទំនង​ប៊្លូធូស" - - - - + "អាចប្រើ​មុខងារកម្រិតខ្ពស់របស់​សៀវភៅទូរសព្ទ" + "ផ្គូផ្គង​មុខងារសៀវភៅទូរសព្ទកម្រិតខ្ពស់​ឡើងវិញ" diff --git a/android/app/res/values-kn/strings_pbap.xml b/android/app/res/values-kn/strings_pbap.xml index c7f550eca23..93543c990a6 100644 --- a/android/app/res/values-kn/strings_pbap.xml +++ b/android/app/res/values-kn/strings_pbap.xml @@ -13,8 +13,6 @@ "ನನ್ನ ಹೆಸರು" "000000" "ಬ್ಲೂಟೂತ್ ಸಂಪರ್ಕ ಹಂಚಿಕೆ" - - - - + "ಫೋನ್‌ಬುಕ್‌ನ ಸುಧಾರಿತ ಫೀಚರ್‌ ಬೆಂಬಲಿತವಾಗಿದೆ" + "ಸುಧಾರಿತ ಫೋನ್‌ಬುಕ್‌ ಫೀಚರ್‌ಗಾಗಿ ಮರು-ಜೋಡಿಸಿ" diff --git a/android/app/res/values-ko/strings_pbap.xml b/android/app/res/values-ko/strings_pbap.xml index acd4a91b19d..eb83f1c46db 100644 --- a/android/app/res/values-ko/strings_pbap.xml +++ b/android/app/res/values-ko/strings_pbap.xml @@ -13,8 +13,6 @@ "내 이름" "000000" "블루투스 연락처 공유" - - - - + "연락처 목록 고급 기능 지원됨" + "고급 연락처 목록 기능을 위해 다시 페어링" diff --git a/android/app/res/values-ky/strings_pbap.xml b/android/app/res/values-ky/strings_pbap.xml index ac8af0cb4fc..d5dc9832128 100644 --- a/android/app/res/values-ky/strings_pbap.xml +++ b/android/app/res/values-ky/strings_pbap.xml @@ -13,8 +13,6 @@ "Менин атым" "000000" "Байланыштарды Bluetooth аркылуу бөлүшүү" - - - - + "Телефон китепчесинин өркүндөтүлгөн функциясы колдоого алынат" + "Телефон китепчесинин өркүндөтүлгөн функциясы үчүн кайра жупташтыруу" diff --git a/android/app/res/values-lo/strings_pbap.xml b/android/app/res/values-lo/strings_pbap.xml index fe460896144..01fe72778e8 100644 --- a/android/app/res/values-lo/strings_pbap.xml +++ b/android/app/res/values-lo/strings_pbap.xml @@ -13,8 +13,6 @@ "ຊື່ຂອງຂ້ອຍ" "000000" "ການແບ່ງປັນລາຍຊື່ຜູ້ຕິດຕໍ່ຜ່ານ Bluetooth" - - - - + "ຮອງຮັບຄຸນສົມບັດຂັ້ນສູງຂອງສະໝຸດໂທລະສັບ" + "ຈັບຄູ່ຄືນໃໝ່ສຳລັບຄຸນສົມບັດສະໝຸດໂທລະສັບຂັ້ນສູງ" diff --git a/android/app/res/values-lt/strings_pbap.xml b/android/app/res/values-lt/strings_pbap.xml index 23283bac71c..317fe301a69 100644 --- a/android/app/res/values-lt/strings_pbap.xml +++ b/android/app/res/values-lt/strings_pbap.xml @@ -13,8 +13,6 @@ "Mano vardas" "000000" "„Bluetooth“ kontaktų bendrinimas" - - - - + "Palaikomos išplėstinės telefonų knygos funkcijos" + "Išplėstinės telefonų knygos funkcijos pakartotinis susiejimas" diff --git a/android/app/res/values-lv/strings_pbap.xml b/android/app/res/values-lv/strings_pbap.xml index 4e6c47a36d2..24b3672fd75 100644 --- a/android/app/res/values-lv/strings_pbap.xml +++ b/android/app/res/values-lv/strings_pbap.xml @@ -13,8 +13,6 @@ "Mans vārds" "000000" "Kontaktpersonu kopīgošana, izmantojot Bluetooth" - - - - + "Atbalstīta tālruņa kataloga papildu funkcija" + "Tālruņa kataloga papildu funkcijas labojums" diff --git a/android/app/res/values-mk/strings_pbap.xml b/android/app/res/values-mk/strings_pbap.xml index fe221c67a34..f7fdc51aa48 100644 --- a/android/app/res/values-mk/strings_pbap.xml +++ b/android/app/res/values-mk/strings_pbap.xml @@ -13,8 +13,6 @@ "Моето име" "000000" "Споделување контакти преку Bluetooth" - - - - + "Напредната функција за телефонски именик е поддржана" + "Повторно спарување за напредната функција за телефонски именик" diff --git a/android/app/res/values-mn/strings_pbap.xml b/android/app/res/values-mn/strings_pbap.xml index 3064425ed76..3d37de990e5 100644 --- a/android/app/res/values-mn/strings_pbap.xml +++ b/android/app/res/values-mn/strings_pbap.xml @@ -13,8 +13,6 @@ "Миний нэр" "000000" "Bluetooth харилцагч хуваалцах" - - - - + "Утасны лавлахын дэвшилтэт онцлогийг дэмжсэн" + "Утасны лавлахын дэвшилтэт онцлогийн засвар" diff --git a/android/app/res/values-mr/strings_pbap.xml b/android/app/res/values-mr/strings_pbap.xml index beb1f7936e8..65d2b474385 100644 --- a/android/app/res/values-mr/strings_pbap.xml +++ b/android/app/res/values-mr/strings_pbap.xml @@ -13,8 +13,6 @@ "माझे नाव" "000000" "ब्लूटूथ संपर्क शेअर" - - - - + "फोनबुकच्या प्रगत वैशिष्ट्याला सपोर्ट आहे" + "फोनबुकच्या प्रगत वैशिष्ट्यासाठी पुन्हा पेअर करा" diff --git a/android/app/res/values-ms/strings_pbap.xml b/android/app/res/values-ms/strings_pbap.xml index bb1bc6ec6b3..23fa745c0ee 100644 --- a/android/app/res/values-ms/strings_pbap.xml +++ b/android/app/res/values-ms/strings_pbap.xml @@ -13,8 +13,6 @@ "Nama saya" "000000" "Perkongsian Kenalan melalui Bluetooth" - - - - + "Ciri Lanjutan Buku Telefon Disokong" + "Gandingkan semula bagi Ciri Lanjutan Buku Telefon" diff --git a/android/app/res/values-my/strings_pbap.xml b/android/app/res/values-my/strings_pbap.xml index 81ea012760f..f0285a45c84 100644 --- a/android/app/res/values-my/strings_pbap.xml +++ b/android/app/res/values-my/strings_pbap.xml @@ -13,8 +13,6 @@ "ကျွန်ုပ်နာမည်" "၀၀၀၀၀၀" "ဘလူးတုသ်ဖြင့် အဆက်အသွယ်မျှဝေခြင်း" - - - - + "‘ဖုန်းစာအုပ် အဆင့်မြင့်တူးလ်’ ကို ပံ့ပိုးထားသည်" + "‘အဆင့်မြင့်ဖုန်းစာအုပ် တူးလ်’ အတွက် ပြန်လည်တွဲချိတ်ရန်" diff --git a/android/app/res/values-nb/strings_pbap.xml b/android/app/res/values-nb/strings_pbap.xml index d719b0c0fe8..25d9acab304 100644 --- a/android/app/res/values-nb/strings_pbap.xml +++ b/android/app/res/values-nb/strings_pbap.xml @@ -13,8 +13,6 @@ "Navnet mitt" "000000" "Bluetooth Contact-deling" - - - - + "Advance-funksjonen i telefonboken støttes" + "Ny tilkobling for Advance-funksjonen i telefonboken" diff --git a/android/app/res/values-ne/strings_pbap.xml b/android/app/res/values-ne/strings_pbap.xml index 17412360f32..cb244056ac3 100644 --- a/android/app/res/values-ne/strings_pbap.xml +++ b/android/app/res/values-ne/strings_pbap.xml @@ -13,8 +13,6 @@ "मेरो नाम" "००००००" "ब्लुटुथमार्फत सम्पर्कको आदान प्रदान" - - - - + "फोनबुकको उन्नत सुविधा प्रयोग गर्न मिल्छ" + "फोनबुकको उन्नत सुविधा प्रयोग गर्न फेरि ब्लुटुथमा कनेक्ट गर्नुहोस्" diff --git a/android/app/res/values-nl/strings_pbap.xml b/android/app/res/values-nl/strings_pbap.xml index dc61f0198b9..588fc41894d 100644 --- a/android/app/res/values-nl/strings_pbap.xml +++ b/android/app/res/values-nl/strings_pbap.xml @@ -13,8 +13,6 @@ "Mijn naam" "000000" "Contacten delen via bluetooth" - - - - + "Geavanceerde telefoonboekfunctie ondersteund" + "Opnieuw koppelen voor geavanceerde telefoonboekfunctie" diff --git a/android/app/res/values-or/strings_pbap.xml b/android/app/res/values-or/strings_pbap.xml index 3263f359111..583a4707780 100644 --- a/android/app/res/values-or/strings_pbap.xml +++ b/android/app/res/values-or/strings_pbap.xml @@ -13,8 +13,6 @@ "ମୋର ନାମ" "000000" "ବ୍ଲୁଟୂଥ କଣ୍ଟାକ୍ଟ ସେୟାର କରନ୍ତୁ" - - - - + "ଫୋନବୁକର ଉନ୍ନତ ଫିଚର ସମର୍ଥିତ ନୁହେଁ" + "ଉନ୍ନତ ଫୋନବୁକ ଫିଚର ପାଇଁ ପୁଣି-ପେୟାର କରନ୍ତୁ" diff --git a/android/app/res/values-pa/strings_pbap.xml b/android/app/res/values-pa/strings_pbap.xml index 0f5a00734c1..e32a362a9c2 100644 --- a/android/app/res/values-pa/strings_pbap.xml +++ b/android/app/res/values-pa/strings_pbap.xml @@ -13,8 +13,6 @@ "ਮੇਰਾ ਨਾਮ" "000000" "ਬਲੂਟੁੱਥ ਸੰਪਰਕ ਸਾਂਝਾਕਰਨ" - - - - + "ਫ਼ੋਨ ਬੁੱਕ ਅਡਵਾਂਸ ਵਿਸ਼ੇਸ਼ਤਾਵਾਂ ਸਮਰਥਿਤ ਹੈ" + "ਅਡਵਾਂਸ ਫ਼ੋਨ ਬੁੱਕ ਵਿਸ਼ੇਸ਼ਤਾ ਲਈ ਮੁੜ-ਜੋੜਬੱਧ ਕਰੋ" diff --git a/android/app/res/values-pl/strings_pbap.xml b/android/app/res/values-pl/strings_pbap.xml index f24be42c19c..94b88c4558b 100644 --- a/android/app/res/values-pl/strings_pbap.xml +++ b/android/app/res/values-pl/strings_pbap.xml @@ -13,8 +13,6 @@ "Moja nazwa" "000000" "Udostępnianie kontaktu przez Bluetooth" - - - - + "Obsługiwana jest zaawansowana funkcja książki telefonicznej" + "Sparuj ponownie, aby korzystać z zaawansowanej funkcji książki telefonicznej" diff --git a/android/app/res/values-pt-rPT/strings_pbap.xml b/android/app/res/values-pt-rPT/strings_pbap.xml index 1509de227e2..4a15bd6f08d 100644 --- a/android/app/res/values-pt-rPT/strings_pbap.xml +++ b/android/app/res/values-pt-rPT/strings_pbap.xml @@ -13,8 +13,6 @@ "O meu nome" "000000" "Partilha de contactos por Bluetooth" - - - - + "Funcionalidade avançada da lista telefónica suportada" + "Volte a sincronizar para obter a funcionalidade avançada da lista telefónica" diff --git a/android/app/res/values-pt/strings_pbap.xml b/android/app/res/values-pt/strings_pbap.xml index fda933e5019..bc6bb5e9363 100644 --- a/android/app/res/values-pt/strings_pbap.xml +++ b/android/app/res/values-pt/strings_pbap.xml @@ -13,8 +13,6 @@ "Meu nome" "000000" "Compartilhamento de contato via Bluetooth" - - - - + "Recurso avançado de agenda de contatos disponível" + "Parear novamente o recurso avançado de agenda de contatos" diff --git a/android/app/res/values-ro/strings_pbap.xml b/android/app/res/values-ro/strings_pbap.xml index c02e4219825..c12fc575ede 100644 --- a/android/app/res/values-ro/strings_pbap.xml +++ b/android/app/res/values-ro/strings_pbap.xml @@ -13,8 +13,6 @@ "Numele meu" "000000" "Distribuirea persoanei de contact prin Bluetooth" - - - - + "Este acceptată funcția Phonebook Advance" + "Asociază din nou pentru funcția Advance Phonebook" diff --git a/android/app/res/values-si/strings_pbap.xml b/android/app/res/values-si/strings_pbap.xml index 25c6a36b7f3..69435a81cf0 100644 --- a/android/app/res/values-si/strings_pbap.xml +++ b/android/app/res/values-si/strings_pbap.xml @@ -13,8 +13,6 @@ "මගේ නම" "000000" "බ්ලූටූත් සම්බන්ධතා බෙදා ගැනීම" - - - - + "දුරකථන නාමාවලි උසස් විශේෂාංගයට සහාය දක්වයි" + "උසස් දුරකථන නාමාවලි විශේෂාංගය සඳහා නැවත යුගල කරන්න" diff --git a/android/app/res/values-sk/strings_pbap.xml b/android/app/res/values-sk/strings_pbap.xml index f3f478a3067..0ee5fc3127b 100644 --- a/android/app/res/values-sk/strings_pbap.xml +++ b/android/app/res/values-sk/strings_pbap.xml @@ -13,8 +13,6 @@ "Moje meno" "000000" "Zdieľanie kontaktov cez Bluetooth" - - - - + "Je podporovaná pokročilá funkcia telefónneho zoznamu" + "Oprava pokročilej funkcie telefónneho zoznamu" diff --git a/android/app/res/values-sl/strings_pbap.xml b/android/app/res/values-sl/strings_pbap.xml index e56ac85f333..601596f01bb 100644 --- a/android/app/res/values-sl/strings_pbap.xml +++ b/android/app/res/values-sl/strings_pbap.xml @@ -13,8 +13,6 @@ "Moje ime" "000000" "Deljenje stikov z drugimi prek Bluetootha" - - - - + "Napredna funkcija telefonskega imenika je podprta" + "Vnovična seznanitev za napredno funkcijo telefonskega imenika" diff --git a/android/app/res/values-sq/strings_pbap.xml b/android/app/res/values-sq/strings_pbap.xml index 10ae5ec7910..0cc879c6e0d 100644 --- a/android/app/res/values-sq/strings_pbap.xml +++ b/android/app/res/values-sq/strings_pbap.xml @@ -13,8 +13,6 @@ "Emri im" "000000" "Ndarja e kontakteve me Bluetooth" - - - - + "Mbështetet \"Veçoria e përparuar e numëratorit telefonik\"" + "Çifto sërish për \"Veçorinë e përparuar të numëratorit telefonik\"" diff --git a/android/app/res/values-sv/strings_pbap.xml b/android/app/res/values-sv/strings_pbap.xml index 6e770f0bbb2..7928caba922 100644 --- a/android/app/res/values-sv/strings_pbap.xml +++ b/android/app/res/values-sv/strings_pbap.xml @@ -13,8 +13,6 @@ "Mitt namn" "000000" "Kontaktdelning via Bluetooth" - - - - + "Avancerad telefonboksfunktion stöds" + "Parkoppla igen för avancerad telefonboksfunktion" diff --git a/android/app/res/values-sw/strings_pbap.xml b/android/app/res/values-sw/strings_pbap.xml index 60b47fd0238..8c65d4ad847 100644 --- a/android/app/res/values-sw/strings_pbap.xml +++ b/android/app/res/values-sw/strings_pbap.xml @@ -13,8 +13,6 @@ "Jina langu" "000000" "Kushiriki Anwani kupitia Bluetooth" - - - - + "Kipengele cha Kina cha Orodha ya anwani Kinatumika" + "Rekebisha Kipengele cha Kina cha Orodha ya Anwani" diff --git a/android/app/res/values-te/strings_pbap.xml b/android/app/res/values-te/strings_pbap.xml index c70f8c954b9..2f231fb431d 100644 --- a/android/app/res/values-te/strings_pbap.xml +++ b/android/app/res/values-te/strings_pbap.xml @@ -13,8 +13,6 @@ "నా పేరు" "000000" "బ్లూటూత్ కాంటాక్ట్ షేర్" - - - - + "ఫోన్‌బుక్‌కు సంబంధించిన అధునాతన ఫీచర్ సపోర్ట్ చేయబడుతుంది" + "అధునాతన ఫోన్‌బుక్ ఫీచర్‌ను ఉపయోగించడానికి, మళ్లీ పెయిర్ చేయండి" diff --git a/android/app/res/values-tl/strings_pbap.xml b/android/app/res/values-tl/strings_pbap.xml index 7985c1e500a..3eb4a969016 100644 --- a/android/app/res/values-tl/strings_pbap.xml +++ b/android/app/res/values-tl/strings_pbap.xml @@ -13,8 +13,6 @@ "Aking pangalan" "000000" "Pagbabahagi ng Contact sa Bluetooth" - - - - + "Sinusuportahan ang Advance Feature ng Phonebook" + "Ipares ulit para sa Advance Feature ng Phonebook" diff --git a/android/app/res/values-tr/strings_pbap.xml b/android/app/res/values-tr/strings_pbap.xml index d405b49dfe6..04bc50424b5 100644 --- a/android/app/res/values-tr/strings_pbap.xml +++ b/android/app/res/values-tr/strings_pbap.xml @@ -13,8 +13,6 @@ "Adım" "000000" "Bluetooth Kişi paylaşımı" - - - - + "Telefon Rehberi İleri Seviye Özelliği Desteklenir" + "İleri Seviye Telefon Rehberi Özelliği için Yeniden Eşleştirme" diff --git a/android/app/res/values-uk/strings_pbap.xml b/android/app/res/values-uk/strings_pbap.xml index 8ce619cd559..0ea877e4a1b 100644 --- a/android/app/res/values-uk/strings_pbap.xml +++ b/android/app/res/values-uk/strings_pbap.xml @@ -13,8 +13,6 @@ "Моє ім\'я" "000000" "Надсилання контактів Bluetooth" - - - - + "Підтримка розширеної функції телефонної книги" + "Повторне підключення розширеної функції телефонної книги" diff --git a/android/app/res/values-ur/strings_pbap.xml b/android/app/res/values-ur/strings_pbap.xml index 5467532d0c9..28b291920ec 100644 --- a/android/app/res/values-ur/strings_pbap.xml +++ b/android/app/res/values-ur/strings_pbap.xml @@ -13,8 +13,6 @@ "میرا نام" "000000" "بلوٹوتھ رابطہ اشتراک" - - - - + "فون بک اعلی خصوصیات تعاون یافتہ ہے" + "فون بک کی اعلی خصوصیات کی مرمت" diff --git a/android/app/res/values-vi/strings_pbap.xml b/android/app/res/values-vi/strings_pbap.xml index 6e680ed7248..f2a552f96d0 100644 --- a/android/app/res/values-vi/strings_pbap.xml +++ b/android/app/res/values-vi/strings_pbap.xml @@ -13,8 +13,6 @@ "Tên của tôi" "000000" "Chia sẻ liên hệ qua Bluetooth" - - - - + "Có hỗ trợ tính năng nâng cao dành cho danh bạ điện thoại" + "Hãy ghép nối lại để dùng tính năng nâng cao dành cho danh bạ điện thoại" diff --git a/android/app/res/values-zh-rCN/strings_pbap.xml b/android/app/res/values-zh-rCN/strings_pbap.xml index d7b338bca98..60fbe171c00 100644 --- a/android/app/res/values-zh-rCN/strings_pbap.xml +++ b/android/app/res/values-zh-rCN/strings_pbap.xml @@ -13,8 +13,6 @@ "我的名字" "000000" "通过蓝牙分享联系人" - - - - + "支持电话簿高级功能" + "重新配对以使用高级电话簿功能" diff --git a/android/app/res/values-zh-rHK/strings_pbap.xml b/android/app/res/values-zh-rHK/strings_pbap.xml index 4592b368047..ef0ac40f1ec 100644 --- a/android/app/res/values-zh-rHK/strings_pbap.xml +++ b/android/app/res/values-zh-rHK/strings_pbap.xml @@ -13,8 +13,6 @@ "我的姓名" "000000" "藍牙聯絡人分享" - - - - + "支援電話簿進階功能" + "為進階電話簿功能而重新配對" diff --git a/android/app/res/values-zh-rTW/strings_pbap.xml b/android/app/res/values-zh-rTW/strings_pbap.xml index 3e4be4f6937..11df8847dc2 100644 --- a/android/app/res/values-zh-rTW/strings_pbap.xml +++ b/android/app/res/values-zh-rTW/strings_pbap.xml @@ -13,8 +13,6 @@ "我的名稱" "000000" "藍牙聯絡人分享" - - - - + "支援電話簿進階功能" + "重新配對以使用進階電話簿功能" diff --git a/android/app/res/values-zu/strings_pbap.xml b/android/app/res/values-zu/strings_pbap.xml index 719c43d89d4..9031b665d60 100644 --- a/android/app/res/values-zu/strings_pbap.xml +++ b/android/app/res/values-zu/strings_pbap.xml @@ -13,8 +13,6 @@ "Igama lami" "000000" "Ukwabelana koxhumana nabo kwe-Bluetooth" - - - - + "Isakhi Esithuthukisiwe Sezinombolo Zokuxhumana Ezisekelwe" + "Lungisa kabusha Isakhi Sezinombolo Zokuxhumana Esithuthukisiwe" -- GitLab From 4d2566ad28fa57d5076ca92847e10bbc1063fd2a Mon Sep 17 00:00:00 2001 From: Palash Ahuja Date: Wed, 15 Mar 2023 13:41:45 -0700 Subject: [PATCH 0008/2405] [BluetoothMetrics] This covers the case for Direct LE-ACL Connection Success Rate as per go/bluetooth-le-connection-metrics. Unit Tests: - Successful - Failure - Timeout - Cancellation Test: atest bluetooth_test_gd_unit:LEConnectionMetricsRemoteDeviceTest --host Change-Id: I7b8618c30d5f1e4dc5b9665e056934c2db888271 --- system/common/metrics.cc | 18 ++ system/common/metrics.h | 11 + system/gd/Android.bp | 1 + system/gd/hci/acl_manager/le_impl.h | 47 +++- system/gd/metrics/Android.bp | 3 + system/gd/metrics/BUILD.gn | 5 +- system/gd/metrics/metrics.h | 1 - system/gd/metrics/metrics_state.cc | 227 ++++++++++++++++++ system/gd/metrics/metrics_state.h | 122 ++++++++++ system/gd/metrics/metrics_state_unittest.cc | 196 +++++++++++++++ system/gd/metrics/utils.cc | 12 + system/gd/metrics/utils.h | 8 +- system/gd/os/android/metrics.cc | 40 +++ system/gd/os/host/metrics.cc | 10 + system/gd/os/linux/metrics.cc | 7 + system/gd/os/metrics.h | 44 +++- system/main/shim/metrics_api.cc | 12 + system/main/shim/metrics_api.h | 9 + system/stack/acl/btm_acl.cc | 12 + .../test/mock/mock_main_shim_metrics_api.cc | 10 + system/test/mock/mock_main_shim_metrics_api.h | 36 +++ 21 files changed, 823 insertions(+), 8 deletions(-) create mode 100644 system/gd/metrics/metrics_state.cc create mode 100644 system/gd/metrics/metrics_state.h create mode 100644 system/gd/metrics/metrics_state_unittest.cc diff --git a/system/common/metrics.cc b/system/common/metrics.cc index baf838b0c4c..b243fd78b7f 100644 --- a/system/common/metrics.cc +++ b/system/common/metrics.cc @@ -20,6 +20,7 @@ #include #include +#include #include #include #include @@ -35,6 +36,9 @@ #include "address_obfuscator.h" #include "bluetooth/metrics/bluetooth.pb.h" +#include "gd/metrics/metrics_state.h" +#include "gd/hci/address.h" +#include "gd/os/metrics.h" #include "leaky_bonded_queue.h" #include "metric_id_allocator.h" #include "osi/include/osi.h" @@ -68,6 +72,7 @@ using bluetooth::metrics::BluetoothMetricsProto::ScanEvent_ScanEventType; using bluetooth::metrics::BluetoothMetricsProto::ScanEvent_ScanTechnologyType; using bluetooth::metrics::BluetoothMetricsProto::WakeEvent; using bluetooth::metrics::BluetoothMetricsProto::WakeEvent_WakeEventType; +using bluetooth::hci::Address; static float combine_averages(float avg_a, int64_t ct_a, float avg_b, int64_t ct_b) { @@ -969,6 +974,19 @@ void LogLeAudioBroadcastSessionReported(int64_t duration_nanos) { } } +void LogLeBluetoothConnectionMetricEventReported( + const Address& address, + android::bluetooth::le::LeConnectionOriginType origin_type, + android::bluetooth::le::LeConnectionType connection_type, + android::bluetooth::le::LeConnectionState transaction_state, + std::vector> + argument_list) { + // Log the events for the State Management + metrics::MetricsCollector::GetLEConnectionMetricsCollector() + ->AddStateChangedEvent(address, origin_type, connection_type, + transaction_state, argument_list); +} + } // namespace common } // namespace bluetooth diff --git a/system/common/metrics.h b/system/common/metrics.h index a0a34b59453..273cbdab194 100644 --- a/system/common/metrics.h +++ b/system/common/metrics.h @@ -21,13 +21,16 @@ #include #include #include +#include #include #include #include #include +#include "gd/os/metrics.h" #include "types/raw_address.h" +#include "hci/address.h" namespace bluetooth { @@ -520,6 +523,14 @@ void LogLeAudioConnectionSessionReported( void LogLeAudioBroadcastSessionReported(int64_t duration_nanos); +void LogLeBluetoothConnectionMetricEventReported( + const RawAddress& raw_address, + android::bluetooth::le::LeConnectionOriginType origin_type, + android::bluetooth::le::LeConnectionType connection_type, + android::bluetooth::le::LeConnectionState transaction_state, + std::vector> + argument_list); + } // namespace common } // namespace bluetooth diff --git a/system/gd/Android.bp b/system/gd/Android.bp index 3a784354cb4..5876cffa8ab 100644 --- a/system/gd/Android.bp +++ b/system/gd/Android.bp @@ -427,6 +427,7 @@ cc_test { "libbt_callbacks_cxx", "libbt_shim_bridge", "libbt_shim_ffi", + "libbt-platform-protos-lite" ], shared_libs: [ "libcrypto", diff --git a/system/gd/hci/acl_manager/le_impl.h b/system/gd/hci/acl_manager/le_impl.h index 4e849e74363..b14e9a19805 100644 --- a/system/gd/hci/acl_manager/le_impl.h +++ b/system/gd/hci/acl_manager/le_impl.h @@ -38,6 +38,7 @@ #include "hci/le_address_manager.h" #include "os/alarm.h" #include "os/handler.h" +#include "os/metrics.h" #include "os/system_properties.h" #include "packet/packet_view.h" @@ -342,6 +343,16 @@ struct le_impl : public bluetooth::hci::LeAddressManagerCallback { AddressWithType remote_address(address, peer_address_type); AddressWithType local_address = le_address_manager_->GetInitiatorAddress(); const bool in_filter_accept_list = is_device_in_connect_list(remote_address); + auto argument_list = std::vector>(); + argument_list.push_back( + std::make_pair(os::ArgumentType::ACL_STATUS_CODE, static_cast(status))); + + bluetooth::os::LogMetricBluetoothLEConnectionMetricEvent( + address, + android::bluetooth::le::LeConnectionOriginType::ORIGIN_NATIVE, + android::bluetooth::le::LeConnectionType::CONNECTION_TYPE_LE_ACL, + android::bluetooth::le::LeConnectionState::STATE_LE_ACL_END, + argument_list); if (role == hci::Role::CENTRAL) { connectability_state_ = ConnectabilityState::DISARMED; @@ -353,7 +364,7 @@ struct le_impl : public bluetooth::hci::LeAddressManagerCallback { if (status == ErrorCode::UNKNOWN_CONNECTION) { if (remote_address.GetAddress() != Address::kEmpty) { LOG_INFO("Controller send non-empty address field:%s", - ADDRESS_TO_LOGGABLE_CSTR(remote_address.GetAddress())); + ADDRESS_TO_LOGGABLE_CSTR(remote_address.GetAddress())); } // direct connect canceled due to connection timeout, start background connect create_le_connection(remote_address, false, false); @@ -485,6 +496,16 @@ struct le_impl : public bluetooth::hci::LeAddressManagerCallback { } AddressWithType remote_address(address, remote_address_type); const bool in_filter_accept_list = is_device_in_connect_list(remote_address); + auto argument_list = std::vector>(); + argument_list.push_back( + std::make_pair(os::ArgumentType::ACL_STATUS_CODE, static_cast(status))); + + bluetooth::os::LogMetricBluetoothLEConnectionMetricEvent( + address, + android::bluetooth::le::LeConnectionOriginType::ORIGIN_NATIVE, + android::bluetooth::le::LeConnectionType::CONNECTION_TYPE_LE_ACL, + android::bluetooth::le::LeConnectionState::STATE_LE_ACL_END, + argument_list); if (role == hci::Role::CENTRAL) { connectability_state_ = ConnectabilityState::DISARMED; @@ -498,7 +519,7 @@ struct le_impl : public bluetooth::hci::LeAddressManagerCallback { if (status == ErrorCode::UNKNOWN_CONNECTION) { if (remote_address.GetAddress() != Address::kEmpty) { LOG_INFO("Controller send non-empty address field:%s", - ADDRESS_TO_LOGGABLE_CSTR(remote_address.GetAddress())); + ADDRESS_TO_LOGGABLE_CSTR(remote_address.GetAddress())); } // direct connect canceled due to connection timeout, start background connect create_le_connection(remote_address, false, false); @@ -792,7 +813,7 @@ struct le_impl : public bluetooth::hci::LeAddressManagerCallback { void remove_device_from_connect_list(AddressWithType address_with_type) { if (connect_list.find(address_with_type) == connect_list.end()) { LOG_WARN("Device not in acceptlist and cannot be removed:%s", - ADDRESS_TO_LOGGABLE_CSTR(address_with_type)); + ADDRESS_TO_LOGGABLE_CSTR(address_with_type)); return; } connect_list.erase(address_with_type); @@ -982,6 +1003,15 @@ struct le_impl : public bluetooth::hci::LeAddressManagerCallback { } void disarm_connectability() { + + auto argument_list = std::vector>(); + bluetooth::os::LogMetricBluetoothLEConnectionMetricEvent( + Address::kEmpty, + os::LeConnectionOriginType::ORIGIN_UNSPECIFIED, + os::LeConnectionType::CONNECTION_TYPE_LE_ACL, + os::LeConnectionState::STATE_LE_ACL_CANCEL, + argument_list); + switch (connectability_state_) { case ConnectabilityState::ARMED: LOG_INFO("Disarming LE connection state machine with create connection cancel"); @@ -1078,6 +1108,17 @@ struct le_impl : public bluetooth::hci::LeAddressManagerCallback { if (create_connection_timeout_alarms_.find(address_with_type) != create_connection_timeout_alarms_.end()) { create_connection_timeout_alarms_.at(address_with_type).Cancel(); create_connection_timeout_alarms_.erase(address_with_type); + auto argument_list = std::vector>(); + argument_list.push_back(std::make_pair( + os::ArgumentType::ACL_STATUS_CODE, + static_cast(android::bluetooth::hci::StatusEnum::STATUS_CONNECTION_TOUT))); + bluetooth::os::LogMetricBluetoothLEConnectionMetricEvent( + address_with_type.GetAddress(), + android::bluetooth::le::LeConnectionOriginType::ORIGIN_NATIVE, + android::bluetooth::le::LeConnectionType::CONNECTION_TYPE_LE_ACL, + android::bluetooth::le::LeConnectionState::STATE_LE_ACL_TIMEOUT, + argument_list); + if (background_connections_.find(address_with_type) != background_connections_.end()) { direct_connections_.erase(address_with_type); disarm_connectability(); diff --git a/system/gd/metrics/Android.bp b/system/gd/metrics/Android.bp index 2556f89daed..5ae11f16e17 100644 --- a/system/gd/metrics/Android.bp +++ b/system/gd/metrics/Android.bp @@ -11,6 +11,8 @@ filegroup { name: "BluetoothMetricsSources", srcs: [ "counter_metrics.cc", + "metrics_state.cc", + "utils.cc" ], } @@ -18,5 +20,6 @@ filegroup { name: "BluetoothMetricsTestSources", srcs: [ "counter_metrics_unittest.cc", + "metrics_state_unittest.cc" ], } diff --git a/system/gd/metrics/BUILD.gn b/system/gd/metrics/BUILD.gn index d920fa54b7c..45ab505355d 100644 --- a/system/gd/metrics/BUILD.gn +++ b/system/gd/metrics/BUILD.gn @@ -34,10 +34,11 @@ source_set("BluetoothMetricsSources") { sources = [ "counter_metrics.cc", "utils.cc", + "metrics_state.cc" ] - configs += [ "//bt/system/gd:gd_defaults" ] - deps = [ "//bt/system/gd:gd_default_deps" ] + configs += [ "//bt/system/gd:gd_defaults"] + deps = [ "//bt/system/gd:gd_default_deps", "//bt/system:libbt-platform-protos-lite", "//bt/system/gd:libstatslog_bt"] if (target_os == "chromeos") { deps += [ ":BluetoothMetricsSources_chromeos" ] diff --git a/system/gd/metrics/metrics.h b/system/gd/metrics/metrics.h index cb8246207d9..6e22318c408 100644 --- a/system/gd/metrics/metrics.h +++ b/system/gd/metrics/metrics.h @@ -16,7 +16,6 @@ #pragma once #include - #include "types/raw_address.h" namespace bluetooth { diff --git a/system/gd/metrics/metrics_state.cc b/system/gd/metrics/metrics_state.cc new file mode 100644 index 00000000000..602657a2f11 --- /dev/null +++ b/system/gd/metrics/metrics_state.cc @@ -0,0 +1,227 @@ +/* + * Copyright 2022 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "metrics_state.h" + +#include +#include + +#include +#include +#include +#include +#include + +#include "common/strings.h" +#include "hci/address.h" +#include "metrics/utils.h" +#include "os/log.h" +#include "os/metrics.h" + +namespace bluetooth { +namespace metrics { + +using android::bluetooth::le::LeConnectionOriginType; +using android::bluetooth::le::LeConnectionState; +using android::bluetooth::le::LeConnectionType; + +// const static ClockTimePoint kInvalidTimePoint{}; + +/* + * This is the device level metrics state, which will be modified based on + * incoming state events. + * + */ +void LEConnectionMetricState::AddStateChangedEvent( + LeConnectionOriginType origin_type, + LeConnectionType connection_type, + LeConnectionState transaction_state, + std::vector> argument_list) { + LOG_INFO( + "LEConnectionMetricState: Origin Type: %s, Connection Type: %s, Transaction State: " + "%s", + common::ToHexString(origin_type).c_str(), + common::ToHexString(connection_type).c_str(), + common::ToHexString(transaction_state).c_str()); + + ClockTimePoint current_timestamp = std::chrono::high_resolution_clock::now(); + state = transaction_state; + + // Assign the origin of the connection + if (connection_origin_type == LeConnectionOriginType::ORIGIN_UNSPECIFIED) { + connection_origin_type = origin_type; + } + + if (input_connection_type == LeConnectionType::CONNECTION_TYPE_UNSPECIFIED) { + input_connection_type = connection_type; + } + + if (start_timepoint == kInvalidTimePoint) { + start_timepoint = current_timestamp; + } + end_timepoint = current_timestamp; + + switch (state) { + case LeConnectionState::STATE_LE_ACL_END: { + int acl_status_code_from_args = + GetArgumentTypeFromList(argument_list, os::ArgumentType::ACL_STATUS_CODE); + acl_status_code = static_cast(acl_status_code_from_args); + acl_state = LeAclConnectionState::LE_ACL_SUCCESS; + + if (acl_status_code != android::bluetooth::hci::StatusEnum::STATUS_SUCCESS) { + acl_state = LeAclConnectionState::LE_ACL_FAILED; + } + break; + } + case LeConnectionState::STATE_LE_ACL_TIMEOUT: { + int acl_status_code_from_args = + GetArgumentTypeFromList(argument_list, os::ArgumentType::ACL_STATUS_CODE); + acl_status_code = static_cast(acl_status_code_from_args); + acl_state = LeAclConnectionState::LE_ACL_FAILED; + break; + } + case LeConnectionState::STATE_LE_ACL_CANCEL: { + acl_state = LeAclConnectionState::LE_ACL_FAILED; + is_cancelled = true; + break; + } + [[fallthrough]]; + default: { + // do nothing + } + } +} + +bool LEConnectionMetricState::IsEnded() { + return acl_state == LeAclConnectionState::LE_ACL_SUCCESS || + acl_state == LeAclConnectionState::LE_ACL_FAILED; +} + +bool LEConnectionMetricState::IsStarted() { + return state == LeConnectionState::STATE_LE_ACL_START; +} + +bool LEConnectionMetricState::IsCancelled() { + return is_cancelled; +} + +// Initialize the LEConnectionMetricsRemoteDevice +LEConnectionMetricsRemoteDevice::LEConnectionMetricsRemoteDevice() { + metrics_logger_module = new MetricsLoggerModule(); +} + +LEConnectionMetricsRemoteDevice::LEConnectionMetricsRemoteDevice( + BaseMetricsLoggerModule* baseMetricsLoggerModule) { + metrics_logger_module = baseMetricsLoggerModule; +} + +// Uploading the session +void LEConnectionMetricsRemoteDevice::UploadLEConnectionSession(const hci::Address& address) { + auto it = opened_devices.find(address); + if (it != opened_devices.end()) { + os::LEConnectionSessionOptions session_options; + session_options.acl_connection_state = it->second->acl_state; + session_options.origin_type = it->second->connection_origin_type; + session_options.transaction_type = it->second->input_connection_type; + session_options.latency = bluetooth::metrics::get_timedelta_nanos( + it->second->start_timepoint, it->second->end_timepoint); + session_options.remote_address = address; + session_options.status = it->second->acl_status_code; + // TODO: keep the acl latency the same as the overall latency for now + // When more events are added, we will an overall latency + session_options.acl_latency = session_options.latency; + session_options.is_cancelled = it->second->is_cancelled; + metrics_logger_module->LogMetricBluetoothLESession(session_options); + LOG_INFO( + "LEConnectionMetricsRemoteDevice: The session is uploaded for %s\n", + ADDRESS_TO_LOGGABLE_CSTR(address)); + opened_devices.erase(it); + } +} + +// Implementation of metrics per remote device +void LEConnectionMetricsRemoteDevice::AddStateChangedEvent( + const hci::Address& address, + LeConnectionOriginType origin_type, + LeConnectionType connection_type, + LeConnectionState transaction_state, + std::vector> argument_list) { + LOG_INFO( + "LEConnectionMetricsRemoteDevice: Transaction State %s, Connection Type %s, Origin Type %s\n", + common::ToHexString(transaction_state).c_str(), + common::ToHexString(connection_type).c_str(), + common::ToHexString(origin_type).c_str()); + if (address.IsEmpty()) { + LOG_INFO( + "LEConnectionMetricsRemoteDevice: Empty Address Cancellation %s, %s, %s\n", + common::ToHexString(transaction_state).c_str(), + common::ToHexString(connection_type).c_str(), + common::ToHexString(transaction_state).c_str()); + for (auto& device_metric : device_metrics) { + if (device_metric->IsStarted() && + transaction_state == LeConnectionState::STATE_LE_ACL_CANCEL) { + LOG_INFO("LEConnectionMetricsRemoteDevice: Cancellation Begin"); + // cancel the connection + device_metric->AddStateChangedEvent( + origin_type, connection_type, transaction_state, argument_list); + continue; + } + + if (device_metric->IsCancelled() && + transaction_state == LeConnectionState::STATE_LE_ACL_END) { + LOG_INFO("LEConnectionMetricsRemoteDevice: Session is now complete after cancellation"); + // complete the connection + device_metric->AddStateChangedEvent( + origin_type, connection_type, transaction_state, argument_list); + UploadLEConnectionSession(address); + continue; + } + } + return; + } + + auto it = opened_devices.find(address); + if (it == opened_devices.end()) { + device_metrics.push_back(std::make_unique(address)); + it = opened_devices.insert(std::begin(opened_devices), {address, device_metrics.back().get()}); + } + + it->second->AddStateChangedEvent(origin_type, connection_type, transaction_state, argument_list); + + // Connection is finished + if (it->second->IsEnded()) { + UploadLEConnectionSession(address); + } +} + + +// MetricsLoggerModule class +void MetricsLoggerModule::LogMetricBluetoothLESession( + os::LEConnectionSessionOptions session_options) { + os::LogMetricBluetoothLEConnection(session_options); +} + +// Instance of Metrics Collector for LEConnectionMetricsRemoteDeviceImpl +LEConnectionMetricsRemoteDevice* MetricsCollector::le_connection_metrics_remote_device = + new LEConnectionMetricsRemoteDevice(); + +LEConnectionMetricsRemoteDevice* MetricsCollector::GetLEConnectionMetricsCollector() { + return MetricsCollector::le_connection_metrics_remote_device; +} + +} // namespace metrics + +} // namespace bluetooth diff --git a/system/gd/metrics/metrics_state.h b/system/gd/metrics/metrics_state.h new file mode 100644 index 00000000000..ca92501ce36 --- /dev/null +++ b/system/gd/metrics/metrics_state.h @@ -0,0 +1,122 @@ +/* + * Copyright 2022 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#pragma once + +#include + +#include +#include +#include +#include +#include +#include + +#include "common/strings.h" +#include "hci/address.h" +#include "os/metrics.h" + +namespace bluetooth { + +namespace metrics { + +using android::bluetooth::le::LeAclConnectionState; +using android::bluetooth::le::LeConnectionOriginType; +using android::bluetooth::le::LeConnectionState; +using android::bluetooth::le::LeConnectionType; + +using ClockTimePoint = std::chrono::time_point; + +const static ClockTimePoint kInvalidTimePoint{}; + +inline int64_t get_timedelta_nanos(const ClockTimePoint& t1, const ClockTimePoint& t2) { + if (t1 == kInvalidTimePoint || t2 == kInvalidTimePoint) { + return -1; + } + return std::abs(std::chrono::duration_cast(t2 - t1).count()); +} + +class BaseMetricsLoggerModule { + public: + BaseMetricsLoggerModule() {} + virtual void LogMetricBluetoothLESession(os::LEConnectionSessionOptions session_options) = 0; + virtual ~BaseMetricsLoggerModule() {} +}; + +class MetricsLoggerModule : public BaseMetricsLoggerModule { + public: + MetricsLoggerModule() {} + void LogMetricBluetoothLESession(os::LEConnectionSessionOptions session_options); + virtual ~MetricsLoggerModule() {} +}; + +class LEConnectionMetricState { + public: + hci::Address address; + LEConnectionMetricState(const hci::Address address) : address(address) {} + LeConnectionState state; + LeAclConnectionState acl_state; + LeConnectionType input_connection_type = LeConnectionType::CONNECTION_TYPE_UNSPECIFIED; + android::bluetooth::hci::StatusEnum acl_status_code; + ClockTimePoint start_timepoint = kInvalidTimePoint; + ClockTimePoint end_timepoint = kInvalidTimePoint; + bool is_cancelled = false; + LeConnectionOriginType connection_origin_type = LeConnectionOriginType::ORIGIN_UNSPECIFIED; + + bool IsStarted(); + bool IsEnded(); + bool IsCancelled(); + + void AddStateChangedEvent( + LeConnectionOriginType origin_type, + LeConnectionType connection_type, + LeConnectionState transaction_state, + std::vector> argument_list); + +}; + +class LEConnectionMetricsRemoteDevice { + public: + LEConnectionMetricsRemoteDevice(); + + LEConnectionMetricsRemoteDevice(BaseMetricsLoggerModule* baseMetricsLoggerModule); + + void AddStateChangedEvent( + const hci::Address& address, + LeConnectionOriginType origin_type, + LeConnectionType connection_type, + LeConnectionState transaction_state, + std::vector> argument_list); + + void UploadLEConnectionSession(const hci::Address& address); + + private: + std::vector> device_metrics; + std::unordered_map opened_devices; + BaseMetricsLoggerModule* metrics_logger_module; +}; + +class MetricsCollector { + public: + // getting the LE Connection Metrics Collector + static LEConnectionMetricsRemoteDevice* GetLEConnectionMetricsCollector(); + + private: + static LEConnectionMetricsRemoteDevice* le_connection_metrics_remote_device; +}; + +} // namespace metrics +} // namespace bluetooth diff --git a/system/gd/metrics/metrics_state_unittest.cc b/system/gd/metrics/metrics_state_unittest.cc new file mode 100644 index 00000000000..435e5c09bb7 --- /dev/null +++ b/system/gd/metrics/metrics_state_unittest.cc @@ -0,0 +1,196 @@ +#include "metrics_state.h" + +#include + +#include +#include + +#include "gtest/gtest.h" +#include "hci/address.h" +#include "metrics_state.h" +#include "os/metrics.h" + +// +using android::bluetooth::hci::StatusEnum; +using android::bluetooth::le::LeAclConnectionState; +using android::bluetooth::le::LeConnectionOriginType; +using android::bluetooth::le::LeConnectionState; +using android::bluetooth::le::LeConnectionType; + +LeAclConnectionState le_acl_state = LeAclConnectionState::LE_ACL_UNSPECIFIED; +LeConnectionOriginType origin_type = LeConnectionOriginType::ORIGIN_UNSPECIFIED; +LeConnectionType connection_type = LeConnectionType::CONNECTION_TYPE_UNSPECIFIED; +StatusEnum status = StatusEnum::STATUS_UNKNOWN; +bluetooth::hci::Address remote_address = bluetooth::hci::Address::kEmpty; +int latency = 0; +int acl_latency = 0; +bool is_cancelled = false; + +namespace bluetooth { +namespace metrics { + +const hci::Address address1 = hci::Address({0x11, 0x22, 0x33, 0x44, 0x55, 0x66}); +const hci::Address empty_address = hci::Address::kEmpty; + +class TestMetricsLoggerModule : public BaseMetricsLoggerModule { + public: + TestMetricsLoggerModule() {} + void LogMetricBluetoothLESession(os::LEConnectionSessionOptions session_options); + virtual ~TestMetricsLoggerModule() {} +}; + +void TestMetricsLoggerModule::LogMetricBluetoothLESession( + os::LEConnectionSessionOptions session_options) { + le_acl_state = session_options.acl_connection_state; + origin_type = session_options.origin_type; + connection_type = session_options.transaction_type; + is_cancelled = session_options.is_cancelled; + status = session_options.status; + remote_address = session_options.remote_address; +} + +class MockMetricsCollector { + public: + static LEConnectionMetricsRemoteDevice* GetLEConnectionMetricsCollector(); + + static LEConnectionMetricsRemoteDevice* le_connection_metrics_remote_device; +}; + + + +LEConnectionMetricsRemoteDevice* MockMetricsCollector::le_connection_metrics_remote_device = + new LEConnectionMetricsRemoteDevice(new TestMetricsLoggerModule()); + +LEConnectionMetricsRemoteDevice* MockMetricsCollector::GetLEConnectionMetricsCollector() { + return MockMetricsCollector::le_connection_metrics_remote_device; +} + +namespace { + +class LEConnectionMetricsRemoteDeviceTest : public ::testing::Test {}; + +TEST(LEConnectionMetricsRemoteDeviceTest, Initialize) { + ASSERT_EQ(0, 0); +} + +TEST(LEConnectionMetricsRemoteDeviceTest, ConnectionSuccess) { + auto argument_list = std::vector>(); + argument_list.push_back(std::make_pair( + os::ArgumentType::ACL_STATUS_CODE, + static_cast(android::bluetooth::hci::StatusEnum::STATUS_SUCCESS))); + + MockMetricsCollector::GetLEConnectionMetricsCollector()->AddStateChangedEvent( + address1, + LeConnectionOriginType::ORIGIN_NATIVE, + LeConnectionType::CONNECTION_TYPE_LE_ACL, + LeConnectionState::STATE_LE_ACL_START, + argument_list); + + MockMetricsCollector::GetLEConnectionMetricsCollector()->AddStateChangedEvent( + address1, + LeConnectionOriginType::ORIGIN_NATIVE, + LeConnectionType::CONNECTION_TYPE_LE_ACL, + LeConnectionState::STATE_LE_ACL_END, + argument_list); + // assert that these are equal + ASSERT_EQ(le_acl_state, LeAclConnectionState::LE_ACL_SUCCESS); + ASSERT_EQ(origin_type, LeConnectionOriginType::ORIGIN_NATIVE); + ASSERT_EQ(connection_type, LeConnectionType::CONNECTION_TYPE_LE_ACL); + ASSERT_EQ(remote_address, address1); + ASSERT_EQ(is_cancelled, false); +} + +TEST(LEConnectionMetricsRemoteDeviceTest, ConnectionFailed) { + auto argument_list = std::vector>(); + argument_list.push_back(std::make_pair( + os::ArgumentType::ACL_STATUS_CODE, + static_cast(android::bluetooth::hci::StatusEnum::STATUS_NO_CONNECTION))); + + MockMetricsCollector::GetLEConnectionMetricsCollector()->AddStateChangedEvent( + address1, + LeConnectionOriginType::ORIGIN_NATIVE, + LeConnectionType::CONNECTION_TYPE_LE_ACL, + LeConnectionState::STATE_LE_ACL_START, + argument_list); + + MockMetricsCollector::GetLEConnectionMetricsCollector()->AddStateChangedEvent( + address1, + LeConnectionOriginType::ORIGIN_NATIVE, + LeConnectionType::CONNECTION_TYPE_LE_ACL, + LeConnectionState::STATE_LE_ACL_END, + argument_list); + // assert that these are equal + ASSERT_EQ(le_acl_state, LeAclConnectionState::LE_ACL_FAILED); + ASSERT_EQ(origin_type, LeConnectionOriginType::ORIGIN_NATIVE); + ASSERT_EQ(connection_type, LeConnectionType::CONNECTION_TYPE_LE_ACL); + ASSERT_EQ(remote_address, address1); + ASSERT_EQ(is_cancelled, false); +} + +TEST(LEConnectionMetricsRemoteDeviceTest, Cancellation) { + auto argument_list = std::vector>(); + auto no_connection_argument_list = std::vector>(); + no_connection_argument_list.push_back(std::make_pair( + os::ArgumentType::ACL_STATUS_CODE, + static_cast(android::bluetooth::hci::StatusEnum::STATUS_NO_CONNECTION))); + + // Start of the LE-ACL Connection + MockMetricsCollector::GetLEConnectionMetricsCollector()->AddStateChangedEvent( + address1, + LeConnectionOriginType::ORIGIN_NATIVE, + LeConnectionType::CONNECTION_TYPE_LE_ACL, + LeConnectionState::STATE_LE_ACL_START, + argument_list); + + // Cancellation of the LE-ACL Connection + MockMetricsCollector::GetLEConnectionMetricsCollector()->AddStateChangedEvent( + empty_address, + LeConnectionOriginType::ORIGIN_NATIVE, + LeConnectionType::CONNECTION_TYPE_LE_ACL, + LeConnectionState::STATE_LE_ACL_CANCEL, + argument_list); + + // Ending of the LE-ACL Connection + MockMetricsCollector::GetLEConnectionMetricsCollector()->AddStateChangedEvent( + address1, + LeConnectionOriginType::ORIGIN_NATIVE, + LeConnectionType::CONNECTION_TYPE_LE_ACL, + LeConnectionState::STATE_LE_ACL_END, + no_connection_argument_list); + + ASSERT_EQ(le_acl_state, LeAclConnectionState::LE_ACL_FAILED); + ASSERT_EQ(origin_type, LeConnectionOriginType::ORIGIN_NATIVE); + ASSERT_EQ(connection_type, LeConnectionType::CONNECTION_TYPE_LE_ACL); + ASSERT_EQ(remote_address, address1); + ASSERT_EQ(is_cancelled, true); +} + +TEST(LEConnectionMetricsRemoteDeviceTest, Timeout) { + auto argument_list = std::vector>(); + + // Start of the LE-ACL Connection + MockMetricsCollector::GetLEConnectionMetricsCollector()->AddStateChangedEvent( + address1, + LeConnectionOriginType::ORIGIN_NATIVE, + LeConnectionType::CONNECTION_TYPE_LE_ACL, + LeConnectionState::STATE_LE_ACL_START, + argument_list); + + // Timeout of the LE-ACL Connection + MockMetricsCollector::GetLEConnectionMetricsCollector()->AddStateChangedEvent( + address1, + LeConnectionOriginType::ORIGIN_NATIVE, + LeConnectionType::CONNECTION_TYPE_LE_ACL, + LeConnectionState::STATE_LE_ACL_TIMEOUT, + argument_list); + + ASSERT_EQ(le_acl_state, LeAclConnectionState::LE_ACL_FAILED); + ASSERT_EQ(origin_type, LeConnectionOriginType::ORIGIN_NATIVE); + ASSERT_EQ(connection_type, LeConnectionType::CONNECTION_TYPE_LE_ACL); + ASSERT_EQ(remote_address, address1); + ASSERT_EQ(is_cancelled, false); +} + +} // namespace +} // namespace metrics +} // namespace bluetooth diff --git a/system/gd/metrics/utils.cc b/system/gd/metrics/utils.cc index b059bb71330..40520e461ba 100644 --- a/system/gd/metrics/utils.cc +++ b/system/gd/metrics/utils.cc @@ -35,5 +35,17 @@ bool GetBootId(std::string* boot_id) { return true; } +int GetArgumentTypeFromList( + std::vector>& argument_list, os::ArgumentType argumentType) { + for (std::pair argumentPair : argument_list) { + if (argumentPair.first == argumentType) { + return argumentPair.second; + } + } + return -1; +} + + + } // namespace metrics } // namespace bluetooth diff --git a/system/gd/metrics/utils.h b/system/gd/metrics/utils.h index d6f25373dc4..78ab5427b2f 100644 --- a/system/gd/metrics/utils.h +++ b/system/gd/metrics/utils.h @@ -16,11 +16,17 @@ #pragma once #include +#include +#include + +#include "os/metrics.h" namespace bluetooth { namespace metrics { bool GetBootId(std::string* boot_id); +int GetArgumentTypeFromList( + std::vector>& argument_list, os::ArgumentType argumentType); } // namespace metrics -} // namespace bluetooth \ No newline at end of file +} // namespace bluetooth diff --git a/system/gd/os/android/metrics.cc b/system/gd/os/android/metrics.cc index c9c66e50dd3..f45d2828172 100644 --- a/system/gd/os/android/metrics.cc +++ b/system/gd/os/android/metrics.cc @@ -23,6 +23,7 @@ #include #include "common/audit_log.h" +#include "metrics/metrics_state.h" #include "common/metric_id_manager.h" #include "common/strings.h" #include "hci/hci_packets.h" @@ -511,5 +512,44 @@ void LogMetricBluetoothCodePathCounterMetrics(int32_t key, int64_t count) { } } +void LogMetricBluetoothLEConnectionMetricEvent( + const Address& address, + android::bluetooth::le::LeConnectionOriginType origin_type, + android::bluetooth::le::LeConnectionType connection_type, + android::bluetooth::le::LeConnectionState transaction_state, + std::vector>& argument_list) { + bluetooth::metrics::MetricsCollector::GetLEConnectionMetricsCollector()->AddStateChangedEvent( + address, origin_type, connection_type, transaction_state, argument_list); +} + +void LogMetricBluetoothLEConnection(os::LEConnectionSessionOptions session_options) { + int metric_id = 0; + if (!session_options.remote_address.IsEmpty()) { + metric_id = MetricIdManager::GetInstance().AllocateId(session_options.remote_address); + } + int ret = stats_write( + BLUETOOTH_LE_SESSION_CONNECTED, + session_options.acl_connection_state, + session_options.origin_type, + session_options.transaction_type, + session_options.transaction_state, + session_options.latency, + metric_id, + session_options.app_uid, + session_options.acl_latency, + session_options.status, + session_options.is_cancelled); + + if (ret < 0) { + LOG_WARN( + "Failed BluetoothLeSessionConnected - Address: %s, ACL Connection State: %s, Origin Type: " + "%s", + ADDRESS_TO_LOGGABLE_CSTR(session_options.remote_address), + common::ToHexString(session_options.acl_connection_state).c_str(), + common::ToHexString(session_options.origin_type).c_str()); + } +} + } // namespace os } // namespace bluetooth + diff --git a/system/gd/os/host/metrics.cc b/system/gd/os/host/metrics.cc index a163b8c30aa..3de27662e8a 100644 --- a/system/gd/os/host/metrics.cc +++ b/system/gd/os/host/metrics.cc @@ -122,5 +122,15 @@ void LogMetricBluetoothRemoteSupportedFeatures( const Address& address, uint32_t page, uint64_t features, uint32_t connection_handle) {} void LogMetricBluetoothCodePathCounterMetrics(int32_t key, int64_t count) {} + +void LogMetricBluetoothLEConnectionMetricEvent( + const Address& address, + android::bluetooth::le::LeConnectionOriginType origin_type, + android::bluetooth::le::LeConnectionType connection_type, + android::bluetooth::le::LeConnectionState transaction_state, + std::vector>& argument_list) {} + +void LogMetricBluetoothLEConnection(os::LEConnectionSessionOptions session_options) {} + } // namespace os } // namespace bluetooth diff --git a/system/gd/os/linux/metrics.cc b/system/gd/os/linux/metrics.cc index d70cb3c0275..fb0a26b42e7 100644 --- a/system/gd/os/linux/metrics.cc +++ b/system/gd/os/linux/metrics.cc @@ -123,5 +123,12 @@ void LogMetricBluetoothRemoteSupportedFeatures( void LogMetricBluetoothCodePathCounterMetrics(int32_t key, int64_t count) {} +void LogMetricBluetoothLEConnectionMetricEvent( + const Address& address, + android::bluetooth::le::LeConnectionOriginType origin_type, + android::bluetooth::le::LeConnectionType connection_type, + android::bluetooth::le::LeConnectionState transaction_state, + std::vector>& argument_list) {} + } // namespace os } // namespace bluetooth diff --git a/system/gd/os/metrics.h b/system/gd/os/metrics.h index 27b6aefb874..e16919fa5aa 100644 --- a/system/gd/os/metrics.h +++ b/system/gd/os/metrics.h @@ -20,6 +20,7 @@ #include #include +#include #include "hci/address.h" @@ -294,6 +295,47 @@ void LogMetricBluetoothRemoteSupportedFeatures( const hci::Address& address, uint32_t page, uint64_t features, uint32_t connection_handle); void LogMetricBluetoothCodePathCounterMetrics(int32_t key, int64_t count); -} // namespace os +using android::bluetooth::le::LeAclConnectionState; +using android::bluetooth::le::LeConnectionOriginType; +using android::bluetooth::le::LeConnectionType; +using android::bluetooth::le::LeConnectionState; +// Adding options +struct LEConnectionSessionOptions { + // Contains the state of the LE-ACL Connection + LeAclConnectionState acl_connection_state = LeAclConnectionState::LE_ACL_UNSPECIFIED; + // Origin of the transaction + LeConnectionOriginType origin_type = LeConnectionOriginType::ORIGIN_UNSPECIFIED; + // Connection Type + LeConnectionType transaction_type = LeConnectionType::CONNECTION_TYPE_UNSPECIFIED; + // Transaction State + LeConnectionState transaction_state = LeConnectionState::STATE_UNSPECIFIED; + // Latency of the entire transaction + int64_t latency = 0; + // Address of the remote device + hci::Address remote_address = hci::Address::kEmpty; + // UID associated with the device + int app_uid = 0; + // Latency of the ACL Transaction + int64_t acl_latency = 0; + // Contains the error code associated with the ACL Connection if failed + android::bluetooth::hci::StatusEnum status = android::bluetooth::hci::StatusEnum::STATUS_UNKNOWN; + // Cancelled connection + bool is_cancelled = false; +}; + +// Argument Type +enum ArgumentType { GATT_IF, L2CAP_PSM, L2CAP_CID, APP_UID, ACL_STATUS_CODE }; +void LogMetricBluetoothLEConnectionMetricEvent( + const hci::Address& address, + LeConnectionOriginType origin_type, + LeConnectionType connection_type, + LeConnectionState transaction_state, + std::vector>& argument_list); + +// Upload LE Session +void LogMetricBluetoothLEConnection(os::LEConnectionSessionOptions session_options); + +} // namespace os + // } // namespace bluetooth diff --git a/system/main/shim/metrics_api.cc b/system/main/shim/metrics_api.cc index 9637ff49297..5ef1bd16a42 100644 --- a/system/main/shim/metrics_api.cc +++ b/system/main/shim/metrics_api.cc @@ -155,5 +155,17 @@ bool CountCounterMetrics(int32_t key, int64_t count) { } return counter_metrics->Count(key, count); } + +void LogMetricBluetoothLEConnectionMetricEvent( + const RawAddress& raw_address, + android::bluetooth::le::LeConnectionOriginType origin_type, + android::bluetooth::le::LeConnectionType connection_type, + android::bluetooth::le::LeConnectionState transaction_state, + std::vector> argument_list) { + + Address address = bluetooth::ToGdAddress(raw_address); + bluetooth::os::LogMetricBluetoothLEConnectionMetricEvent(address, origin_type, connection_type, transaction_state, argument_list); +} + } // namespace shim } // namespace bluetooth diff --git a/system/main/shim/metrics_api.h b/system/main/shim/metrics_api.h index 6661d6a9168..2540fbdc12e 100644 --- a/system/main/shim/metrics_api.h +++ b/system/main/shim/metrics_api.h @@ -18,9 +18,11 @@ #include #include +#include #include #include "types/raw_address.h" +#include "metrics/metrics_state.h" namespace bluetooth { namespace shim { @@ -220,5 +222,12 @@ void LogMetricManufacturerInfo( const std::string& software_version); bool CountCounterMetrics(int32_t key, int64_t count); + +void LogMetricBluetoothLEConnectionMetricEvent( + const RawAddress& raw_address, + android::bluetooth::le::LeConnectionOriginType origin_type, + android::bluetooth::le::LeConnectionType connection_type, + android::bluetooth::le::LeConnectionState transaction_state, + std::vector> argument_list); } // namespace shim } // namespace bluetooth diff --git a/system/stack/acl/btm_acl.cc b/system/stack/acl/btm_acl.cc index 9788f02af28..06368dfa88e 100644 --- a/system/stack/acl/btm_acl.cc +++ b/system/stack/acl/btm_acl.cc @@ -44,12 +44,14 @@ #include "device/include/controller.h" #include "device/include/device_iot_config.h" #include "device/include/interop.h" +#include "gd/metrics/metrics_state.h" #include "include/l2cap_hci_link_interface.h" #include "main/shim/acl_api.h" #include "main/shim/btm_api.h" #include "main/shim/controller.h" #include "main/shim/dumpsys.h" #include "main/shim/l2c_api.h" +#include "main/shim/metrics_api.h" #include "main/shim/shim.h" #include "os/parameter_provider.h" #include "osi/include/allocator.h" @@ -74,6 +76,7 @@ #include "stack/include/sco_hci_link_interface.h" #include "types/hci_role.h" #include "types/raw_address.h" +#include "os/metrics.h" #ifndef PROPERTY_LINK_SUPERVISION_TIMEOUT #define PROPERTY_LINK_SUPERVISION_TIMEOUT \ @@ -2876,6 +2879,15 @@ bool acl_create_le_connection_with_id(uint8_t id, const RawAddress& bd_addr, return false; } + // argument list + auto argument_list = std::vector>(); + + bluetooth::shim::LogMetricBluetoothLEConnectionMetricEvent( + bd_addr, android::bluetooth::le::LeConnectionOriginType::ORIGIN_NATIVE, + android::bluetooth::le::LeConnectionType::CONNECTION_TYPE_LE_ACL, + android::bluetooth::le::LeConnectionState::STATE_LE_ACL_START, + argument_list); + bluetooth::shim::ACL_AcceptLeConnectionFrom(address_with_type, /* is_direct */ true); return true; diff --git a/system/test/mock/mock_main_shim_metrics_api.cc b/system/test/mock/mock_main_shim_metrics_api.cc index ae8e3feef24..fac54d210f5 100644 --- a/system/test/mock/mock_main_shim_metrics_api.cc +++ b/system/test/mock/mock_main_shim_metrics_api.cc @@ -184,6 +184,16 @@ void bluetooth::shim::LogMetricManufacturerInfo( bool bluetooth::shim::CountCounterMetrics(int32_t key, int64_t count) { inc_func_call_count(__func__); return false; + +} +void bluetooth::shim::LogMetricBluetoothLEConnectionMetricEvent( + const RawAddress& raw_address, + android::bluetooth::le::LeConnectionOriginType origin_type, + android::bluetooth::le::LeConnectionType connection_type, + android::bluetooth::le::LeConnectionState transaction_state, + std::vector> argument_list) { + mock_function_count_map[__func__]++; + // test::mock::main_shim_metrics_api::LogMetricBluetoothLEConnectionMetricEvent(raw_address, origin_type, connection_type, transaction_state, argument_list); } // END mockcify generation diff --git a/system/test/mock/mock_main_shim_metrics_api.h b/system/test/mock/mock_main_shim_metrics_api.h index 646e463ba56..c8b850ecedd 100644 --- a/system/test/mock/mock_main_shim_metrics_api.h +++ b/system/test/mock/mock_main_shim_metrics_api.h @@ -39,6 +39,8 @@ #include "main/shim/helpers.h" #include "main/shim/metrics_api.h" #include "types/raw_address.h" +#include + // Mocked compile conditionals, if any #ifndef UNUSED_ATTR @@ -297,6 +299,40 @@ struct LogMetricManufacturerInfo { }; extern struct LogMetricManufacturerInfo LogMetricManufacturerInfo; +// Name: LogMetricBluetoothLEConnectionMetricEvent +// Params: const RawAddress& raw_address, +// android::bluetooth::le::LeConnectionOriginType origin_type, +// android::bluetooth::le::LeConnectionType connection_type, +// android::bluetooth::le::LeConnectionState transaction_state, +// std::vector> +// argument_list +struct LogMetricBluetoothLEConnectionMetricEvent { + std::function> + argument_list)> + body{[](const RawAddress& raw_address, + android::bluetooth::le::LeConnectionOriginType origin_type, + android::bluetooth::le::LeConnectionType connection_type, + android::bluetooth::le::LeConnectionState + transaction_state, + std::vector> + argument_list) {}}; + void operator()( + const RawAddress& raw_address, + android::bluetooth::le::LeConnectionOriginType origin_type, + android::bluetooth::le::LeConnectionType connection_type, + android::bluetooth::le::LeConnectionState transaction_state, + std::vector> + argument_list) { + body(raw_address, origin_type, connection_type, transaction_state, + argument_list); + }; +}; + } // namespace main_shim_metrics_api } // namespace mock } // namespace test -- GitLab From 537ecc462d721b077b83c7b9c51a2f4f90491008 Mon Sep 17 00:00:00 2001 From: William Escande Date: Fri, 17 Mar 2023 12:16:41 -0700 Subject: [PATCH 0009/2405] Mock static initialization order 26 cpp static order initialization is not guarantee. In order to avoid the mess, we need to have a lazy init schema. replace last internal usage Bug: 265217208 Ignore-AOSP-First: no such code on AOSP Test: atest --host Change-Id: I921ebd6bc5dc3865054b4752a4fc064eb76eb0eb --- system/test/mock/mock_main_shim_metrics_api.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/system/test/mock/mock_main_shim_metrics_api.cc b/system/test/mock/mock_main_shim_metrics_api.cc index fac54d210f5..4be7bd0e290 100644 --- a/system/test/mock/mock_main_shim_metrics_api.cc +++ b/system/test/mock/mock_main_shim_metrics_api.cc @@ -192,7 +192,7 @@ void bluetooth::shim::LogMetricBluetoothLEConnectionMetricEvent( android::bluetooth::le::LeConnectionType connection_type, android::bluetooth::le::LeConnectionState transaction_state, std::vector> argument_list) { - mock_function_count_map[__func__]++; + inc_func_call_count(__func__); // test::mock::main_shim_metrics_api::LogMetricBluetoothLEConnectionMetricEvent(raw_address, origin_type, connection_type, transaction_state, argument_list); } -- GitLab From fc23bb6fa440ee9fa821cf32df05adf4d741300e Mon Sep 17 00:00:00 2001 From: Ayushi Khopkar Date: Fri, 17 Mar 2023 17:27:33 +0530 Subject: [PATCH 0010/2405] Updated fuzz_config in Android.bp file Added new fields in fuzz_config like - hotlists, description, vector, service_privilege, users, fuzzed_code_usage, etc. Bug: 271384401 Test: Build the updated fuzz targets Change-Id: I8863fe758d183f5378362828dd7026f04e51d0af --- system/audio_hal_interface/fuzzer/Android.bp | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/system/audio_hal_interface/fuzzer/Android.bp b/system/audio_hal_interface/fuzzer/Android.bp index ae57c74ffa8..0cea97a7e5d 100644 --- a/system/audio_hal_interface/fuzzer/Android.bp +++ b/system/audio_hal_interface/fuzzer/Android.bp @@ -105,6 +105,14 @@ cc_defaults { fuzz_config: { cc: ["android-bluetooth-security@google.com"], componentid: 27441, + hotlists: [ + "4593311", + ], + description: "The fuzzer targets the APIs of libbt-audio-hal-interface", + vector: "local_no_privileges_required", + service_privilege: "privileged", + users: "multi_user", + fuzzed_code_usage: "shipped", }, } -- GitLab From 0af04b20b12df306791fe90d3d7c1e93c59690eb Mon Sep 17 00:00:00 2001 From: Ayushi Khopkar Date: Fri, 17 Mar 2023 17:54:50 +0530 Subject: [PATCH 0011/2405] Updated fuzz_config in Android.bp file Added new fields in fuzz_config like - hotlists, description, vector, service_privilege, users, fuzzed_code_usage, etc. Bug: 271384401 Test: Build the updated fuzz targets Change-Id: If369b329ee8c39873aa23ebe9dab05ffe40ee01a --- system/btcore/fuzzer/Android.bp | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/system/btcore/fuzzer/Android.bp b/system/btcore/fuzzer/Android.bp index 4ab98e6c06d..9ed4589f380 100644 --- a/system/btcore/fuzzer/Android.bp +++ b/system/btcore/fuzzer/Android.bp @@ -65,6 +65,14 @@ cc_defaults { fuzz_config: { cc: ["android-bluetooth-security@google.com"], componentid: 27441, + hotlists: [ + "4593311", + ], + description: "The fuzzer targets the APIs of libbtcore", + vector: "local_no_privileges_required", + service_privilege: "privileged", + users: "multi_user", + fuzzed_code_usage: "shipped", }, } -- GitLab From e1cc6ed49df7db13f25ffc878bb89d5698e9708a Mon Sep 17 00:00:00 2001 From: Ayushi Khopkar Date: Mon, 20 Mar 2023 15:58:45 +0530 Subject: [PATCH 0012/2405] Updated fuzz_config in Android.bp file Added new fields in fuzz_config like - hotlists, description, vector, service_privilege, users, fuzzed_code_usage, etc. Bug: 271384401 Test: Build btdevice_esco_fuzzer Change-Id: I478348cd0b8e8fdc6a7a07561cfc187a04f036a8 --- system/device/fuzzer/Android.bp | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/system/device/fuzzer/Android.bp b/system/device/fuzzer/Android.bp index ab9039b07ce..a299cc496d0 100644 --- a/system/device/fuzzer/Android.bp +++ b/system/device/fuzzer/Android.bp @@ -49,5 +49,13 @@ cc_fuzz { fuzz_config: { cc: ["android-bluetooth-security@google.com"], componentid: 27441, + hotlists: [ + "4593311", + ], + description: "The fuzzer targets the APIs of libbtdevice library", + vector: "local_no_privileges_required", + service_privilege: "privileged", + users: "multi_user", + fuzzed_code_usage: "shipped", }, } -- GitLab From 51ac8ed919976c9a17364548a73aa0611e88c629 Mon Sep 17 00:00:00 2001 From: Bill Yi Date: Tue, 28 Mar 2023 19:31:47 -0700 Subject: [PATCH 0013/2405] Import translations. DO NOT MERGE ANYWHERE Auto-generated-cl: translation import Change-Id: I6de8249a6b720dc487a248835c1c56129a39af5e --- android/app/res/values-am/strings_pbap.xml | 6 ++---- android/app/res/values-eu/strings_pbap.xml | 6 ++---- android/app/res/values-fr-rCA/strings_pbap.xml | 6 ++---- android/app/res/values-ta/strings_pbap.xml | 6 ++---- 4 files changed, 8 insertions(+), 16 deletions(-) diff --git a/android/app/res/values-am/strings_pbap.xml b/android/app/res/values-am/strings_pbap.xml index e3f1b4e6ebd..89da5d01b13 100644 --- a/android/app/res/values-am/strings_pbap.xml +++ b/android/app/res/values-am/strings_pbap.xml @@ -13,8 +13,6 @@ "የእኔ ስም" "000000" "ብሉቱዝ የእውቂያ መጋራት" - - - - + "የስልክ ደብተር የላቀ ባህሪ ይደገፋል" + "የላቀ የስልክ ደብተር ባህሪን ዳግም ያጣምሩ" diff --git a/android/app/res/values-eu/strings_pbap.xml b/android/app/res/values-eu/strings_pbap.xml index e07ffb98bf2..bd08027958e 100644 --- a/android/app/res/values-eu/strings_pbap.xml +++ b/android/app/res/values-eu/strings_pbap.xml @@ -13,8 +13,6 @@ "Nire izena" "000000" "Kontaktuak Bluetooth bidez partekatzeko aukera" - - - - + "Agendaren eginbide aurreratua onartzen da" + "Agendaren eginbide aurreratua erabiltzeko, parekatu berriro" diff --git a/android/app/res/values-fr-rCA/strings_pbap.xml b/android/app/res/values-fr-rCA/strings_pbap.xml index b35cc6e9e35..59a768fc548 100644 --- a/android/app/res/values-fr-rCA/strings_pbap.xml +++ b/android/app/res/values-fr-rCA/strings_pbap.xml @@ -13,8 +13,6 @@ "Mon nom" "000000" "Partage de contacts par Bluetooth" - - - - + "Fonctionnalité avancée du répertoire téléphonique prise en charge" + "Réassocier pour la fonctionnalité avancée du répertoire téléphonique" diff --git a/android/app/res/values-ta/strings_pbap.xml b/android/app/res/values-ta/strings_pbap.xml index b0039078766..62da16e3853 100644 --- a/android/app/res/values-ta/strings_pbap.xml +++ b/android/app/res/values-ta/strings_pbap.xml @@ -13,8 +13,6 @@ "எனது பெயர்" "000000" "புளூடூத் தொடர்புப் பகிர்தல்" - - - - + "ஃபோன்புக் தொடர்பான மேம்பட்ட அம்சம் ஆதரிக்கப்படுகிறது" + "மேம்பட்ட ஃபோன்புக் அம்சத்திற்காக மீண்டும் இணைத்தல்" -- GitLab From 350054d142981f8a24a5a98189ca9a7550685646 Mon Sep 17 00:00:00 2001 From: hoax Date: Fri, 31 Mar 2023 08:23:29 +0000 Subject: [PATCH 0014/2405] gd: stack: use new start/stop timeout properties Watches take longer to finish downloading firmware when the system is busy. Sometimes FW download takes more than 3 seconds, GD stack timeouts should be increased accordingly. Add two new props bluetooth.gd.start_timeout and bluetooth.gd.stop_timeout, then these props can be adjusted by targets. Tag: #stability Bug: 271859293 Test: Run the following script for 3 hours and check if there is no BT timeout issues Script: while true do adb shell su 0 svc bluetooth enable sleep 10 adb shell su 0 svc bluetooth disable sleep 5 done Change-Id: Icff5db9d6baf24ccfb0237605a62fc08dbc25816 --- system/gd/stack_manager.cc | 14 ++++++++++++-- system/gd/stack_manager.h | 1 + 2 files changed, 13 insertions(+), 2 deletions(-) diff --git a/system/gd/stack_manager.cc b/system/gd/stack_manager.cc index a2afa80522d..760ef841e76 100644 --- a/system/gd/stack_manager.cc +++ b/system/gd/stack_manager.cc @@ -25,6 +25,7 @@ #include "module.h" #include "os/handler.h" #include "os/log.h" +#include "os/system_properties.h" #include "os/thread.h" #include "os/wakelock_manager.h" @@ -45,7 +46,8 @@ void StackManager::StartUp(ModuleList* modules, Thread* stack_thread) { handler_->Post(common::BindOnce(&StackManager::handle_start_up, common::Unretained(this), modules, stack_thread, std::move(promise))); - auto init_status = future.wait_for(std::chrono::seconds(3)); + auto init_status = future.wait_for(std::chrono::milliseconds( + get_gd_stack_timeout_ms(/* is_start = */ true))); WakelockManager::Get().Release(); @@ -71,7 +73,8 @@ void StackManager::ShutDown() { auto future = promise.get_future(); handler_->Post(common::BindOnce(&StackManager::handle_shut_down, common::Unretained(this), std::move(promise))); - auto stop_status = future.wait_for(std::chrono::seconds(5)); + auto stop_status = future.wait_for(std::chrono::milliseconds( + get_gd_stack_timeout_ms(/* is_start = */ false))); WakelockManager::Get().Release(); WakelockManager::Get().CleanUp(); @@ -92,4 +95,11 @@ void StackManager::handle_shut_down(std::promise promise) { promise.set_value(); } +std::chrono::milliseconds StackManager::get_gd_stack_timeout_ms(bool is_start) { + auto gd_timeout = os::GetSystemPropertyUint32( + is_start ? "bluetooth.gd.start_timeout" : "bluetooth.gd.stop_timeout", + /* default_value = */ is_start ? 3000 : 5000); + return std::chrono::milliseconds(gd_timeout); +} + } // namespace bluetooth diff --git a/system/gd/stack_manager.h b/system/gd/stack_manager.h index c09a7f6a36d..85b0721ea70 100644 --- a/system/gd/stack_manager.h +++ b/system/gd/stack_manager.h @@ -44,6 +44,7 @@ class StackManager { void handle_start_up(ModuleList* modules, os::Thread* stack_thread, std::promise promise); void handle_shut_down(std::promise promise); + static std::chrono::milliseconds get_gd_stack_timeout_ms(bool is_start); }; } // namespace bluetooth -- GitLab From 008e83678cbe25808f91636cbeffb8eb052005e6 Mon Sep 17 00:00:00 2001 From: Xuan Xing Date: Fri, 17 Mar 2023 22:12:09 +0000 Subject: [PATCH 0015/2405] Adding a Bluetooth SDP stack fuzzer Ignore-AOSP-First: Internal fuzzers Test: Manually build the SDP fuzzer Bug: 274525374 Change-Id: Id12dd5d922f3eb71081413323b1e22bb1780c2df --- system/stack/Android.bp | 80 +++++++++ system/stack/fuzzers/sdp_fuzzer.cc | 252 +++++++++++++++++++++++++++++ 2 files changed, 332 insertions(+) create mode 100644 system/stack/fuzzers/sdp_fuzzer.cc diff --git a/system/stack/Android.bp b/system/stack/Android.bp index 59292bb4941..49f9454734c 100644 --- a/system/stack/Android.bp +++ b/system/stack/Android.bp @@ -287,6 +287,86 @@ cc_library_static { min_sdk_version: "Tiramisu", } +cc_defaults { + name: "btstack_fuzzer_default", + host_supported: true, + cflags: [ + "-Wall", + "-Wextra", + "-Werror", + // Mocked components have too many unused parameters + "-Wno-unused-parameter", + "-DHAS_NO_BDROID_BUILDCFG", + ], + include_dirs: [ + "packages/modules/Bluetooth/system", + "packages/modules/Bluetooth/system/gd", + "packages/modules/Bluetooth/system/include", + "packages/modules/Bluetooth/system/internal_include", + "packages/modules/Bluetooth/system/stack/include", + "packages/modules/Bluetooth/system/test/common", + "packages/modules/Bluetooth/system/types", + ], + static_libs: [ + "libchrome", + ], + target: { + darwin: { + enabled: false, + }, + android: { + shared_libs: [ + "libcutils", + "libutils", + ], + }, + host: { + cflags: [ + "-DOS_GENERIC", + ], + }, + }, +} + +cc_fuzz { + name: "sdp-fuzzer", + defaults: [ + "btstack_fuzzer_default", + "fluoride_defaults_fuzzable", + ], + include_dirs: [ + "packages/modules/Bluetooth/system/stack/btm", + ], + srcs: [ + ":LegacyStackSdp", + ":TestCommonLogMsg", + ":TestCommonMockFunctions", + ":TestFakeOsi", + ":TestMockBtif", + ":TestMockDevice", + ":TestMockGdOsLoggingLogRedaction", + ":TestMockStackL2cap", + ":TestMockStackMetrics", + ":TestMockStackBtm", + "fuzzers/sdp_fuzzer.cc", + ], + fuzz_config: { + cc: [ + "android-bluetooth-security@google.com", + "android-security-assurance-redteam@google.com", + ], + componentid: 27441, + hotlists: [ + "4810445", + "3705175", + ], + acknowledgement: [ + "Android Red Team of Google", + "Android Bluetooth Team of Google", + ], + }, +} + // Bluetooth stack unit tests for target cc_test { name: "net_test_stack", diff --git a/system/stack/fuzzers/sdp_fuzzer.cc b/system/stack/fuzzers/sdp_fuzzer.cc new file mode 100644 index 00000000000..317de1ebb69 --- /dev/null +++ b/system/stack/fuzzers/sdp_fuzzer.cc @@ -0,0 +1,252 @@ +/* + * Copyright 2022 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include + +#include +#include +#include + +#include "osi/include/allocator.h" +#include "stack/include/bt_hdr.h" +#include "stack/include/sdp_api.h" +#include "stack/include/sdpdefs.h" +#include "stack/sdp/sdpint.h" +#include "test/fake/fake_osi.h" +#include "test/mock/mock_btif_config.h" +#include "test/mock/mock_stack_l2cap_api.h" +#include "types/bluetooth/uuid.h" + +namespace { + +#define SDP_DB_SIZE 0x10000 + +constexpr uint16_t kDummyCID = 0x1234; +constexpr uint16_t kDummyPSM = 0x7788; +constexpr uint8_t kDummyID = 0x99; +constexpr uint8_t kDummyAddr[] = {0x11, 0x22, 0x33, 0x44, 0x55, 0x66}; + +// Set up default callback structure +tL2CAP_APPL_INFO cb_info = { + .pL2CA_ConnectInd_Cb = [](const RawAddress& bd_addr, uint16_t lcid, + uint16_t psm, + uint8_t id) {}, // tL2CA_CONNECT_IND_CB + .pL2CA_ConnectCfm_Cb = [](uint16_t lcid, + uint16_t result) {}, // tL2CA_CONNECT_CFM_CB + .pL2CA_ConfigInd_Cb = [](uint16_t lcid, + tL2CAP_CFG_INFO* p_cfg) {}, // tL2CA_CONFIG_IND_CB + .pL2CA_ConfigCfm_Cb = [](uint16_t lcid, uint16_t initiator, + tL2CAP_CFG_INFO* p_cfg) {}, // tL2CA_CONFIG_CFM_CB + .pL2CA_DisconnectInd_Cb = + [](uint16_t lcid, bool should_ack) {}, // tL2CA_DISCONNECT_IND_CB + .pL2CA_DisconnectCfm_Cb = + [](uint16_t lcid, uint16_t result) {}, // tL2CA_DISCONNECT_CFM_CB + .pL2CA_DataInd_Cb = [](uint16_t lcid, + BT_HDR* data) {}, // tL2CA_DATA_IND_CB + .pL2CA_CongestionStatus_Cb = + [](uint16_t lcid, bool is_congested) {}, // tL2CA_CONGESTION_STATUS_CB + .pL2CA_TxComplete_Cb = [](uint16_t lcid, + uint16_t num_sdu) {}, // tL2CA_TX_COMPLETE_CB + .pL2CA_Error_Cb = [](uint16_t lcid, + uint16_t error_type) {}, // tL2CA_ERROR_CB + .pL2CA_CreditBasedConnectInd_Cb = + [](const RawAddress& bdaddr, std::vector& lcids, uint16_t psm, + uint16_t peer_mtu, + uint8_t identifier) {}, // tL2CA_CREDIT_BASED_CONNECT_IND_CB + .pL2CA_CreditBasedConnectCfm_Cb = + [](const RawAddress& bdaddr, uint16_t lcid, uint16_t peer_mtu, + uint16_t result) {}, // tL2CA_CREDIT_BASED_CONNECT_CFM_CB + .pL2CA_CreditBasedReconfigCompleted_Cb = + [](const RawAddress& bdaddr, uint16_t lcid, bool is_local_cfg, + tL2CAP_LE_CFG_INFO* p_cfg) { + }, // tL2CA_CREDIT_BASED_RECONFIG_COMPLETED_CB + .pL2CA_CreditBasedCollisionInd_Cb = + [](const RawAddress& bdaddr) {}, // tL2CA_CREDIT_BASED_COLLISION_IND_CB +}; + +class FakeL2cap { + public: + FakeL2cap() { + test::mock::stack_l2cap_api::L2CA_ConnectReq.body = + [](uint16_t psm, const RawAddress& raw_address) { return kDummyCID; }; + test::mock::stack_l2cap_api::L2CA_ConnectReq2.body = + [](uint16_t psm, const RawAddress& p_bd_addr, uint16_t sec_level) { + return L2CA_ConnectReq(psm, p_bd_addr); + }; + test::mock::stack_l2cap_api::L2CA_DataWrite.body = [](uint16_t cid, + BT_HDR* p_data) { + auto len = p_data->len; + osi_free(p_data); + return (uint8_t)len; + }; + test::mock::stack_l2cap_api::L2CA_DisconnectReq.body = [](uint16_t lcid) { + return true; + }; + test::mock::stack_l2cap_api::L2CA_Register2.body = + [](uint16_t psm, const tL2CAP_APPL_INFO& p_cb_info, bool enable_snoop, + tL2CAP_ERTM_INFO* p_ertm_info, uint16_t my_mtu, + uint16_t required_remote_mtu, uint16_t sec_level) { + cb_info = p_cb_info; + return psm; + }; + } + + ~FakeL2cap() { + test::mock::stack_l2cap_api::L2CA_ConnectReq = {}; + test::mock::stack_l2cap_api::L2CA_ConnectReq2 = {}; + test::mock::stack_l2cap_api::L2CA_DataWrite = {}; + test::mock::stack_l2cap_api::L2CA_DisconnectReq = {}; + test::mock::stack_l2cap_api::L2CA_Register2 = {}; + } +}; + +class FakeBtifConfig { + public: + FakeBtifConfig() { + test::mock::btif_config::btif_config_set_bin.body = + [](const std::string&, const std::string&, const uint8_t*, size_t) { + // This function is not properly mocked. The abort here allows us to + // catch any cases using this mock. + abort(); + return true; + }; + test::mock::btif_config::btif_config_set_int.body = + [](const std::string& section, const std::string& key, int value) { + // This function is not properly mocked. The abort here allows us to + // catch any cases using this mock. + abort(); + return true; + }; + } + + ~FakeBtifConfig() { + test::mock::btif_config::btif_config_set_bin = {}; + test::mock::btif_config::btif_config_set_int = {}; + } +}; + +class Fakes { + public: + test::fake::FakeOsi fake_osi; + FakeL2cap fake_l2cap; + FakeBtifConfig fake_btif_config; +}; + +} // namespace + +static void FuzzAsServer(const uint8_t* data, size_t size) { + FuzzedDataProvider fdp(data, size); + std::vector> attrs; + + sdp_init(); + auto rec_num = fdp.ConsumeIntegralInRange(0, 10); + for (uint8_t i = 0; i < rec_num; i++) { + auto handle = SDP_CreateRecord(); + auto attr_num = fdp.ConsumeIntegralInRange(0, 10); + for (uint8_t s = 0; s < attr_num; s++) { + auto id = (i == 0) ? ATTR_ID_BT_PROFILE_DESC_LIST + : fdp.ConsumeIntegral(); + auto type = fdp.ConsumeIntegral(); + auto len = fdp.ConsumeIntegralInRange(1, 512); + auto data = fdp.ConsumeBytes(len); + + if (data.size() == 0) { + break; + } + + attrs.push_back(data); + SDP_AddAttribute(handle, id, type, data.size(), data.data()); + } + } + + cb_info.pL2CA_ConnectInd_Cb(RawAddress(kDummyAddr), kDummyCID, kDummyPSM, + kDummyID); + + tL2CAP_CFG_INFO cfg = {}; + cb_info.pL2CA_ConfigCfm_Cb(kDummyCID, 0, &cfg); + + while (fdp.remaining_bytes() > 0) { + auto size = fdp.ConsumeIntegralInRange(0, 1024); + auto bytes = fdp.ConsumeBytes(size); + BT_HDR* hdr = (BT_HDR*)osi_calloc(sizeof(BT_HDR) + bytes.size()); + hdr->len = bytes.size(); + std::copy(bytes.cbegin(), bytes.cend(), hdr->data); + cb_info.pL2CA_DataInd_Cb(kDummyCID, hdr); + } + + cb_info.pL2CA_DisconnectInd_Cb(kDummyCID, false); + sdp_free(); +} + +static void FuzzAsClient(const uint8_t* data, size_t size) { + FuzzedDataProvider fdp(data, size); + std::shared_ptr p_db( + (tSDP_DISCOVERY_DB*)malloc(SDP_DB_SIZE), free); + + std::vector init_uuids; + std::vector init_attrs; + + sdp_init(); + + uint8_t num_uuid = + fdp.ConsumeIntegralInRange(0, SDP_MAX_UUID_FILTERS); + uint8_t num_attr = + fdp.ConsumeIntegralInRange(0, SDP_MAX_ATTR_FILTERS); + + for (uint8_t i = 0; i < num_uuid; i++) { + init_uuids.push_back( + bluetooth::Uuid::From16Bit(fdp.ConsumeIntegral())); + } + + for (uint8_t i = 0; i < num_attr; i++) { + init_attrs.push_back(fdp.ConsumeIntegral()); + } + + SDP_InitDiscoveryDb(p_db.get(), SDP_DB_SIZE, init_uuids.size(), + init_uuids.data(), init_attrs.size(), init_attrs.data()); + + bool is_di_discover = fdp.ConsumeBool(); + if (is_di_discover) { + SDP_ServiceSearchRequest(kDummyAddr, p_db.get(), [](tSDP_RESULT result) {}); + } else { + SDP_ServiceSearchAttributeRequest(kDummyAddr, p_db.get(), + [](tSDP_RESULT result) {}); + } + cb_info.pL2CA_ConnectCfm_Cb(kDummyCID, L2CAP_CONN_OK); + + tL2CAP_CFG_INFO cfg = {}; + cb_info.pL2CA_ConfigCfm_Cb(kDummyCID, 0, &cfg); + + while (fdp.remaining_bytes() > 0) { + auto size = fdp.ConsumeIntegralInRange(0, 1024); + auto bytes = fdp.ConsumeBytes(size); + BT_HDR* hdr = (BT_HDR*)osi_calloc(sizeof(BT_HDR) + bytes.size()); + hdr->len = bytes.size(); + std::copy(bytes.cbegin(), bytes.cend(), hdr->data); + cb_info.pL2CA_DataInd_Cb(kDummyCID, hdr); + } + + cb_info.pL2CA_DisconnectInd_Cb(kDummyCID, false); + sdp_free(); +} + +extern "C" int LLVMFuzzerTestOneInput(const uint8_t* Data, size_t Size) { + auto fakes = std::make_unique(); + + FuzzAsServer(Data, Size); + FuzzAsClient(Data, Size); + return 0; +} -- GitLab From 73671af2b199d39a6e15e78cc827a5bb2247e46c Mon Sep 17 00:00:00 2001 From: Bill Yi Date: Tue, 11 Apr 2023 13:37:32 -0700 Subject: [PATCH 0016/2405] Import translations. DO NOT MERGE ANYWHERE Auto-generated-cl: translation import Change-Id: I3bd01ddbe54604f8c54f067a2afebf0bc0867f97 --- android/app/res/values-or/strings.xml | 8 ++++---- android/app/res/values-te/strings.xml | 4 ++-- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/android/app/res/values-or/strings.xml b/android/app/res/values-or/strings.xml index 291587784be..411aa65c3aa 100644 --- a/android/app/res/values-or/strings.xml +++ b/android/app/res/values-or/strings.xml @@ -35,7 +35,7 @@ "ଆସୁଥିବା ଫାଇଲକୁ ଗ୍ରହଣ କରିବେ?" "ଅସ୍ୱୀକାର" "ସ୍ୱୀକାର କରନ୍ତୁ" - "ଠିକ୍‌ ଅଛି" + "ଠିକ ଅଛି" "\"%1$s\"ଙ୍କଠାରୁ ଆସୁଥିବା ଫାଇଲ୍‌ ସ୍ୱୀକାର କରୁଥିବାବେଳେ ସମୟ ସମାପ୍ତ ହୋଇଗଲା" "ଆସୁଥିବା ଫାଇଲ୍‌" "%1$s ଏକ ଫାଇଲ୍ ପଠାଇବାକୁ ପ୍ରସ୍ତୁତ ଅଛନ୍ତି: %2$s" @@ -60,18 +60,18 @@ "ଫାଇଲ୍‌ ପ୍ରାପ୍ତ ହେଲା ନାହିଁ" "ଫାଇଲ୍‌: %1$s" "କାରଣ: %1$s" - "ଠିକ୍‌ ଅଛି" + "ଠିକ ଅଛି" "ଫାଇଲ୍‌ ପ୍ରାପ୍ତ ହେଲା" "ଖୋଲନ୍ତୁ" "ପ୍ରାପ୍ତକର୍ତ୍ତା: \"%1$s\"" "ଫାଇଲ୍‌ ପ୍ରକାର: %1$s (%2$s)" "ଫାଇଲ୍‌ ପଠାଯାଉଛି…" "ଫାଇଲ୍‌ ପଠାଗଲା" - "ଠିକ୍‌ ଅଛି" + "ଠିକ ଅଛି" "ଫାଇଲ୍‌ \"%1$s\"ଙ୍କୁ ପଠାଯାଇନଥିଲା।" "ଫାଇଲ୍‌: %1$s" "ବନ୍ଦ କରନ୍ତୁ" - "ଠିକ୍‌ ଅଛି" + "ଠିକ ଅଛି" "ଅଜଣା ଫାଇଲ୍‌" "ଏହିଭଳି ଫାଇଲ୍‌କୁ ସମ୍ଭାଳିବା ପାଇଁ କୌଣସି ଆପ୍‌ ନାହିଁ। \n" "କୌଣସି ଫାଇଲ୍‌ ନାହିଁ" diff --git a/android/app/res/values-te/strings.xml b/android/app/res/values-te/strings.xml index dbc430615a8..a98297dd367 100644 --- a/android/app/res/values-te/strings.xml +++ b/android/app/res/values-te/strings.xml @@ -94,8 +94,8 @@ "కంటెంట్‌కు మద్దతు లేదు." "లక్ష్య పరికరం బదిలీని నిషేధించింది." "వినియోగదారు బదిలీని రద్దు చేశారు." - "నిల్వ సమస్య." - "USB నిల్వ లేదు." + "స్టోరేజ్‌ సమస్య." + "USB స్టోరేజ్‌ లేదు." "SD కార్డు లేదు. బదిలీ చేయబడిన ఫైళ్లను సేవ్ చేయడానికి SD కార్డుని చొప్పించండి." "కనెక్షన్ విఫలమైంది." "రిక్వెస్ట్‌ సరిగ్గా నిర్వహించబడదు." -- GitLab From c929d9b7758f3cbb5e6867b3f7af58256d5f0695 Mon Sep 17 00:00:00 2001 From: Bill Yi Date: Tue, 11 Apr 2023 13:38:23 -0700 Subject: [PATCH 0017/2405] Import translations. DO NOT MERGE ANYWHERE Auto-generated-cl: translation import Change-Id: I841f15c0e81a5c9320808f8e7acaeb92e9f76571 --- android/app/res/values-or/test_strings.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/android/app/res/values-or/test_strings.xml b/android/app/res/values-or/test_strings.xml index fd2571f2c41..1849219b2ce 100644 --- a/android/app/res/values-or/test_strings.xml +++ b/android/app/res/values-or/test_strings.xml @@ -6,7 +6,7 @@ "ରେକର୍ଡ ସୁନିଶ୍ଚିତ କରନ୍ତୁ" "ରେକର୍ଡ ସ୍ୱୀକୃତ କରନ୍ତୁ" "ସମସ୍ତ ରେକର୍ଡ ଡିଲିଟ୍‌ କରନ୍ତୁ" - "ଠିକ୍‌ ଅଛି" + "ଠିକ ଅଛି" "ରେକର୍ଡ ଡିଲିଟ୍‌ କରନ୍ତୁ" "TCP ସର୍ଭର୍‌ ଆରମ୍ଭ କରନ୍ତୁ" "TCP ସର୍ଭର୍‌କୁ ସୂଚିତ କରନ୍ତୁ" -- GitLab From 23136bf6e0f275c41c63fa60bbc64d7762d8f1bd Mon Sep 17 00:00:00 2001 From: Xuan Xing Date: Mon, 10 Apr 2023 20:51:42 +0000 Subject: [PATCH 0018/2405] Updating Bluetooth stack fuzzer configurations This change adds the following default fuzzer settings: 1. Disable debug output for performance 2. Reducing the max corpus size to 4KB (default is 1MB) Ignore-AOSP-First: Internal fuzzers Test: Manual build and test Bug: 274525374 Change-Id: I0a87bdb46bb5205dd112538e6b70954ea4c08f3b --- system/stack/Android.bp | 37 ++++++++++++++++++++++--------------- 1 file changed, 22 insertions(+), 15 deletions(-) diff --git a/system/stack/Android.bp b/system/stack/Android.bp index 711a6a47d15..729d7470c1f 100644 --- a/system/stack/Android.bp +++ b/system/stack/Android.bp @@ -326,6 +326,28 @@ cc_defaults { ], }, }, + fuzz_config: { + // Options for performance improvement + libfuzzer_options: [ + // This disables the stdout and stderr + "close_fd_mask=3", + // This limits the maximum corpus size to 4KB + "max_len=4096", + ], + cc: [ + "android-bluetooth-security@google.com", + "android-security-assurance-redteam@google.com", + ], + componentid: 27441, // Android > Android OS & Apps > Systems > bluetooth + hotlists: [ + "4810445", // ASA Red Team: Bluetooth Engagement Issues + "3705175", // ASA Red Team Discovered Issues + ], + acknowledgement: [ + "Android Red Team of Google", + "Android Bluetooth Team of Google", + ], + }, } cc_fuzz { @@ -350,21 +372,6 @@ cc_fuzz { ":TestMockStackBtm", "fuzzers/sdp_fuzzer.cc", ], - fuzz_config: { - cc: [ - "android-bluetooth-security@google.com", - "android-security-assurance-redteam@google.com", - ], - componentid: 27441, - hotlists: [ - "4810445", - "3705175", - ], - acknowledgement: [ - "Android Red Team of Google", - "Android Bluetooth Team of Google", - ], - }, } // Bluetooth stack unit tests for target -- GitLab From 5c7b8c95ed81a9739d9a8cfe5aabead213d7de05 Mon Sep 17 00:00:00 2001 From: David Duarte Date: Fri, 14 Apr 2023 06:38:22 +0000 Subject: [PATCH 0019/2405] Revert "Ignore PeriodicScanManager to fix failing GattServiceTest" This reverts commit 3c237dbe8f38e46dc8c05c0def3ccf01037ac043. Reason for revert: This patch was made for tm-qpr-dev but has been automerged to master Change-Id: I72c23d650bdca94d05e3c9d036b6dba1072ec912 --- .../com/android/bluetooth/gatt/GattServiceTest.java | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/android/app/tests/unit/src/com/android/bluetooth/gatt/GattServiceTest.java b/android/app/tests/unit/src/com/android/bluetooth/gatt/GattServiceTest.java index 2e63b6cac68..4047f2b6daf 100644 --- a/android/app/tests/unit/src/com/android/bluetooth/gatt/GattServiceTest.java +++ b/android/app/tests/unit/src/com/android/bluetooth/gatt/GattServiceTest.java @@ -64,7 +64,6 @@ import org.junit.After; import org.junit.Assert; import org.junit.Assume; import org.junit.Before; -import org.junit.Ignore; import org.junit.Rule; import org.junit.Test; import org.junit.runner.RunWith; @@ -96,6 +95,7 @@ public class GattServiceTest { @Mock private GattService.ScannerMap mScannerMap; @Mock private GattService.ScannerMap.App mApp; @Mock private GattService.PendingIntentInfo mPiInfo; + @Mock private PeriodicScanManager mPeriodicScanManager; @Mock private ScanManager mScanManager; @Mock private Set mReliableQueue; @Mock private GattService.ServerMap mServerMap; @@ -144,6 +144,7 @@ public class GattServiceTest { mService.mClientMap = mClientMap; mService.mScannerMap = mScannerMap; + mService.mPeriodicScanManager = mPeriodicScanManager; mService.mScanManager = mScanManager; mService.mReliableQueue = mReliableQueue; mService.mServerMap = mServerMap; @@ -701,7 +702,6 @@ public class GattServiceTest { mAttributionSource); } - @Ignore("b/265327402") @Test public void registerSync() { ScanResult scanResult = new ScanResult(mDevice, 1, 2, 3, 4, 5, 6, 7, null, 8); @@ -710,6 +710,7 @@ public class GattServiceTest { IPeriodicAdvertisingCallback callback = mock(IPeriodicAdvertisingCallback.class); mService.registerSync(scanResult, skip, timeout, callback, mAttributionSource); + verify(mPeriodicScanManager).startSync(scanResult, skip, timeout, callback); } @Test @@ -718,9 +719,9 @@ public class GattServiceTest { int syncHandle = 2; mService.transferSync(mDevice, serviceData, syncHandle, mAttributionSource); + verify(mPeriodicScanManager).transferSync(mDevice, serviceData, syncHandle); } - @Ignore("b/265327402") @Test public void transferSetInfo() { int serviceData = 1; @@ -729,14 +730,15 @@ public class GattServiceTest { mService.transferSetInfo(mDevice, serviceData, advHandle, callback, mAttributionSource); + verify(mPeriodicScanManager).transferSetInfo(mDevice, serviceData, advHandle, callback); } - @Ignore("b/265327402") @Test public void unregisterSync() { IPeriodicAdvertisingCallback callback = mock(IPeriodicAdvertisingCallback.class); mService.unregisterSync(callback, mAttributionSource); + verify(mPeriodicScanManager).stopSync(callback); } @Test -- GitLab From d0ae28337d4fd5a5e2098144aa9cd4a01ad598c6 Mon Sep 17 00:00:00 2001 From: Bill Yi Date: Mon, 17 Apr 2023 20:57:02 -0700 Subject: [PATCH 0020/2405] Import translations. DO NOT MERGE ANYWHERE Auto-generated-cl: translation import Change-Id: Ia368a4d7e9ff06577b0ffc19f4471414644d0418 --- android/app/res/values-te/strings_sap.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/android/app/res/values-te/strings_sap.xml b/android/app/res/values-te/strings_sap.xml index d52a8efa627..0bad366ec6f 100644 --- a/android/app/res/values-te/strings_sap.xml +++ b/android/app/res/values-te/strings_sap.xml @@ -5,6 +5,6 @@ "బ్లూటూత్ SIM యాక్సెస్" "డిస్‌కనెక్ట్ చేయడానికి క్లయింట్‌ను అభ్యర్థించాలా?" "డిస్‌కనెక్ట్ చేయడానికి క్లయింట్ కోసం వేచి ఉంది" - "డిస్‌కనెక్ట్ చేయి" + "డిస్‌కనెక్ట్ చేయండి" "నిర్బంధంగా డిస్‌కనెక్ట్ చేయి" -- GitLab From f2814caf8669c792f419b6a4533b50a982e28936 Mon Sep 17 00:00:00 2001 From: Bill Yi Date: Mon, 17 Apr 2023 20:57:46 -0700 Subject: [PATCH 0021/2405] Import translations. DO NOT MERGE ANYWHERE Auto-generated-cl: translation import Change-Id: If30fcf150f1f2586b1f9666a2b7da6f2515367e9 --- android/app/res/values-te/strings.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/android/app/res/values-te/strings.xml b/android/app/res/values-te/strings.xml index a98297dd367..fbe30065451 100644 --- a/android/app/res/values-te/strings.xml +++ b/android/app/res/values-te/strings.xml @@ -24,7 +24,7 @@ "తెలియని పరికరం" "తెలియదు" "అందించబడలేదు" - "ఎయిర్‌ప్లేన్ మోడ్" + "విమానం మోడ్" "మీరు ఎయిర్‌ప్లేన్ మోడ్‌లో బ్లూటూత్‌ను ఉపయోగించలేరు." "బ్లూటూత్ సేవలను ఉపయోగించడానికి, మీరు తప్పనిసరిగా ముందుగా బ్లూటూత్‌ను ప్రారంభించాలి." @@ -70,7 +70,7 @@ "సరే" "ఫైల్ \"%1$s\"కి పంపబడలేదు." "ఫైల్: %1$s" - "మూసివేయి" + "మూసివేయండి" "సరే" "తెలియని ఫైల్" "ఈ రకమైన ఫైల్‌ను మేనేజ్ చేయడానికి యాప్ ఏదీ లేదు. \n" -- GitLab From c359302ce543264ce36bb2e60ecd330f4bf66fdb Mon Sep 17 00:00:00 2001 From: Bill Yi Date: Fri, 21 Apr 2023 18:26:58 -0700 Subject: [PATCH 0022/2405] Import translations. DO NOT MERGE ANYWHERE Auto-generated-cl: translation import Change-Id: I1a96a7d884ac4bd757a178f33eebc1b965c56eae --- android/app/res/values-mk/strings.xml | 2 +- android/app/res/values-or/strings.xml | 2 +- android/app/res/values-zh-rHK/strings.xml | 8 ++++---- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/android/app/res/values-mk/strings.xml b/android/app/res/values-mk/strings.xml index 0baec8dde16..d7f99077e44 100644 --- a/android/app/res/values-mk/strings.xml +++ b/android/app/res/values-mk/strings.xml @@ -53,7 +53,7 @@ "Примање датотеки..." "Запри" - "Сокриј" + "Скриј" "Од" "Име на датотека" "Големина" diff --git a/android/app/res/values-or/strings.xml b/android/app/res/values-or/strings.xml index 411aa65c3aa..a9e5cdbf1ce 100644 --- a/android/app/res/values-or/strings.xml +++ b/android/app/res/values-or/strings.xml @@ -24,7 +24,7 @@ "ଅଜଣା ଡିଭାଇସ୍" "ଅଜଣା" "ପ୍ରଦାନ କରାଯାଇନାହିଁ" - "ଏରୋପ୍ଲେନ୍‍ ମୋଡ୍" + "ଏରୋପ୍ଲେନ ମୋଡ" "ଆପଣ, ଏୟାରପ୍ଲେନ୍‌ ମୋଡ୍‌ରେ ବ୍ଲୁଟୂଥ୍‍‌ ବ୍ୟବହାର କରିପାରିବେ ନାହିଁ।" "ବ୍ଲୁଟୂଥ୍‍‌ ସେବା ବ୍ୟବହାର କରିବା ପାଇଁ, ଆପଣଙ୍କୁ ପ୍ରଥମେ ବ୍ଲୁଟୂଥ୍‍‌ ଅନ୍‌ କରିବାକୁ ପଡ଼ିବ।" diff --git a/android/app/res/values-zh-rHK/strings.xml b/android/app/res/values-zh-rHK/strings.xml index 3edb0eccdb6..4ae1ceedeaa 100644 --- a/android/app/res/values-zh-rHK/strings.xml +++ b/android/app/res/values-zh-rHK/strings.xml @@ -119,7 +119,7 @@ "歌曲識別" "儲存" "取消" - "選取您要透過藍牙分享的帳戶。連線時,您仍然必須接受所有帳戶存取要求。" + "選取你要透過藍牙分享的帳戶。連線時,你仍然必須接受所有帳戶存取要求。" "剩餘插槽數:" "應用程式圖示" "藍牙訊息分享設定" @@ -130,9 +130,9 @@ "無法轉移 4 GB 以上的檔案" "連接藍牙" "在飛航模式中保持藍牙開啟" - "如果您不關閉藍牙,下次手機進入飛行模式時,藍牙將保持開啟" + "如果你不關閉藍牙,下次手機進入飛行模式時,藍牙將保持開啟" "保持藍牙連線" - "手機會記得在飛行模式下保持藍牙開啟。如果您不希望保持開啟,請關閉藍牙。" + "手機會記得在飛行模式下保持藍牙開啟。如果你不希望保持開啟,請關閉藍牙。" "Wi-Fi 和藍牙保持開啟" - "手機會記得在飛行模式下保持 Wi-Fi 及藍牙開啟。如果您不希望保持開啟,請關閉 Wi-Fi 及藍牙。" + "手機會記得在飛行模式下保持 Wi-Fi 及藍牙開啟。如果你不希望保持開啟,請關閉 Wi-Fi 及藍牙。" -- GitLab From 4e7d135c0a2917b0a1f1184d6f7926cb5022edac Mon Sep 17 00:00:00 2001 From: Bill Yi Date: Sat, 22 Apr 2023 00:13:41 -0700 Subject: [PATCH 0023/2405] Import translations. DO NOT MERGE ANYWHERE Auto-generated-cl: translation import Change-Id: Idef5a1088ea1956cf4cfec9d10f85edae28faf4f --- android/app/res/values-af/strings_pbap.xml | 2 ++ android/app/res/values-am/strings_pbap.xml | 2 ++ android/app/res/values-ar/strings_pbap.xml | 2 ++ android/app/res/values-as/strings_pbap.xml | 2 ++ android/app/res/values-az/strings_pbap.xml | 2 ++ android/app/res/values-b+sr+Latn/strings_pbap.xml | 2 ++ android/app/res/values-be/strings_pbap.xml | 2 ++ android/app/res/values-bg/strings_pbap.xml | 2 ++ android/app/res/values-bn/strings_pbap.xml | 2 ++ android/app/res/values-bs/strings_pbap.xml | 2 ++ android/app/res/values-ca/strings_pbap.xml | 2 ++ android/app/res/values-cs/strings_pbap.xml | 2 ++ android/app/res/values-da/strings_pbap.xml | 2 ++ android/app/res/values-de/strings_pbap.xml | 2 ++ android/app/res/values-el/strings_pbap.xml | 2 ++ android/app/res/values-en-rAU/strings_pbap.xml | 2 ++ android/app/res/values-en-rCA/strings_pbap.xml | 8 +++++--- android/app/res/values-en-rGB/strings_pbap.xml | 2 ++ android/app/res/values-en-rIN/strings_pbap.xml | 2 ++ android/app/res/values-en-rXC/strings_pbap.xml | 2 ++ android/app/res/values-es-rUS/strings_pbap.xml | 2 ++ android/app/res/values-es/strings_pbap.xml | 2 ++ android/app/res/values-et/strings_pbap.xml | 2 ++ android/app/res/values-eu/strings_pbap.xml | 2 ++ android/app/res/values-fa/strings_pbap.xml | 2 ++ android/app/res/values-fi/strings_pbap.xml | 2 ++ android/app/res/values-fr-rCA/strings_pbap.xml | 2 ++ android/app/res/values-fr/strings_pbap.xml | 2 ++ android/app/res/values-gl/strings_pbap.xml | 2 ++ android/app/res/values-gu/strings_pbap.xml | 2 ++ android/app/res/values-hi/strings_pbap.xml | 2 ++ android/app/res/values-hr/strings_pbap.xml | 2 ++ android/app/res/values-hu/strings_pbap.xml | 2 ++ android/app/res/values-hy/strings_pbap.xml | 2 ++ android/app/res/values-in/strings_pbap.xml | 2 ++ android/app/res/values-is/strings_pbap.xml | 2 ++ android/app/res/values-it/strings_pbap.xml | 2 ++ android/app/res/values-iw/strings_pbap.xml | 2 ++ android/app/res/values-ja/strings_pbap.xml | 2 ++ android/app/res/values-ka/strings_pbap.xml | 2 ++ android/app/res/values-kk/strings_pbap.xml | 2 ++ android/app/res/values-km/strings_pbap.xml | 2 ++ android/app/res/values-kn/strings_pbap.xml | 2 ++ android/app/res/values-ko/strings_pbap.xml | 2 ++ android/app/res/values-ky/strings_pbap.xml | 4 +++- android/app/res/values-lo/strings_pbap.xml | 2 ++ android/app/res/values-lt/strings_pbap.xml | 2 ++ android/app/res/values-lv/strings_pbap.xml | 2 ++ android/app/res/values-mk/strings_pbap.xml | 2 ++ android/app/res/values-ml/strings_pbap.xml | 2 ++ android/app/res/values-mn/strings_pbap.xml | 2 ++ android/app/res/values-mr/strings_pbap.xml | 2 ++ android/app/res/values-ms/strings_pbap.xml | 2 ++ android/app/res/values-my/strings_pbap.xml | 2 ++ android/app/res/values-nb/strings_pbap.xml | 2 ++ android/app/res/values-ne/strings_pbap.xml | 2 ++ android/app/res/values-nl/strings_pbap.xml | 2 ++ android/app/res/values-or/strings_pbap.xml | 4 +++- android/app/res/values-pa/strings_pbap.xml | 2 ++ android/app/res/values-pl/strings_pbap.xml | 2 ++ android/app/res/values-pt-rPT/strings_pbap.xml | 4 ++-- android/app/res/values-pt/strings_pbap.xml | 4 ++-- android/app/res/values-ro/strings_pbap.xml | 6 ++++-- android/app/res/values-ru/strings_pbap.xml | 2 ++ android/app/res/values-si/strings_pbap.xml | 2 ++ android/app/res/values-sk/strings_pbap.xml | 2 ++ android/app/res/values-sl/strings_pbap.xml | 2 ++ android/app/res/values-sq/strings_pbap.xml | 2 ++ android/app/res/values-sr/strings_pbap.xml | 2 ++ android/app/res/values-sv/strings_pbap.xml | 2 ++ android/app/res/values-sw/strings_pbap.xml | 2 ++ android/app/res/values-ta/strings_pbap.xml | 2 ++ android/app/res/values-te/strings_pbap.xml | 2 ++ android/app/res/values-th/strings_pbap.xml | 2 ++ android/app/res/values-tl/strings_pbap.xml | 2 ++ android/app/res/values-tr/strings_pbap.xml | 2 ++ android/app/res/values-uk/strings_pbap.xml | 2 ++ android/app/res/values-ur/strings_pbap.xml | 2 ++ android/app/res/values-uz/strings_pbap.xml | 2 ++ android/app/res/values-vi/strings_pbap.xml | 2 ++ android/app/res/values-zh-rCN/strings_pbap.xml | 2 ++ android/app/res/values-zh-rHK/strings_pbap.xml | 2 ++ android/app/res/values-zh-rTW/strings_pbap.xml | 2 ++ android/app/res/values-zu/strings_pbap.xml | 2 ++ 84 files changed, 175 insertions(+), 11 deletions(-) diff --git a/android/app/res/values-af/strings_pbap.xml b/android/app/res/values-af/strings_pbap.xml index 65bffa555e8..0fa903b172d 100644 --- a/android/app/res/values-af/strings_pbap.xml +++ b/android/app/res/values-af/strings_pbap.xml @@ -13,4 +13,6 @@ "My naam" "000000" "Bluetooth-kontakdeling" + "Foonboek se gevorderde kenmerk word gesteun" + "Bind weer saam met Foonboek se gevorderde kenmerk" diff --git a/android/app/res/values-am/strings_pbap.xml b/android/app/res/values-am/strings_pbap.xml index 132be0f6d2d..89da5d01b13 100644 --- a/android/app/res/values-am/strings_pbap.xml +++ b/android/app/res/values-am/strings_pbap.xml @@ -13,4 +13,6 @@ "የእኔ ስም" "000000" "ብሉቱዝ የእውቂያ መጋራት" + "የስልክ ደብተር የላቀ ባህሪ ይደገፋል" + "የላቀ የስልክ ደብተር ባህሪን ዳግም ያጣምሩ" diff --git a/android/app/res/values-ar/strings_pbap.xml b/android/app/res/values-ar/strings_pbap.xml index acab2fa3846..198c8c087c5 100644 --- a/android/app/res/values-ar/strings_pbap.xml +++ b/android/app/res/values-ar/strings_pbap.xml @@ -13,4 +13,6 @@ "اسمي" "000000" "مشاركة جهات الاتصال عبر البلوتوث" + "إتاحة الميزات المتقدّمة لدليل الهاتف" + "إصلاح الميزات المتقدّمة لدليل الهاتف" diff --git a/android/app/res/values-as/strings_pbap.xml b/android/app/res/values-as/strings_pbap.xml index 65f55573159..70014fbe4e0 100644 --- a/android/app/res/values-as/strings_pbap.xml +++ b/android/app/res/values-as/strings_pbap.xml @@ -13,4 +13,6 @@ "মোৰ নাম" "০০০০০০" "ব্লুটুথ সম্পৰ্ক শ্বেয়াৰ" + "ফ’নবুকৰ উচ্চখাপৰ সুবিধা সমৰ্থন কৰা হয়" + "ফ’নবুকৰ উচ্চখাপৰ সুবিধাৰ বাবে পুনৰ পেয়াৰ কৰক" diff --git a/android/app/res/values-az/strings_pbap.xml b/android/app/res/values-az/strings_pbap.xml index 8bb340b37ca..5a88b01a8f6 100644 --- a/android/app/res/values-az/strings_pbap.xml +++ b/android/app/res/values-az/strings_pbap.xml @@ -13,4 +13,6 @@ "Mənim adım" "000000" "Bluetooth Kontakt paylaşımı" + "Telefon Kitabçasının Təkmil Funksiyası Dəstəklənir" + "Təkmil Telefon Kitabçası Funksiyası üçün yenidən əlaqələndirin" diff --git a/android/app/res/values-b+sr+Latn/strings_pbap.xml b/android/app/res/values-b+sr+Latn/strings_pbap.xml index 4e7ee77aef9..78f6961c9b1 100644 --- a/android/app/res/values-b+sr+Latn/strings_pbap.xml +++ b/android/app/res/values-b+sr+Latn/strings_pbap.xml @@ -13,4 +13,6 @@ "Moje ime" "000000" "Deljenje kontakata preko Bluetooth-a" + "Podržana je napredna funkcija telefonskog imenika" + "Ponovno uparivanje za naprednu funkciju telefonskog imenika" diff --git a/android/app/res/values-be/strings_pbap.xml b/android/app/res/values-be/strings_pbap.xml index 87a85ac08c4..569f6e824ee 100644 --- a/android/app/res/values-be/strings_pbap.xml +++ b/android/app/res/values-be/strings_pbap.xml @@ -13,4 +13,6 @@ "Маё імя" "000000" "Абагульванне кантактаў праз Bluetooth" + "Падтрымліваюцца пашыраныя функцыі тэлефоннай кнігі" + "Для выкарыстання пашыраных функцый тэлефоннай кнігі выканайце спалучэнне яшчэ раз" diff --git a/android/app/res/values-bg/strings_pbap.xml b/android/app/res/values-bg/strings_pbap.xml index 004c9f190a6..cfc0d5463e1 100644 --- a/android/app/res/values-bg/strings_pbap.xml +++ b/android/app/res/values-bg/strings_pbap.xml @@ -13,4 +13,6 @@ "Моето име" "000000" "Споделяне на контакта през Bluetooth" + "Поддържа се разширената функция за телефонен указател" + "Извършете повторно сдвояване за разширената функция за телефонен указател" diff --git a/android/app/res/values-bn/strings_pbap.xml b/android/app/res/values-bn/strings_pbap.xml index d93abb6921c..d1869ed1d37 100644 --- a/android/app/res/values-bn/strings_pbap.xml +++ b/android/app/res/values-bn/strings_pbap.xml @@ -13,4 +13,6 @@ "আমার নাম" "০০০০০০" "ব্লুটুথ পরিচিতির সাথে শেয়ার করা" + "ফোনবুক উন্নত ফিচার কাজ করবে" + "উন্নত ফোনবুক ফিচারের জন্য আবার পেয়ার করুন" diff --git a/android/app/res/values-bs/strings_pbap.xml b/android/app/res/values-bs/strings_pbap.xml index 2f94d05ef75..4672149f3ae 100644 --- a/android/app/res/values-bs/strings_pbap.xml +++ b/android/app/res/values-bs/strings_pbap.xml @@ -13,4 +13,6 @@ "Moje ime" "000000" "Dijeljenje kontakata putem Bluetootha" + "Podržane su napredne funkcije za telefonski imenik" + "Ponovno uparivanje za naprednu funkciju telefonskog imenika" diff --git a/android/app/res/values-ca/strings_pbap.xml b/android/app/res/values-ca/strings_pbap.xml index f8dcebfdef7..add1ee228d6 100644 --- a/android/app/res/values-ca/strings_pbap.xml +++ b/android/app/res/values-ca/strings_pbap.xml @@ -13,4 +13,6 @@ "El meu nom" "000000" "Compartir contactes amb Bluetooth" + "Funció avançada de l\'agenda telefònica admesa" + "Torna a vincular la funció avançada de l\'agenda telefònica" diff --git a/android/app/res/values-cs/strings_pbap.xml b/android/app/res/values-cs/strings_pbap.xml index f004613f97a..d296e577289 100644 --- a/android/app/res/values-cs/strings_pbap.xml +++ b/android/app/res/values-cs/strings_pbap.xml @@ -13,4 +13,6 @@ "Mé jméno" "000000" "Sdílení kontaktu přes Bluetooth" + "Je podporována pokročilá funkce telefonního seznamu" + "Pro funkci pokročilého telefonního seznamu opakujte spárování" diff --git a/android/app/res/values-da/strings_pbap.xml b/android/app/res/values-da/strings_pbap.xml index 8199d355bcc..40ad73884e1 100644 --- a/android/app/res/values-da/strings_pbap.xml +++ b/android/app/res/values-da/strings_pbap.xml @@ -13,4 +13,6 @@ "Mit navn" "000000" "Deling af kontakter via Bluetooth" + "Avanceret funktion til telefonbogen understøttes" + "Parring af avanceret funktion til telefonbogen" diff --git a/android/app/res/values-de/strings_pbap.xml b/android/app/res/values-de/strings_pbap.xml index 01e4b441ac1..f02a6b919a3 100644 --- a/android/app/res/values-de/strings_pbap.xml +++ b/android/app/res/values-de/strings_pbap.xml @@ -13,4 +13,6 @@ "Mein Name" "000000" "Kontakte über Bluetooth teilen" + "Erweitertes Telefonbuch wird unterstützt" + "Für Nutzung des erweiterten Telefonbuchs wieder koppeln" diff --git a/android/app/res/values-el/strings_pbap.xml b/android/app/res/values-el/strings_pbap.xml index a68c25b3b3b..4f67d317e94 100644 --- a/android/app/res/values-el/strings_pbap.xml +++ b/android/app/res/values-el/strings_pbap.xml @@ -13,4 +13,6 @@ "Το όνομα μου" "000000" "Κοινοποίηση επαφών μέσω Bluetooth" + "Η σύνθετη λειτουργία τηλεφωνικού καταλόγου υποστηρίζεται" + "Επιδιόρθωση για τη σύνθετη λειτουργία τηλεφωνικού καταλόγου" diff --git a/android/app/res/values-en-rAU/strings_pbap.xml b/android/app/res/values-en-rAU/strings_pbap.xml index c7b8dc853ba..f296a30d551 100644 --- a/android/app/res/values-en-rAU/strings_pbap.xml +++ b/android/app/res/values-en-rAU/strings_pbap.xml @@ -13,4 +13,6 @@ "My name" "000000" "Bluetooth Contact share" + "Phonebook advance feature supported" + "Re-pair for advance phonebook feature" diff --git a/android/app/res/values-en-rCA/strings_pbap.xml b/android/app/res/values-en-rCA/strings_pbap.xml index c7b8dc853ba..943172eca5c 100644 --- a/android/app/res/values-en-rCA/strings_pbap.xml +++ b/android/app/res/values-en-rCA/strings_pbap.xml @@ -4,13 +4,15 @@ "Type session key for %1$s" "Bluetooth session key required" "There was time out to accept connection with %1$s" - "There was a timeout to input session key with %1$s" + "There was time out to input session key with %1$s" "Obex authentication request" - "Session key" + "Session Key" "Type session key for %1$s" - "Car Kit" + "Carkit" "Unknown name" "My name" "000000" "Bluetooth Contact share" + "Phonebook Advance Feature Supported" + "Re-pair for Advance Phonebook Feature" diff --git a/android/app/res/values-en-rGB/strings_pbap.xml b/android/app/res/values-en-rGB/strings_pbap.xml index c7b8dc853ba..f296a30d551 100644 --- a/android/app/res/values-en-rGB/strings_pbap.xml +++ b/android/app/res/values-en-rGB/strings_pbap.xml @@ -13,4 +13,6 @@ "My name" "000000" "Bluetooth Contact share" + "Phonebook advance feature supported" + "Re-pair for advance phonebook feature" diff --git a/android/app/res/values-en-rIN/strings_pbap.xml b/android/app/res/values-en-rIN/strings_pbap.xml index c7b8dc853ba..f296a30d551 100644 --- a/android/app/res/values-en-rIN/strings_pbap.xml +++ b/android/app/res/values-en-rIN/strings_pbap.xml @@ -13,4 +13,6 @@ "My name" "000000" "Bluetooth Contact share" + "Phonebook advance feature supported" + "Re-pair for advance phonebook feature" diff --git a/android/app/res/values-en-rXC/strings_pbap.xml b/android/app/res/values-en-rXC/strings_pbap.xml index 39160fdcc6b..ce608a5251f 100644 --- a/android/app/res/values-en-rXC/strings_pbap.xml +++ b/android/app/res/values-en-rXC/strings_pbap.xml @@ -13,4 +13,6 @@ "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‎‎‎‏‏‏‎‏‏‏‏‏‏‏‏‏‏‏‏‎‏‎‎‎‏‏‏‎‎‎‎‏‏‎‏‎‎‎‎‏‎‏‏‏‎‎‏‏‏‎‏‎‎‏‎‏‎‏‏‏‎‎‎‏‏‏‏‏‏‎‏‏‏‎‎‎‎My name‎‏‎‎‏‎" "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‎‎‎‏‏‏‎‏‏‏‏‏‏‏‎‎‏‎‏‎‎‎‏‏‏‎‏‎‏‏‎‎‏‏‏‏‏‏‏‏‏‏‎‎‎‎‏‎‎‎‏‏‎‏‎‎‏‎‎‏‎‏‏‎‏‎‏‎‎‎‏‎‏‏‏‎‎000000‎‏‎‎‏‎" "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‎‎‎‏‏‏‎‏‏‏‏‏‎‏‏‏‎‏‎‏‎‎‎‎‎‎‏‎‏‏‏‏‏‏‎‎‎‎‎‏‏‏‏‏‎‎‏‏‏‎‏‎‎‏‎‎‎‏‏‏‎‏‎‏‏‏‎‎‎‏‎‎‏‎‏‎Bluetooth Contact share‎‏‎‎‏‎" + "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‎‎‎‏‏‏‎‏‏‏‏‏‏‏‏‏‎‎‎‎‏‏‎‏‎‎‎‏‏‏‏‏‏‎‎‏‎‏‏‎‏‏‎‏‏‎‏‎‎‏‏‏‎‏‎‏‎‎‏‏‏‏‏‏‎‏‏‎‏‎‏‎‏‎‎‎‎Phonebook Advance Feature Supported‎‏‎‎‏‎" + "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‎‎‎‏‏‏‎‏‏‏‏‏‎‏‏‎‎‎‎‎‏‏‎‏‏‏‎‎‏‎‎‎‎‎‎‏‏‎‎‎‏‎‎‎‏‎‎‏‏‏‎‎‏‏‎‎‏‎‎‎‏‏‎‏‏‎‎‎‎‏‏‏‏‏‏‎Re-pair for Advance Phonebook Feature‎‏‎‎‏‎" diff --git a/android/app/res/values-es-rUS/strings_pbap.xml b/android/app/res/values-es-rUS/strings_pbap.xml index 674bcc0a529..9a67653219e 100644 --- a/android/app/res/values-es-rUS/strings_pbap.xml +++ b/android/app/res/values-es-rUS/strings_pbap.xml @@ -13,4 +13,6 @@ "Mi nombre" "000000" "Compartir contactos por Bluetooth" + "Compatibilidad con las funciones avanzadas de la agenda telefónica" + "Volver a vincular para acceder a las funciones avanzadas de la agenda telefónica" diff --git a/android/app/res/values-es/strings_pbap.xml b/android/app/res/values-es/strings_pbap.xml index bd40f7a8161..7ec3a65a8a7 100644 --- a/android/app/res/values-es/strings_pbap.xml +++ b/android/app/res/values-es/strings_pbap.xml @@ -13,4 +13,6 @@ "Mi nombre" "000000" "Compartir contactos por Bluetooth" + "Compatible con la función avanzada de agenda de contactos" + "Volver a emparejar para la función avanzada de agenda de contactos" diff --git a/android/app/res/values-et/strings_pbap.xml b/android/app/res/values-et/strings_pbap.xml index a25075fd98c..1d2a2df8e0d 100644 --- a/android/app/res/values-et/strings_pbap.xml +++ b/android/app/res/values-et/strings_pbap.xml @@ -13,4 +13,6 @@ "Minu nimi" "000000" "Bluetoothi kontakti jagamine" + "Toetatud on telefoniraamatu täiustatud funktsioon" + "Täiustatud telefoniraamatufunktsiooni kasutamiseks siduge seade uuesti" diff --git a/android/app/res/values-eu/strings_pbap.xml b/android/app/res/values-eu/strings_pbap.xml index db17ca9fa49..bd08027958e 100644 --- a/android/app/res/values-eu/strings_pbap.xml +++ b/android/app/res/values-eu/strings_pbap.xml @@ -13,4 +13,6 @@ "Nire izena" "000000" "Kontaktuak Bluetooth bidez partekatzeko aukera" + "Agendaren eginbide aurreratua onartzen da" + "Agendaren eginbide aurreratua erabiltzeko, parekatu berriro" diff --git a/android/app/res/values-fa/strings_pbap.xml b/android/app/res/values-fa/strings_pbap.xml index 539a39d1163..917f5b59414 100644 --- a/android/app/res/values-fa/strings_pbap.xml +++ b/android/app/res/values-fa/strings_pbap.xml @@ -13,4 +13,6 @@ "نام من" "000000" "اشتراک‌گذاری مخاطبین ازطریق بلوتوث" + "از ویژگی پیشرفته دفترچه تلفن پشتیبانی می‌شود" + "برای ویژگی پیشرفته دفترچه تلفن دوباره مرتبط کنید" diff --git a/android/app/res/values-fi/strings_pbap.xml b/android/app/res/values-fi/strings_pbap.xml index 9174326acca..b8b149e266d 100644 --- a/android/app/res/values-fi/strings_pbap.xml +++ b/android/app/res/values-fi/strings_pbap.xml @@ -13,4 +13,6 @@ "Oma nimeni" "000000" "Bluetooth-yhteyden jako" + "Puhelinluettelo-lisäominaisuuden tuki" + "Puhelinluettelo-lisäominaisuuden yhdistäminen uudelleen" diff --git a/android/app/res/values-fr-rCA/strings_pbap.xml b/android/app/res/values-fr-rCA/strings_pbap.xml index 96556e880ff..59a768fc548 100644 --- a/android/app/res/values-fr-rCA/strings_pbap.xml +++ b/android/app/res/values-fr-rCA/strings_pbap.xml @@ -13,4 +13,6 @@ "Mon nom" "000000" "Partage de contacts par Bluetooth" + "Fonctionnalité avancée du répertoire téléphonique prise en charge" + "Réassocier pour la fonctionnalité avancée du répertoire téléphonique" diff --git a/android/app/res/values-fr/strings_pbap.xml b/android/app/res/values-fr/strings_pbap.xml index 75521885924..c3bddbcea0d 100644 --- a/android/app/res/values-fr/strings_pbap.xml +++ b/android/app/res/values-fr/strings_pbap.xml @@ -13,4 +13,6 @@ "Mon nom" "000000" "Partage de contact Bluetooth" + "Fonctionnalité avancée de l\'annuaire téléphonique prise en charge" + "Nouvelle association de la fonctionnalité avancée de l\'annuaire téléphonique" diff --git a/android/app/res/values-gl/strings_pbap.xml b/android/app/res/values-gl/strings_pbap.xml index 07446a28d47..7b333458d04 100644 --- a/android/app/res/values-gl/strings_pbap.xml +++ b/android/app/res/values-gl/strings_pbap.xml @@ -13,4 +13,6 @@ "O meu nome" "000000" "Compartir contactos por Bluetooth" + "Compatible coa función avanzada de axenda telefónica" + "Volve vincular para activar a función avanzada de axenda telefónica" diff --git a/android/app/res/values-gu/strings_pbap.xml b/android/app/res/values-gu/strings_pbap.xml index 594db2b8ae7..c19ddf2e644 100644 --- a/android/app/res/values-gu/strings_pbap.xml +++ b/android/app/res/values-gu/strings_pbap.xml @@ -13,4 +13,6 @@ "મારું નામ" "000000" "બ્લૂટૂથ સંપર્ક શેર કરો" + "ફોનબુકની વિગતવાર સુવિધાને સપોર્ટ કરવામાં આવે છે" + "ફોનબુકની વિગતવાર સુવિધા માટે ફરીથી જોડાણ કરો" diff --git a/android/app/res/values-hi/strings_pbap.xml b/android/app/res/values-hi/strings_pbap.xml index ded519c4ba7..e624202da0b 100644 --- a/android/app/res/values-hi/strings_pbap.xml +++ b/android/app/res/values-hi/strings_pbap.xml @@ -13,4 +13,6 @@ "मेरा नाम" "000000" "ब्लूटूथ संपर्क शेयर करें" + "फ़ोनबुक की बेहतर सुविधा उपलब्ध है" + "फ़ोनबुक की बेहतर सुविधा इस्तेमाल करने के लिए, ब्लूटूथ को फिर से कनेक्ट करें" diff --git a/android/app/res/values-hr/strings_pbap.xml b/android/app/res/values-hr/strings_pbap.xml index 77f668ca8e5..1adca2dcd57 100644 --- a/android/app/res/values-hr/strings_pbap.xml +++ b/android/app/res/values-hr/strings_pbap.xml @@ -13,4 +13,6 @@ "Moje ime" "000000" "Dijeljenje kontakata Bluetoothom" + "Podržana je napredna značajka telefonskog imenika" + "Popravak napredne značajke telefonskog imenika" diff --git a/android/app/res/values-hu/strings_pbap.xml b/android/app/res/values-hu/strings_pbap.xml index 6d0f727c785..a6af6163b20 100644 --- a/android/app/res/values-hu/strings_pbap.xml +++ b/android/app/res/values-hu/strings_pbap.xml @@ -13,4 +13,6 @@ "Telefon neve" "000000" "Bluetooth-névjegymegosztás" + "A telefonkönyv speciális funkcióinak támogatása" + "Újrapárosítás a telefon speciális funkciójának támogatásához" diff --git a/android/app/res/values-hy/strings_pbap.xml b/android/app/res/values-hy/strings_pbap.xml index 26b005da9d2..de86e212824 100644 --- a/android/app/res/values-hy/strings_pbap.xml +++ b/android/app/res/values-hy/strings_pbap.xml @@ -13,4 +13,6 @@ "Իմ անունը" "000000" "Bluetooth կոնտակտների համօգտագործում" + "Աջակցվում են հեռախոսագրքի ընդլայնված գործառույթը" + "Վերազուգակցում հեռախոսագրքի ընդլայնված գործառույթի համար" diff --git a/android/app/res/values-in/strings_pbap.xml b/android/app/res/values-in/strings_pbap.xml index 0ce6bd6faab..b6ee6642a17 100644 --- a/android/app/res/values-in/strings_pbap.xml +++ b/android/app/res/values-in/strings_pbap.xml @@ -13,4 +13,6 @@ "Nama saya" "000000" "Berbagi Kontak Bluetooth" + "Fitur Lanjutan Daftar Kontak Didukung" + "Sambungkan Ulang untuk mendapatkan Fitur Lanjutan Daftar Kontak" diff --git a/android/app/res/values-is/strings_pbap.xml b/android/app/res/values-is/strings_pbap.xml index 53d6029cad0..baf503e6968 100644 --- a/android/app/res/values-is/strings_pbap.xml +++ b/android/app/res/values-is/strings_pbap.xml @@ -13,4 +13,6 @@ "Nafnið mitt" "000000" "Tengiliðum deilt með Bluetooth" + "Ítareiginleikar símaskrár studdir" + "Lagfæring á ítareiginleikum símaskrár" diff --git a/android/app/res/values-it/strings_pbap.xml b/android/app/res/values-it/strings_pbap.xml index 33a6d71074b..c4324101463 100644 --- a/android/app/res/values-it/strings_pbap.xml +++ b/android/app/res/values-it/strings_pbap.xml @@ -13,4 +13,6 @@ "Il mio nome" "000000" "Condivisione dei contatti tramite Bluetooth" + "Funzionalità avanzata della rubrica supportata" + "Nuovo accoppiamento per funzionalità avanzata della rubrica" diff --git a/android/app/res/values-iw/strings_pbap.xml b/android/app/res/values-iw/strings_pbap.xml index 6a7b006213e..db117984e08 100644 --- a/android/app/res/values-iw/strings_pbap.xml +++ b/android/app/res/values-iw/strings_pbap.xml @@ -13,4 +13,6 @@ "השם שלי" "000000" "‏שיתוף אנשי קשר באמצעות Bluetooth" + "יש תמיכה בתכונה המתקדמת של ספר הטלפונים" + "יש להתאים מחדש כדי להשתמש בתכונה המתקדמת של ספר הטלפונים" diff --git a/android/app/res/values-ja/strings_pbap.xml b/android/app/res/values-ja/strings_pbap.xml index 673efabb2a6..5ad560c387b 100644 --- a/android/app/res/values-ja/strings_pbap.xml +++ b/android/app/res/values-ja/strings_pbap.xml @@ -13,4 +13,6 @@ "名前" "000000" "Bluetooth での連絡先の共有" + "高度な電話帳機能に対応" + "高度な電話帳機能に合わせて再度ペア設定" diff --git a/android/app/res/values-ka/strings_pbap.xml b/android/app/res/values-ka/strings_pbap.xml index f54c28f446c..625b0e18976 100644 --- a/android/app/res/values-ka/strings_pbap.xml +++ b/android/app/res/values-ka/strings_pbap.xml @@ -13,4 +13,6 @@ "ჩემი სახელი" "000000" "Bluetooth კონტაქტის გაზიარება" + "სატელეფონო წიგნის მხარდაჭერილი გაფართოებული ფუნქციები" + "შეკეთება სატელეფონო წიგნის გაფართოებული ფუნქციისთვის" diff --git a/android/app/res/values-kk/strings_pbap.xml b/android/app/res/values-kk/strings_pbap.xml index cbc15e9e41f..c092d2c124d 100644 --- a/android/app/res/values-kk/strings_pbap.xml +++ b/android/app/res/values-kk/strings_pbap.xml @@ -13,4 +13,6 @@ "Mені атым" "000000" "Bluetooth арқылы контактіні бөлісу" + "Телефон кітапшасының қолдау көрсетілетін кеңейтілген функциясы" + "Телефон кітапшасының кеңейтілген функциясын қайта жұптау" diff --git a/android/app/res/values-km/strings_pbap.xml b/android/app/res/values-km/strings_pbap.xml index 37e1aac2b49..33f9a3f17ec 100644 --- a/android/app/res/values-km/strings_pbap.xml +++ b/android/app/res/values-km/strings_pbap.xml @@ -13,4 +13,6 @@ "ឈ្មោះ​របស់​ខ្ញុំ" "000000" "ការចែករំលែក​ទំនាក់ទំនង​ប៊្លូធូស" + "អាចប្រើ​មុខងារកម្រិតខ្ពស់របស់​សៀវភៅទូរសព្ទ" + "ផ្គូផ្គង​មុខងារសៀវភៅទូរសព្ទកម្រិតខ្ពស់​ឡើងវិញ" diff --git a/android/app/res/values-kn/strings_pbap.xml b/android/app/res/values-kn/strings_pbap.xml index 5f75060c9cf..93543c990a6 100644 --- a/android/app/res/values-kn/strings_pbap.xml +++ b/android/app/res/values-kn/strings_pbap.xml @@ -13,4 +13,6 @@ "ನನ್ನ ಹೆಸರು" "000000" "ಬ್ಲೂಟೂತ್ ಸಂಪರ್ಕ ಹಂಚಿಕೆ" + "ಫೋನ್‌ಬುಕ್‌ನ ಸುಧಾರಿತ ಫೀಚರ್‌ ಬೆಂಬಲಿತವಾಗಿದೆ" + "ಸುಧಾರಿತ ಫೋನ್‌ಬುಕ್‌ ಫೀಚರ್‌ಗಾಗಿ ಮರು-ಜೋಡಿಸಿ" diff --git a/android/app/res/values-ko/strings_pbap.xml b/android/app/res/values-ko/strings_pbap.xml index 9e2a557f4c8..eb83f1c46db 100644 --- a/android/app/res/values-ko/strings_pbap.xml +++ b/android/app/res/values-ko/strings_pbap.xml @@ -13,4 +13,6 @@ "내 이름" "000000" "블루투스 연락처 공유" + "연락처 목록 고급 기능 지원됨" + "고급 연락처 목록 기능을 위해 다시 페어링" diff --git a/android/app/res/values-ky/strings_pbap.xml b/android/app/res/values-ky/strings_pbap.xml index 02281616544..d5dc9832128 100644 --- a/android/app/res/values-ky/strings_pbap.xml +++ b/android/app/res/values-ky/strings_pbap.xml @@ -12,5 +12,7 @@ "Белгисиз ат" "Менин атым" "000000" - "Bluetooth аркылуу байланыш менен бөлүшүү" + "Байланыштарды Bluetooth аркылуу бөлүшүү" + "Телефон китепчесинин өркүндөтүлгөн функциясы колдоого алынат" + "Телефон китепчесинин өркүндөтүлгөн функциясы үчүн кайра жупташтыруу" diff --git a/android/app/res/values-lo/strings_pbap.xml b/android/app/res/values-lo/strings_pbap.xml index 7bd4b12788b..01fe72778e8 100644 --- a/android/app/res/values-lo/strings_pbap.xml +++ b/android/app/res/values-lo/strings_pbap.xml @@ -13,4 +13,6 @@ "ຊື່ຂອງຂ້ອຍ" "000000" "ການແບ່ງປັນລາຍຊື່ຜູ້ຕິດຕໍ່ຜ່ານ Bluetooth" + "ຮອງຮັບຄຸນສົມບັດຂັ້ນສູງຂອງສະໝຸດໂທລະສັບ" + "ຈັບຄູ່ຄືນໃໝ່ສຳລັບຄຸນສົມບັດສະໝຸດໂທລະສັບຂັ້ນສູງ" diff --git a/android/app/res/values-lt/strings_pbap.xml b/android/app/res/values-lt/strings_pbap.xml index 39d3fe688ca..317fe301a69 100644 --- a/android/app/res/values-lt/strings_pbap.xml +++ b/android/app/res/values-lt/strings_pbap.xml @@ -13,4 +13,6 @@ "Mano vardas" "000000" "„Bluetooth“ kontaktų bendrinimas" + "Palaikomos išplėstinės telefonų knygos funkcijos" + "Išplėstinės telefonų knygos funkcijos pakartotinis susiejimas" diff --git a/android/app/res/values-lv/strings_pbap.xml b/android/app/res/values-lv/strings_pbap.xml index d34161d0d84..24b3672fd75 100644 --- a/android/app/res/values-lv/strings_pbap.xml +++ b/android/app/res/values-lv/strings_pbap.xml @@ -13,4 +13,6 @@ "Mans vārds" "000000" "Kontaktpersonu kopīgošana, izmantojot Bluetooth" + "Atbalstīta tālruņa kataloga papildu funkcija" + "Tālruņa kataloga papildu funkcijas labojums" diff --git a/android/app/res/values-mk/strings_pbap.xml b/android/app/res/values-mk/strings_pbap.xml index 888f4bab0f9..f7fdc51aa48 100644 --- a/android/app/res/values-mk/strings_pbap.xml +++ b/android/app/res/values-mk/strings_pbap.xml @@ -13,4 +13,6 @@ "Моето име" "000000" "Споделување контакти преку Bluetooth" + "Напредната функција за телефонски именик е поддржана" + "Повторно спарување за напредната функција за телефонски именик" diff --git a/android/app/res/values-ml/strings_pbap.xml b/android/app/res/values-ml/strings_pbap.xml index 47fa21305be..06cc65058a1 100644 --- a/android/app/res/values-ml/strings_pbap.xml +++ b/android/app/res/values-ml/strings_pbap.xml @@ -13,4 +13,6 @@ "എന്റെ പേര്" "000000" "Bluetooth കോണ്‍‌ടാക്റ്റ് പങ്കിടൽ" + "ഫോൺബുക്കിന്റെ വിപുലമായ ഫീച്ചറുകൾ പിന്തുണയ്ക്കുന്നു" + "ഫോൺബുക്കിന്റെ വിപുലമായ ഫീച്ചറിനായി വീണ്ടും ജോടിയാക്കുക" diff --git a/android/app/res/values-mn/strings_pbap.xml b/android/app/res/values-mn/strings_pbap.xml index d0a45423f84..3d37de990e5 100644 --- a/android/app/res/values-mn/strings_pbap.xml +++ b/android/app/res/values-mn/strings_pbap.xml @@ -13,4 +13,6 @@ "Миний нэр" "000000" "Bluetooth харилцагч хуваалцах" + "Утасны лавлахын дэвшилтэт онцлогийг дэмжсэн" + "Утасны лавлахын дэвшилтэт онцлогийн засвар" diff --git a/android/app/res/values-mr/strings_pbap.xml b/android/app/res/values-mr/strings_pbap.xml index c711268d2e4..65d2b474385 100644 --- a/android/app/res/values-mr/strings_pbap.xml +++ b/android/app/res/values-mr/strings_pbap.xml @@ -13,4 +13,6 @@ "माझे नाव" "000000" "ब्लूटूथ संपर्क शेअर" + "फोनबुकच्या प्रगत वैशिष्ट्याला सपोर्ट आहे" + "फोनबुकच्या प्रगत वैशिष्ट्यासाठी पुन्हा पेअर करा" diff --git a/android/app/res/values-ms/strings_pbap.xml b/android/app/res/values-ms/strings_pbap.xml index 46c7a091116..23fa745c0ee 100644 --- a/android/app/res/values-ms/strings_pbap.xml +++ b/android/app/res/values-ms/strings_pbap.xml @@ -13,4 +13,6 @@ "Nama saya" "000000" "Perkongsian Kenalan melalui Bluetooth" + "Ciri Lanjutan Buku Telefon Disokong" + "Gandingkan semula bagi Ciri Lanjutan Buku Telefon" diff --git a/android/app/res/values-my/strings_pbap.xml b/android/app/res/values-my/strings_pbap.xml index 6d8d3f7409f..f0285a45c84 100644 --- a/android/app/res/values-my/strings_pbap.xml +++ b/android/app/res/values-my/strings_pbap.xml @@ -13,4 +13,6 @@ "ကျွန်ုပ်နာမည်" "၀၀၀၀၀၀" "ဘလူးတုသ်ဖြင့် အဆက်အသွယ်မျှဝေခြင်း" + "‘ဖုန်းစာအုပ် အဆင့်မြင့်တူးလ်’ ကို ပံ့ပိုးထားသည်" + "‘အဆင့်မြင့်ဖုန်းစာအုပ် တူးလ်’ အတွက် ပြန်လည်တွဲချိတ်ရန်" diff --git a/android/app/res/values-nb/strings_pbap.xml b/android/app/res/values-nb/strings_pbap.xml index 863aad9ebbe..25d9acab304 100644 --- a/android/app/res/values-nb/strings_pbap.xml +++ b/android/app/res/values-nb/strings_pbap.xml @@ -13,4 +13,6 @@ "Navnet mitt" "000000" "Bluetooth Contact-deling" + "Advance-funksjonen i telefonboken støttes" + "Ny tilkobling for Advance-funksjonen i telefonboken" diff --git a/android/app/res/values-ne/strings_pbap.xml b/android/app/res/values-ne/strings_pbap.xml index 6c544648b5f..cb244056ac3 100644 --- a/android/app/res/values-ne/strings_pbap.xml +++ b/android/app/res/values-ne/strings_pbap.xml @@ -13,4 +13,6 @@ "मेरो नाम" "००००००" "ब्लुटुथमार्फत सम्पर्कको आदान प्रदान" + "फोनबुकको उन्नत सुविधा प्रयोग गर्न मिल्छ" + "फोनबुकको उन्नत सुविधा प्रयोग गर्न फेरि ब्लुटुथमा कनेक्ट गर्नुहोस्" diff --git a/android/app/res/values-nl/strings_pbap.xml b/android/app/res/values-nl/strings_pbap.xml index 393a675c169..588fc41894d 100644 --- a/android/app/res/values-nl/strings_pbap.xml +++ b/android/app/res/values-nl/strings_pbap.xml @@ -13,4 +13,6 @@ "Mijn naam" "000000" "Contacten delen via bluetooth" + "Geavanceerde telefoonboekfunctie ondersteund" + "Opnieuw koppelen voor geavanceerde telefoonboekfunctie" diff --git a/android/app/res/values-or/strings_pbap.xml b/android/app/res/values-or/strings_pbap.xml index 40c1e7f4d25..583a4707780 100644 --- a/android/app/res/values-or/strings_pbap.xml +++ b/android/app/res/values-or/strings_pbap.xml @@ -12,5 +12,7 @@ "ଅଜଣା ନାମ" "ମୋର ନାମ" "000000" - "ବ୍ଲୁଟୂଥ୍‍‌ ଯୋଗାଯୋଗ ସେୟାର୍‌ କରନ୍ତୁ" + "ବ୍ଲୁଟୂଥ କଣ୍ଟାକ୍ଟ ସେୟାର କରନ୍ତୁ" + "ଫୋନବୁକର ଉନ୍ନତ ଫିଚର ସମର୍ଥିତ ନୁହେଁ" + "ଉନ୍ନତ ଫୋନବୁକ ଫିଚର ପାଇଁ ପୁଣି-ପେୟାର କରନ୍ତୁ" diff --git a/android/app/res/values-pa/strings_pbap.xml b/android/app/res/values-pa/strings_pbap.xml index 3b4280a631d..e32a362a9c2 100644 --- a/android/app/res/values-pa/strings_pbap.xml +++ b/android/app/res/values-pa/strings_pbap.xml @@ -13,4 +13,6 @@ "ਮੇਰਾ ਨਾਮ" "000000" "ਬਲੂਟੁੱਥ ਸੰਪਰਕ ਸਾਂਝਾਕਰਨ" + "ਫ਼ੋਨ ਬੁੱਕ ਅਡਵਾਂਸ ਵਿਸ਼ੇਸ਼ਤਾਵਾਂ ਸਮਰਥਿਤ ਹੈ" + "ਅਡਵਾਂਸ ਫ਼ੋਨ ਬੁੱਕ ਵਿਸ਼ੇਸ਼ਤਾ ਲਈ ਮੁੜ-ਜੋੜਬੱਧ ਕਰੋ" diff --git a/android/app/res/values-pl/strings_pbap.xml b/android/app/res/values-pl/strings_pbap.xml index f6bdde786a8..94b88c4558b 100644 --- a/android/app/res/values-pl/strings_pbap.xml +++ b/android/app/res/values-pl/strings_pbap.xml @@ -13,4 +13,6 @@ "Moja nazwa" "000000" "Udostępnianie kontaktu przez Bluetooth" + "Obsługiwana jest zaawansowana funkcja książki telefonicznej" + "Sparuj ponownie, aby korzystać z zaawansowanej funkcji książki telefonicznej" diff --git a/android/app/res/values-pt-rPT/strings_pbap.xml b/android/app/res/values-pt-rPT/strings_pbap.xml index e61726684f7..4a15bd6f08d 100644 --- a/android/app/res/values-pt-rPT/strings_pbap.xml +++ b/android/app/res/values-pt-rPT/strings_pbap.xml @@ -13,6 +13,6 @@ "O meu nome" "000000" "Partilha de contactos por Bluetooth" - Recurso Avançado da Lista Telefônica Suportado - Re-par para Recurso Avançado Agenda + "Funcionalidade avançada da lista telefónica suportada" + "Volte a sincronizar para obter a funcionalidade avançada da lista telefónica" diff --git a/android/app/res/values-pt/strings_pbap.xml b/android/app/res/values-pt/strings_pbap.xml index b0c906715ee..bc6bb5e9363 100644 --- a/android/app/res/values-pt/strings_pbap.xml +++ b/android/app/res/values-pt/strings_pbap.xml @@ -13,6 +13,6 @@ "Meu nome" "000000" "Compartilhamento de contato via Bluetooth" - Recurso Avançado da Lista Telefônica Suportado - Re-par para Recurso Avançado Agenda + "Recurso avançado de agenda de contatos disponível" + "Parear novamente o recurso avançado de agenda de contatos" diff --git a/android/app/res/values-ro/strings_pbap.xml b/android/app/res/values-ro/strings_pbap.xml index b89401c0495..c12fc575ede 100644 --- a/android/app/res/values-ro/strings_pbap.xml +++ b/android/app/res/values-ro/strings_pbap.xml @@ -1,16 +1,18 @@ - "Introduceți cheia de sesiune pentru %1$s" + "Introdu cheia de sesiune pentru %1$s" "Cheie de sesiune Bluetooth solicitată" "A expirat timpul pentru acceptarea conexiunii cu %1$s" "A expirat timpul de introducere a cheii de sesiune cu %1$s" "Cerere de autentificare pentru protocolul OBEX" "Cheia sesiunii" - "Introduceți cheia de sesiune pentru %1$s" + "Introdu cheia de sesiune pentru %1$s" "Set de mașină" "Nume necunoscut" "Numele meu" "000000" "Distribuirea persoanei de contact prin Bluetooth" + "Este acceptată funcția Phonebook Advance" + "Asociază din nou pentru funcția Advance Phonebook" diff --git a/android/app/res/values-ru/strings_pbap.xml b/android/app/res/values-ru/strings_pbap.xml index a8b1b727677..46ad6c5652c 100644 --- a/android/app/res/values-ru/strings_pbap.xml +++ b/android/app/res/values-ru/strings_pbap.xml @@ -13,4 +13,6 @@ "Мое название" "000000" "Передача контактов по Bluetooth" + "Поддерживается продвинутая функция телефонной книги" + "Восстановление продвинутой функции телефонной книги" diff --git a/android/app/res/values-si/strings_pbap.xml b/android/app/res/values-si/strings_pbap.xml index f6e6d010b57..69435a81cf0 100644 --- a/android/app/res/values-si/strings_pbap.xml +++ b/android/app/res/values-si/strings_pbap.xml @@ -13,4 +13,6 @@ "මගේ නම" "000000" "බ්ලූටූත් සම්බන්ධතා බෙදා ගැනීම" + "දුරකථන නාමාවලි උසස් විශේෂාංගයට සහාය දක්වයි" + "උසස් දුරකථන නාමාවලි විශේෂාංගය සඳහා නැවත යුගල කරන්න" diff --git a/android/app/res/values-sk/strings_pbap.xml b/android/app/res/values-sk/strings_pbap.xml index 829e720af91..0ee5fc3127b 100644 --- a/android/app/res/values-sk/strings_pbap.xml +++ b/android/app/res/values-sk/strings_pbap.xml @@ -13,4 +13,6 @@ "Moje meno" "000000" "Zdieľanie kontaktov cez Bluetooth" + "Je podporovaná pokročilá funkcia telefónneho zoznamu" + "Oprava pokročilej funkcie telefónneho zoznamu" diff --git a/android/app/res/values-sl/strings_pbap.xml b/android/app/res/values-sl/strings_pbap.xml index 9ac34346923..601596f01bb 100644 --- a/android/app/res/values-sl/strings_pbap.xml +++ b/android/app/res/values-sl/strings_pbap.xml @@ -13,4 +13,6 @@ "Moje ime" "000000" "Deljenje stikov z drugimi prek Bluetootha" + "Napredna funkcija telefonskega imenika je podprta" + "Vnovična seznanitev za napredno funkcijo telefonskega imenika" diff --git a/android/app/res/values-sq/strings_pbap.xml b/android/app/res/values-sq/strings_pbap.xml index 0c0da34c596..0cc879c6e0d 100644 --- a/android/app/res/values-sq/strings_pbap.xml +++ b/android/app/res/values-sq/strings_pbap.xml @@ -13,4 +13,6 @@ "Emri im" "000000" "Ndarja e kontakteve me Bluetooth" + "Mbështetet \"Veçoria e përparuar e numëratorit telefonik\"" + "Çifto sërish për \"Veçorinë e përparuar të numëratorit telefonik\"" diff --git a/android/app/res/values-sr/strings_pbap.xml b/android/app/res/values-sr/strings_pbap.xml index 1fd8464d6c9..5a28f8c8bdd 100644 --- a/android/app/res/values-sr/strings_pbap.xml +++ b/android/app/res/values-sr/strings_pbap.xml @@ -13,4 +13,6 @@ "Моје име" "000000" "Дељење контаката преко Bluetooth-а" + "Подржана је напредна функција телефонског именика" + "Поновно упаривање за напредну функцију телефонског именика" diff --git a/android/app/res/values-sv/strings_pbap.xml b/android/app/res/values-sv/strings_pbap.xml index e5908af9958..7928caba922 100644 --- a/android/app/res/values-sv/strings_pbap.xml +++ b/android/app/res/values-sv/strings_pbap.xml @@ -13,4 +13,6 @@ "Mitt namn" "000000" "Kontaktdelning via Bluetooth" + "Avancerad telefonboksfunktion stöds" + "Parkoppla igen för avancerad telefonboksfunktion" diff --git a/android/app/res/values-sw/strings_pbap.xml b/android/app/res/values-sw/strings_pbap.xml index 0c38faf14b2..8c65d4ad847 100644 --- a/android/app/res/values-sw/strings_pbap.xml +++ b/android/app/res/values-sw/strings_pbap.xml @@ -13,4 +13,6 @@ "Jina langu" "000000" "Kushiriki Anwani kupitia Bluetooth" + "Kipengele cha Kina cha Orodha ya anwani Kinatumika" + "Rekebisha Kipengele cha Kina cha Orodha ya Anwani" diff --git a/android/app/res/values-ta/strings_pbap.xml b/android/app/res/values-ta/strings_pbap.xml index 99e5477a393..62da16e3853 100644 --- a/android/app/res/values-ta/strings_pbap.xml +++ b/android/app/res/values-ta/strings_pbap.xml @@ -13,4 +13,6 @@ "எனது பெயர்" "000000" "புளூடூத் தொடர்புப் பகிர்தல்" + "ஃபோன்புக் தொடர்பான மேம்பட்ட அம்சம் ஆதரிக்கப்படுகிறது" + "மேம்பட்ட ஃபோன்புக் அம்சத்திற்காக மீண்டும் இணைத்தல்" diff --git a/android/app/res/values-te/strings_pbap.xml b/android/app/res/values-te/strings_pbap.xml index fa300302bcf..2f231fb431d 100644 --- a/android/app/res/values-te/strings_pbap.xml +++ b/android/app/res/values-te/strings_pbap.xml @@ -13,4 +13,6 @@ "నా పేరు" "000000" "బ్లూటూత్ కాంటాక్ట్ షేర్" + "ఫోన్‌బుక్‌కు సంబంధించిన అధునాతన ఫీచర్ సపోర్ట్ చేయబడుతుంది" + "అధునాతన ఫోన్‌బుక్ ఫీచర్‌ను ఉపయోగించడానికి, మళ్లీ పెయిర్ చేయండి" diff --git a/android/app/res/values-th/strings_pbap.xml b/android/app/res/values-th/strings_pbap.xml index 06805da436d..6692631cf2e 100644 --- a/android/app/res/values-th/strings_pbap.xml +++ b/android/app/res/values-th/strings_pbap.xml @@ -13,4 +13,6 @@ "ชื่อของฉัน" "000000" "การแชร์รายชื่อติดต่อทางบลูทูธ" + "รองรับฟีเจอร์สมุดโทรศัพท์ขั้นสูง" + "จับคู่อีกครั้งเพื่อใช้ฟีเจอร์สมุดโทรศัพท์ขั้นสูง" diff --git a/android/app/res/values-tl/strings_pbap.xml b/android/app/res/values-tl/strings_pbap.xml index 7854825bd01..3eb4a969016 100644 --- a/android/app/res/values-tl/strings_pbap.xml +++ b/android/app/res/values-tl/strings_pbap.xml @@ -13,4 +13,6 @@ "Aking pangalan" "000000" "Pagbabahagi ng Contact sa Bluetooth" + "Sinusuportahan ang Advance Feature ng Phonebook" + "Ipares ulit para sa Advance Feature ng Phonebook" diff --git a/android/app/res/values-tr/strings_pbap.xml b/android/app/res/values-tr/strings_pbap.xml index e7ed7b85a45..04bc50424b5 100644 --- a/android/app/res/values-tr/strings_pbap.xml +++ b/android/app/res/values-tr/strings_pbap.xml @@ -13,4 +13,6 @@ "Adım" "000000" "Bluetooth Kişi paylaşımı" + "Telefon Rehberi İleri Seviye Özelliği Desteklenir" + "İleri Seviye Telefon Rehberi Özelliği için Yeniden Eşleştirme" diff --git a/android/app/res/values-uk/strings_pbap.xml b/android/app/res/values-uk/strings_pbap.xml index f7922afe6ad..0ea877e4a1b 100644 --- a/android/app/res/values-uk/strings_pbap.xml +++ b/android/app/res/values-uk/strings_pbap.xml @@ -13,4 +13,6 @@ "Моє ім\'я" "000000" "Надсилання контактів Bluetooth" + "Підтримка розширеної функції телефонної книги" + "Повторне підключення розширеної функції телефонної книги" diff --git a/android/app/res/values-ur/strings_pbap.xml b/android/app/res/values-ur/strings_pbap.xml index 29818443a96..28b291920ec 100644 --- a/android/app/res/values-ur/strings_pbap.xml +++ b/android/app/res/values-ur/strings_pbap.xml @@ -13,4 +13,6 @@ "میرا نام" "000000" "بلوٹوتھ رابطہ اشتراک" + "فون بک اعلی خصوصیات تعاون یافتہ ہے" + "فون بک کی اعلی خصوصیات کی مرمت" diff --git a/android/app/res/values-uz/strings_pbap.xml b/android/app/res/values-uz/strings_pbap.xml index 0800a6e1a36..37304692bdb 100644 --- a/android/app/res/values-uz/strings_pbap.xml +++ b/android/app/res/values-uz/strings_pbap.xml @@ -13,4 +13,6 @@ "Ismim" "000000" "Kontaktlarni Bluetooth orqali yuborish" + "Telefon kitobchasi kengaytirilgan funksiyalari ishlaydi" + "Telefon kitobchasi kengaytirilgan funksiyalarini tuzatish" diff --git a/android/app/res/values-vi/strings_pbap.xml b/android/app/res/values-vi/strings_pbap.xml index fb57f04384c..f2a552f96d0 100644 --- a/android/app/res/values-vi/strings_pbap.xml +++ b/android/app/res/values-vi/strings_pbap.xml @@ -13,4 +13,6 @@ "Tên của tôi" "000000" "Chia sẻ liên hệ qua Bluetooth" + "Có hỗ trợ tính năng nâng cao dành cho danh bạ điện thoại" + "Hãy ghép nối lại để dùng tính năng nâng cao dành cho danh bạ điện thoại" diff --git a/android/app/res/values-zh-rCN/strings_pbap.xml b/android/app/res/values-zh-rCN/strings_pbap.xml index 67a14d2a11c..60fbe171c00 100644 --- a/android/app/res/values-zh-rCN/strings_pbap.xml +++ b/android/app/res/values-zh-rCN/strings_pbap.xml @@ -13,4 +13,6 @@ "我的名字" "000000" "通过蓝牙分享联系人" + "支持电话簿高级功能" + "重新配对以使用高级电话簿功能" diff --git a/android/app/res/values-zh-rHK/strings_pbap.xml b/android/app/res/values-zh-rHK/strings_pbap.xml index c1b6af5fdd5..ef0ac40f1ec 100644 --- a/android/app/res/values-zh-rHK/strings_pbap.xml +++ b/android/app/res/values-zh-rHK/strings_pbap.xml @@ -13,4 +13,6 @@ "我的姓名" "000000" "藍牙聯絡人分享" + "支援電話簿進階功能" + "為進階電話簿功能而重新配對" diff --git a/android/app/res/values-zh-rTW/strings_pbap.xml b/android/app/res/values-zh-rTW/strings_pbap.xml index d11dff893cb..11df8847dc2 100644 --- a/android/app/res/values-zh-rTW/strings_pbap.xml +++ b/android/app/res/values-zh-rTW/strings_pbap.xml @@ -13,4 +13,6 @@ "我的名稱" "000000" "藍牙聯絡人分享" + "支援電話簿進階功能" + "重新配對以使用進階電話簿功能" diff --git a/android/app/res/values-zu/strings_pbap.xml b/android/app/res/values-zu/strings_pbap.xml index fb554a2fb0c..9031b665d60 100644 --- a/android/app/res/values-zu/strings_pbap.xml +++ b/android/app/res/values-zu/strings_pbap.xml @@ -13,4 +13,6 @@ "Igama lami" "000000" "Ukwabelana koxhumana nabo kwe-Bluetooth" + "Isakhi Esithuthukisiwe Sezinombolo Zokuxhumana Ezisekelwe" + "Lungisa kabusha Isakhi Sezinombolo Zokuxhumana Esithuthukisiwe" -- GitLab From 69aeda9feac8590bb2fbf628867f151a40881c28 Mon Sep 17 00:00:00 2001 From: Bill Yi Date: Sat, 22 Apr 2023 00:14:04 -0700 Subject: [PATCH 0024/2405] Import translations. DO NOT MERGE ANYWHERE Auto-generated-cl: translation import Change-Id: Ic971e0f91f8bb101c3cff49d2f176f8b852fc381 --- android/app/res/values-as/strings_sap.xml | 4 ++-- android/app/res/values-en-rCA/strings_sap.xml | 2 +- android/app/res/values-ro/strings_sap.xml | 6 +++--- android/app/res/values-te/strings_sap.xml | 2 +- 4 files changed, 7 insertions(+), 7 deletions(-) diff --git a/android/app/res/values-as/strings_sap.xml b/android/app/res/values-as/strings_sap.xml index f886e47fa17..f18138bb0b1 100644 --- a/android/app/res/values-as/strings_sap.xml +++ b/android/app/res/values-as/strings_sap.xml @@ -1,8 +1,8 @@ - "ব্লুটুথৰ ছিম ব্যৱহাৰ" - "ব্লুটুথৰ ছিম ব্যৱহাৰ" + "ব্লুটুথৰ ছিম এক্সেছ" + "ব্লুটুথৰ ছিম এক্সেছ" "সংযোগ বিচ্ছিন্ন কৰিবলৈ ক্লায়েণ্টক অনুৰোধ কৰিবনে?" "সংযোগ বিচ্ছিন্ন কৰিবলৈ ক্লায়েণ্টৰ অপেক্ষা কৰি থকা হৈছে" "বিচ্ছিন্ন কৰক" diff --git a/android/app/res/values-en-rCA/strings_sap.xml b/android/app/res/values-en-rCA/strings_sap.xml index 29288d1eff1..06566412888 100644 --- a/android/app/res/values-en-rCA/strings_sap.xml +++ b/android/app/res/values-en-rCA/strings_sap.xml @@ -2,7 +2,7 @@ "Bluetooth SIM access" - "Bluetooth SIM access" + "Bluetooth SIM Access" "Request client to disconnect?" "Waiting for client to disconnect" "Disconnect" diff --git a/android/app/res/values-ro/strings_sap.xml b/android/app/res/values-ro/strings_sap.xml index 2dbe4bf41da..c48400b6903 100644 --- a/android/app/res/values-ro/strings_sap.xml +++ b/android/app/res/values-ro/strings_sap.xml @@ -3,8 +3,8 @@ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> "Accesul la SIM prin Bluetooth" "Accesul la SIM prin Bluetooth" - "Solicitați clientului să se deconecteze?" + "Soliciți clientului să se deconecteze?" "Se așteaptă deconectarea clientului" - "Deconectați-vă" - "Deconectați forțat" + "Deconectează-te" + "Deconectează forțat" diff --git a/android/app/res/values-te/strings_sap.xml b/android/app/res/values-te/strings_sap.xml index d52a8efa627..0bad366ec6f 100644 --- a/android/app/res/values-te/strings_sap.xml +++ b/android/app/res/values-te/strings_sap.xml @@ -5,6 +5,6 @@ "బ్లూటూత్ SIM యాక్సెస్" "డిస్‌కనెక్ట్ చేయడానికి క్లయింట్‌ను అభ్యర్థించాలా?" "డిస్‌కనెక్ట్ చేయడానికి క్లయింట్ కోసం వేచి ఉంది" - "డిస్‌కనెక్ట్ చేయి" + "డిస్‌కనెక్ట్ చేయండి" "నిర్బంధంగా డిస్‌కనెక్ట్ చేయి" -- GitLab From 8b65304f4c2c46e7cc60ee39b82f080bcd306606 Mon Sep 17 00:00:00 2001 From: Bill Yi Date: Sat, 22 Apr 2023 00:14:35 -0700 Subject: [PATCH 0025/2405] Import translations. DO NOT MERGE ANYWHERE Auto-generated-cl: translation import Change-Id: I62eee311e4218a04209fe460455d6a631ca53361 --- android/app/res/values-af/strings.xml | 13 ++-- android/app/res/values-am/strings.xml | 15 +++-- android/app/res/values-ar/strings.xml | 17 +++-- android/app/res/values-as/strings.xml | 21 +++--- android/app/res/values-az/strings.xml | 13 ++-- android/app/res/values-b+sr+Latn/strings.xml | 13 ++-- android/app/res/values-be/strings.xml | 13 ++-- android/app/res/values-bg/strings.xml | 13 ++-- android/app/res/values-bn/strings.xml | 21 +++--- android/app/res/values-bs/strings.xml | 23 ++++--- android/app/res/values-ca/strings.xml | 13 ++-- android/app/res/values-cs/strings.xml | 13 ++-- android/app/res/values-da/strings.xml | 13 ++-- android/app/res/values-de/strings.xml | 17 +++-- android/app/res/values-el/strings.xml | 17 +++-- android/app/res/values-en-rAU/strings.xml | 13 ++-- android/app/res/values-en-rCA/strings.xml | 35 +++++----- android/app/res/values-en-rGB/strings.xml | 13 ++-- android/app/res/values-en-rIN/strings.xml | 13 ++-- android/app/res/values-en-rXC/strings.xml | 13 ++-- android/app/res/values-es-rUS/strings.xml | 15 +++-- android/app/res/values-es/strings.xml | 15 +++-- android/app/res/values-et/strings.xml | 13 ++-- android/app/res/values-eu/strings.xml | 31 +++++---- android/app/res/values-fa/strings.xml | 15 +++-- android/app/res/values-fi/strings.xml | 15 +++-- android/app/res/values-fr-rCA/strings.xml | 21 +++--- android/app/res/values-fr/strings.xml | 13 ++-- android/app/res/values-gl/strings.xml | 13 ++-- android/app/res/values-gu/strings.xml | 13 ++-- android/app/res/values-hi/strings.xml | 25 +++++--- android/app/res/values-hr/strings.xml | 29 +++++---- android/app/res/values-hu/strings.xml | 13 ++-- android/app/res/values-hy/strings.xml | 35 +++++----- android/app/res/values-in/strings.xml | 31 +++++---- android/app/res/values-is/strings.xml | 13 ++-- android/app/res/values-it/strings.xml | 13 ++-- android/app/res/values-iw/strings.xml | 13 ++-- android/app/res/values-ja/strings.xml | 15 +++-- android/app/res/values-ka/strings.xml | 13 ++-- android/app/res/values-kk/strings.xml | 19 ++++-- android/app/res/values-km/strings.xml | 29 +++++---- android/app/res/values-kn/strings.xml | 19 ++++-- android/app/res/values-ko/strings.xml | 17 +++-- android/app/res/values-ky/strings.xml | 43 +++++++------ android/app/res/values-lo/strings.xml | 19 ++++-- android/app/res/values-lt/strings.xml | 13 ++-- android/app/res/values-lv/strings.xml | 13 ++-- android/app/res/values-mk/strings.xml | 31 +++++---- android/app/res/values-ml/strings.xml | 23 ++++--- android/app/res/values-mn/strings.xml | 13 ++-- android/app/res/values-mr/strings.xml | 17 +++-- android/app/res/values-ms/strings.xml | 17 +++-- android/app/res/values-my/strings.xml | 19 ++++-- android/app/res/values-nb/strings.xml | 13 ++-- android/app/res/values-ne/strings.xml | 29 +++++---- android/app/res/values-nl/strings.xml | 21 +++--- android/app/res/values-or/strings.xml | 35 +++++----- android/app/res/values-pa/strings.xml | 25 +++++--- android/app/res/values-pl/strings.xml | 13 ++-- android/app/res/values-pt-rPT/strings.xml | 19 ++++-- android/app/res/values-pt/strings.xml | 35 +++++----- android/app/res/values-ro/strings.xml | 67 +++++++++++--------- android/app/res/values-ru/strings.xml | 13 ++-- android/app/res/values-si/strings.xml | 13 ++-- android/app/res/values-sk/strings.xml | 13 ++-- android/app/res/values-sl/strings.xml | 13 ++-- android/app/res/values-sq/strings.xml | 13 ++-- android/app/res/values-sr/strings.xml | 13 ++-- android/app/res/values-sv/strings.xml | 13 ++-- android/app/res/values-sw/strings.xml | 15 +++-- android/app/res/values-ta/strings.xml | 13 ++-- android/app/res/values-te/strings.xml | 43 +++++++------ android/app/res/values-th/strings.xml | 13 ++-- android/app/res/values-tl/strings.xml | 17 +++-- android/app/res/values-tr/strings.xml | 13 ++-- android/app/res/values-uk/strings.xml | 15 +++-- android/app/res/values-ur/strings.xml | 13 ++-- android/app/res/values-uz/strings.xml | 13 ++-- android/app/res/values-vi/strings.xml | 15 +++-- android/app/res/values-zh-rCN/strings.xml | 15 +++-- android/app/res/values-zh-rHK/strings.xml | 15 +++-- android/app/res/values-zh-rTW/strings.xml | 13 ++-- android/app/res/values-zu/strings.xml | 13 ++-- 84 files changed, 986 insertions(+), 566 deletions(-) diff --git a/android/app/res/values-af/strings.xml b/android/app/res/values-af/strings.xml index 85eca9b42e0..b48fae73814 100644 --- a/android/app/res/values-af/strings.xml +++ b/android/app/res/values-af/strings.xml @@ -23,6 +23,7 @@ "Bluetooth" "Onbekende toestel" "Onbekend" + "Nie verskaf nie" "Vliegtuigmodus" "Jy kan nie Bluetooth in vliegtuigmodus gebruik nie." @@ -109,10 +110,8 @@ "Alle items sal uit die lys verwyder word." "Bluetooth-deling: Gestuurde lêers" "Bluetooth-deling: Ontvangde lêers" - - - - + "{count,plural, =1{# onsuksesvol.}other{# onsuksesvol.}}" + "{count,plural, =1{# suksesvol, %1$s}other{# suksesvol, %1$s}}" "Vee lys uit" "Open" "Verwyder uit lys" @@ -130,4 +129,10 @@ "Bluetooth-oudio" "Lêers groter as 4 GB kan nie oorgedra word nie" "Koppel aan Bluetooth" + "Bluetooth is aan in vliegtuigmodus" + "As jy Bluetooth aangeskakel hou, sal jou foon onthou om dit aan te hou wanneer jy weer in vliegtuigmodus is" + "Bluetooth bly aan" + "Jou foon onthou om Bluetooth aangeskakel te hou in vliegtuigmodus. Skakel Bluetooth af as jy nie wil hê dit moet aan bly nie." + "Wi-fi en Bluetooth bly aan" + "Jou foon onthou om wi‑fi en Bluetooth aan te hou in vliegtuigmodus. Skakel wi-fi en Bluetooth af as jy nie wil het hulle moet aan bly nie." diff --git a/android/app/res/values-am/strings.xml b/android/app/res/values-am/strings.xml index 2191a25d21e..6b8449e5f6c 100644 --- a/android/app/res/values-am/strings.xml +++ b/android/app/res/values-am/strings.xml @@ -23,6 +23,7 @@ "ብሉቱዝ" "ያልታወቀ መሣሪያ" "ያልታወቀ" + "አልቀረበም" "የአውሮፕላን ሁነታ" "ብሉቱዝበአውሮፕላን ሁነትመጠቀም አይችሉም።" @@ -104,15 +105,13 @@ "%1$s ተቀብሎ ተጠናቋል።" "%1$s ልኮ ተጠናቋል።" "ወደ ውስጥ ማስተላለፍ" - "ወደ ውጪ ማስተላለፍ" + "ወደ ውጭ ማስተላለፍ" "የዝውውር ታሪክ ባዶ ነው።" "ሁሉም ዓይነቶች ከዝርዝር ውስጥ ይሰረዛሉ።" "ብሉቱዝ ማጋሪያ፡ የተላኩ ፋይሎች" "ብሉቱዝ ማጋሪያ፡ የደረሱ ፋይሎች" - - - - + "{count,plural, =1{# አልተሳካም።}one{# አልተሳካም።}other{# አልተሳኩም።}}" + "{count,plural, =1{# ተሳክቷል፣ %1$s}one{# ተሳክቷል፣ %1$s}other{# ተሳክተዋል፣ %1$s}}" "ዝርዝር አጽዳ" "ክፈት" "ከዝርዝር አጽዳ" @@ -130,4 +129,10 @@ "የብሉቱዝ ኦዲዮ" "ከ4 ጊባ በላይ የሆኑ ፋይሎች ሊዛወሩ አይችሉም" "ከብሉቱዝ ጋር ተገናኝ" + "ብሉቱዝ በአውሮፕላን ሁነታ ላይ በርቷል" + "ብሉቱዝን አብርተው ካቆዩ በቀጣይ ጊዜ በአውሮፕላን ሁነታ ውስጥ ሲሆኑ ስልክዎ እሱን አብርቶ ማቆየቱን ያስታውሳል" + "ብሉቱዝ በርቶ ይቆያል" + "ስልክዎ ብሉቱዝን በአውሮፕላን ሁነታ ውስጥ አብርቶ ማቆየትን ያስታውሳል። በርቶ እንዲቆይ ካልፈለጉ ብሉቱዝን ያጥፉት።" + "Wi-Fi እና ብሉቱዝ በርተው ይቆያሉ" + "ስልክዎ Wi-Fiን እና ብሉቱዝን በአውሮፕላን ሁነታ ውስጥ አብርቶ ማቆየትን ያስታውሳል። በርተው እንዲቆዩ ካልፈለጉ Wi-Fi እና ብሉቱዝን ያጥፏቸው።" diff --git a/android/app/res/values-ar/strings.xml b/android/app/res/values-ar/strings.xml index f3390112128..c6f7396342c 100644 --- a/android/app/res/values-ar/strings.xml +++ b/android/app/res/values-ar/strings.xml @@ -23,6 +23,7 @@ "بلوتوث" "جهاز غير معروف" "غير معروف" + "غير متوفر" "وضع الطيران" "لا يمكنك استخدام البلوتوث في وضع الطيران." @@ -37,7 +38,7 @@ "حسنًا" "انتهت المهلة أثناء قبول ملف وراد من \"%1$s\"" "ملف وارد" - "%1$s على استعداد لإرسال ملف: %2$s" + "‏‫%1$s على استعداد لإرسال ملف: %2$s" "مشاركة البلوتوث: يتم استلام %1$s" "مشاركة البلوتوث: تم استلام %1$s" "مشاركة البلوتوث: لم يتم استلام الملف %1$s" @@ -109,15 +110,13 @@ "سيتم محو جميع العناصر من القائمة." "مشاركة البلوتوث: الملفات المرسلة" "مشاركة البلوتوث: الملفات المستلمة" - - - - + "{count,plural, =1{وتعذّر إرسال ملف واحد.}zero{وتعذّر إرسال # ملف.}two{وتعذّر إرسال ملفين.}few{وتعذّر إرسال # ملفات.}many{وتعذّر إرسال # ملفًا.}other{وتعذّر إرسال # ملف.}}" + "{count,plural, =1{‏تم إرسال ملف واحد بنجاح، %1$s}zero{‏تم إرسال # ملف بنجاح، %1$s}two{‏تم إرسال ملفين بنجاح، %1$s}few{‏تم إرسال # ملفات بنجاح، %1$s}many{‏تم إرسال # ملفًا بنجاح، %1$s}other{‏تم إرسال # ملف بنجاح، %1$s}}" "محو القائمة" "فتح" "محو من القائمة" "محو" - "التعرّف التلقائي على الموسيقى" + "قيد التشغيل الآن" "حفظ" "إلغاء" "حدد الحسابات التي تريد مشاركتها عبر البلوتوث. لا يزال يتعين عليك قبول أي دخول إلى الحسابات أثناء الاتصال." @@ -130,4 +129,10 @@ "بث صوتي عبر البلوتوث" "يتعذّر نقل الملفات التي يزيد حجمها عن 4 غيغابايت" "الاتصال ببلوتوث" + "تقنية البلوتوث مفعّلة في \"وضع الطيران\"" + "إذا واصلت تفعيل تقنية البلوتوث، سيتذكر هاتفك إبقاءها مفعَّلة في المرة القادمة التي تفعِّل فيها \"وضع الطيران\"." + "تظل تقنية البلوتوث مفعّلة" + "يتذكر هاتفك الاحتفاظ بتقنية البلوتوث مفعَّلة في \"وضع الطيران\". يمكنك إيقاف تقنية البلوتوث إذا لم تكن تريد مواصلة تفعيلها." + "‏تظل شبكة Wi‑Fi وتقنية البلوتوث مفعَّلتَين." + "‏يتذكر هاتفك الاحتفاظ بشبكة Wi‑Fi وتقنية البلوتوث مفعَّلتَين في \"وضع الطيران\". يمكنك إيقاف شبكة Wi‑Fi وتقنية البلوتوث إذا لم تكن تريد مواصلة تفعيلهما." diff --git a/android/app/res/values-as/strings.xml b/android/app/res/values-as/strings.xml index b240d68cf41..bcc4a27c942 100644 --- a/android/app/res/values-as/strings.xml +++ b/android/app/res/values-as/strings.xml @@ -16,13 +16,14 @@ - "ডাউনল’ড মেনেজাৰ ব্যৱহাৰ কৰিব পাৰে।" - "এপটোক BluetoothShare মেনেজাৰ ব্যৱহাৰ কৰি ফাইল স্থানান্তৰ কৰিবলৈ অনুমতি দিয়ে।" + "ডাউনল’ড মেনেজাৰ এক্সেছ কৰিব পাৰে।" + "এপ্‌টোক BluetoothShare মেনেজাৰ ব্যৱহাৰ কৰি ফাইল স্থানান্তৰ কৰিবলৈ অনুমতি দিয়ে।" "ব্লুটুথ ডিভাইচ এক্সেছ কৰাৰ স্বীকৃতি দিয়ে।" "এপ্‌টোক এটা ব্লুটুথ ডিভাইচ অস্থায়ীৰূপে স্বীকাৰ কৰাৰ অনুমতি দিয়ে যিয়ে ডিভাইচটোক ব্যৱহাৰকাৰীৰ নিশ্চিতিকৰণৰ অবিহনেই ইয়ালৈ ফাইল পঠিওৱাৰ অনুমতি দিয়ে।" "ব্লুটুথ" "অজ্ঞাত ডিভাইচ" "অজ্ঞাত" + "প্ৰদান কৰা হোৱা নাই" "এয়াৰপ্লে’ন ম’ড" "আপুনি এয়াৰপ্লেইন ম\'ডত ব্লুটুথ ব্যৱহাৰ কৰিব নোৱাৰে।" @@ -86,7 +87,7 @@ "ফাইলটো ছেভ কৰিব পৰাকৈ ইউএছবি ষ্ট’ৰেজত পৰ্যাপ্ত খালী ঠাই নাই।" "ফাইলটো ছেভ কৰিব পৰাকৈ এছডি কাৰ্ডখনত পৰ্যাপ্ত খালী ঠাই নাই।" "ইমান খালী ঠাইৰ দৰকাৰ: %1$s" - "বহুত বেছি অনুৰোধৰ ওপৰত প্ৰক্ৰিয়া চলি আছে৷ পিছত আকৌ চেষ্টা কৰক৷" + "বহুত বেছি অনুৰোধৰ ওপৰত প্ৰক্ৰিয়া চলি আছে৷ পাছত আকৌ চেষ্টা কৰক৷" "ফাইলৰ স্থানান্তৰণ এতিয়ালৈকে আৰম্ভ হোৱা নাই।" "ফাইলৰ স্থানান্তৰণ চলি আছে।" "ফাইলৰ স্থানান্তৰণৰ কাৰ্য সফলতাৰে সম্পন্ন কৰা হ’ল।" @@ -109,10 +110,8 @@ "আটাইবোৰ সমল সূচীৰ পৰা মচা হ\'ব।" "ব্লুটুথ শ্বেয়াৰ: প্ৰেৰণ কৰা ফাইলসমূহ" "ব্লুটুথ শ্বেয়াৰ: লাভ কৰা ফাইলসমূহ" - - - - + "{count,plural, =1{# টা বিফল হৈছে।}one{# টা বিফল হৈছে।}other{# টা বিফল হৈছে।}}" + "{count,plural, =1{# টা সফল হৈছে, %1$s}one{# টা সফল হৈছে, %1$s}other{# টা সফল হৈছে, %1$s}}" "সূচী মচক" "খোলক" "সূচীৰ পৰা মচক" @@ -120,7 +119,7 @@ "এতিয়া প্লে’ হৈ আছে" "ছেভ কৰক" "বাতিল কৰক" - "ব্লুটুথৰ জৰিয়তে শ্বেয়াৰ কৰিব খোজা একাউণ্টসমূহ বাছক। তথাপিও সংযোগ কৰি থাকোঁতে আপুনি একাউণ্টসমূহক সকলো ধৰণৰ অনুমতি দিবই লাগিব।" + "ব্লুটুথৰ জৰিয়তে শ্বেয়াৰ কৰিব খোজা একাউণ্টসমূহ বাছক। তথাপিও সংযোগ কৰি থাকোঁতে আপুনি একাউণ্টসমূহক সকলো ধৰণৰ এক্সেছ দিবই লাগিব।" "বাকী থকা শ্লটবোৰ:" "এপ্লিকেশ্বন আইকন" "ব্লুটুথৰ জৰিয়তে বাৰ্তা শ্বেয়াৰ কৰাৰ ছেটিং" @@ -130,4 +129,10 @@ "ব্লুটুথ অডিঅ\'" "৪ জি. বি. তকৈ ডাঙৰ ফাইল স্থানান্তৰ কৰিব নোৱাৰি" "ব্লুটুথৰ সৈতে সংযোগ কৰক" + "এয়াৰপ্লেন ম’ডত ব্লুটুথ অন হৈ থাকিব" + "আপুনি যদি ব্লুটুথ অন কৰি ৰাখে, পৰৱৰ্তী সময়ত আপুনি এয়াৰপ্লেন ম’ড ব্যৱহাৰ কৰিলে আপোনাৰ ফ’নটোৱে এয়া অন কৰি ৰাখিবলৈ মনত ৰাখিব" + "ব্লুটুথ অন হৈ থাকে" + "আপোনাৰ ফ’নটোৱে এয়াৰপ্লেন ম’ডত ব্লুটুথ অন ৰাখিবলৈ মনত ৰাখে। আপুনি যদি ব্লুটুথ অন হৈ থকাটো নিবিচাৰে, তেন্তে ইয়াক অফ কৰক।" + "ৱাই-ফাই আৰু ব্লুটুথ অন হৈ থাকে" + "আপোনাৰ ফ’নটোৱে এয়াৰপ্লেন ম’ডত ৱাই-ফাই আৰু ব্লুটুথ অন ৰাখিবলৈ মনত ৰাখে। আপুনি ৱাই-ফাই আৰু ব্লুটুথ অন হৈ থকাটো নিবিচাৰিলে সেইবোৰ অফ কৰক।" diff --git a/android/app/res/values-az/strings.xml b/android/app/res/values-az/strings.xml index af246733418..ec63e9583da 100644 --- a/android/app/res/values-az/strings.xml +++ b/android/app/res/values-az/strings.xml @@ -23,6 +23,7 @@ "Bluetooth" "Naməlum cihaz" "Naməlum" + "Təmin edilməyib" "Təyyarə rejimi" "Təyyarə rejimində Bluetooth istifadə edə bilməzsiniz." @@ -109,10 +110,8 @@ "Bütün məlumatlar siyahıdan silinəcək." "Bluetooth paylaşım: Göndərilmiş fayllar" "Bluetooth paylaşım: Qəbul edilən fayllar" - - - - + "{count,plural, =1{# uğursuz.}other{# uğursuz.}}" + "{count,plural, =1{# uğurlu, %1$s}other{# uğurlu, %1$s}}" "Siyahını silin" "Açın" "Siyahıdan silin" @@ -130,4 +129,10 @@ "Bluetooth audio" "4GB-dən böyük olan faylları köçürmək mümkün deyil" "Bluetooth\'a qoşulun" + "Bluetooth təyyarə rejimində aktivdir" + "Bluetooth\'u aktiv saxlasanız, növbəti dəfə təyyarə rejimində olduqda telefonunuz onu aktiv saxlayacaq" + "Bluetooth aktiv qalacaq" + "Telefonunuz təyyarə rejimində Bluetooth\'u aktiv saxlayacaq. Aktiv qalmasını istəmirsinizsə, Bluetooth\'u deaktiv edin." + "Wi-Fi və Bluetooth aktiv qalır" + "Telefonunuz təyyarə rejimində Wi‑Fi və Bluetooth\'u aktiv saxlayacaq. Aktiv qalmasını istəmirsinizsə, Wi-Fi və Bluetooth\'u deaktiv edin." diff --git a/android/app/res/values-b+sr+Latn/strings.xml b/android/app/res/values-b+sr+Latn/strings.xml index 73d340855bb..e9548e2f298 100644 --- a/android/app/res/values-b+sr+Latn/strings.xml +++ b/android/app/res/values-b+sr+Latn/strings.xml @@ -23,6 +23,7 @@ "Bluetooth" "Nepoznati uređaj" "Nepoznato" + "Nije navedeno" "Režim rada u avionu" "Ne možete da koristite Bluetooth u režimu rada u avionu." @@ -109,10 +110,8 @@ "Sve stavke će biti izbrisane sa liste." "Deljenje preko Bluetooth-a: poslate datoteke" "Deljenje preko Bluetooth-a: primljene datoteke" - - - - + "{count,plural, =1{# neuspešno.}one{# neuspešno.}few{# neuspešna.}other{# neuspešnih.}}" + "{count,plural, =1{# uspešno, %1$s}one{# uspešno, %1$s}few{# uspešna, %1$s}other{# uspešnih, %1$s}}" "Obriši listu" "Otvori" "Obriši sa liste" @@ -130,4 +129,10 @@ "Bluetooth audio" "Ne mogu da se prenose datoteke veće od 4 GB" "Poveži sa Bluetooth-om" + "Bluetooth je uključen u režimu rada u avionu" + "Ako odlučite da ne isključujete Bluetooth, telefon će zapamtiti da ga ne isključuje sledeći put kada budete u režimu rada u avionu" + "Bluetooth se ne isključuje" + "Telefon pamti da ne treba da isključuje Bluetooth u režimu rada u avionu. Isključite Bluetooth ako ne želite da ostane uključen." + "WiFi i Bluetooth ostaju uključeni" + "Telefon pamti da ne treba da isključuje WiFi i Bluetooth u režimu rada u avionu. Isključite WiFi i Bluetooth ako ne želite da ostanu uključeni." diff --git a/android/app/res/values-be/strings.xml b/android/app/res/values-be/strings.xml index dadb0886628..ca6767e4a83 100644 --- a/android/app/res/values-be/strings.xml +++ b/android/app/res/values-be/strings.xml @@ -23,6 +23,7 @@ "Bluetooth" "Невядомая прылада" "Невядомы" + "Не прапанавана" "Рэжым палёту" "Вы не можаце выкарыстоўваць Bluetooth у рэжыме палёту." @@ -109,10 +110,8 @@ "Усе элементы будуць выдаленыя са спісу." "Перадача праз Bluetooth: адпраўленыя файлы" "Перадача праз Bluetooth: атрыманыя файлы" - - - - + "{count,plural, =1{не выканана: #.}one{не выканана: #.}few{не выканана: #.}many{не выканана: #.}other{не выканана: #.}}" + "{count,plural, =1{Выканана: #; %1$s}one{Выканана: #; %1$s}few{Выканана: #; %1$s}many{Выканана: #; %1$s}other{Выканана: #; %1$s}}" "Ачысціць спіс" "Адкрыць" "Выдаліць са спісу" @@ -130,4 +129,10 @@ "Bluetooth-аўдыя" "Немагчыма перадаць файлы, большыя за 4 ГБ" "Падключыцца да Bluetooth" + "У рэжыме палёту Bluetooth уключаны" + "Калі вы не выключыце Bluetooth, падчас наступнага пераходу ў рэжым палёту тэлефон будзе захоўваць яго ўключаным" + "Bluetooth застаецца ўключаным" + "На тэлефоне ў рэжыме палёту Bluetooth застанецца ўключаным, але вы можаце выключыць яго." + "Wi-Fi і Bluetooth застаюцца ўключанымі" + "На тэлефоне ў рэжыме палёту сетка Wi‑Fi і Bluetooth будуць заставацца ўключанымі, але вы можаце выключыць іх." diff --git a/android/app/res/values-bg/strings.xml b/android/app/res/values-bg/strings.xml index 5d595f12c97..22d88eb0591 100644 --- a/android/app/res/values-bg/strings.xml +++ b/android/app/res/values-bg/strings.xml @@ -23,6 +23,7 @@ "Bluetooth" "Неизвестно устройство" "Неизвестно" + "Не е предоставено" "Самолетен режим" "Не можете да използвате Bluetooth в самолетен режим." @@ -109,10 +110,8 @@ "Всички елементи ще бъдат премахнати от списъка." "Споделяне чрез Bluetooth: Изпратени файлове" "Споделяне чрез Bluetooth: Получени файлове" - - - - + "{count,plural, =1{# неуспешно.}other{# неуспешно.}}" + "{count,plural, =1{# успешно, %1$s}other{# успешно, %1$s}}" "Изчистване на списъка" "Отваряне" "Изчистване от списъка" @@ -130,4 +129,10 @@ "Аудио през Bluetooth" "Файловете с размер над 4 ГБ не могат да бъдат прехвърлени" "Свързване с Bluetooth" + "Функцията за Bluetooth е включена в самолетния режим" + "Ако не изключите функцията за Bluetooth, телефонът ви ще я остави активна следващия път, когато използвате самолетния режим" + "Функцията за Bluetooth няма да се изключи" + "Функцията за Bluetooth ще бъде включена, докато телефонът ви е в самолетен режим. Ако не искате това, изключете я." + "Функциите за Wi-Fi и Bluetooth няма да бъдат изключени" + "Функциите за Wi‑Fi и Bluetooth ще бъдат включени, докато телефонът ви е в самолетен режим. Ако не искате това, изключете ги." diff --git a/android/app/res/values-bn/strings.xml b/android/app/res/values-bn/strings.xml index c26d95c9953..e83784183fc 100644 --- a/android/app/res/values-bn/strings.xml +++ b/android/app/res/values-bn/strings.xml @@ -23,6 +23,7 @@ "ব্লুটুথ" "অজানা ডিভাইস" "অজানা" + "প্রদান করা হয়নি" "বিমান মোড" "আপনি বিমান মোডে ব্লুটুথ ব্যবহার করতে পারবেন না।" @@ -41,8 +42,8 @@ "ব্লুটুথ share: %1$s প্রাপ্ত করা হচ্ছে" "ব্লুটুথ share: %1$s প্রাপ্ত করা হয়েছে" "ব্লুটুথ share: %1$s ফাইল প্রাপ্ত করা হয়নি" - "ব্লুটুথ share: %1$s পাঠানো হচ্ছে" - "ব্লুটুথ share: %1$s পাঠানো হয়েছে" + "ব্লুটুথ শেয়ার: %1$s পাঠানো হচ্ছে" + "ব্লুটুথ শেয়ার: %1$s পাঠানো হয়েছে" "১০০% সম্পূর্ণ" "ব্লুটুথ share: %1$s ফাইল পাঠানো হয়নি" "ফাইল ট্রান্সফার" @@ -107,12 +108,10 @@ "বহির্গামী স্থানান্তরগুলি" "ট্রান্সফার করার ইতিহাস খালি।" "তালিকা থেকে সমস্ত আইটেম সাফ করা হবে।" - "ব্লুটুথ share: পাঠানো ফাইলগুলি" - "ব্লুটুথ share: প্রাপ্ত করা ফাইলগুলি" - - - - + "ব্লুটুথ শেয়ার: পাঠানো ফাইল" + "ব্লুটুথ শেয়ার: গ্রহন করা ফাইল" + "{count,plural, =1{#টি ফাইল পাঠানো যায়নি।}one{#টি ফাইল পাঠানো যায়নি।}other{#টি ফাইল পাঠানো যায়নি।}}" + "{count,plural, =1{#টি ফাইল পাঠানো হয়েছে, %1$s}one{#টি ফাইল পাঠানো হয়েছে, %1$s}other{#টি ফাইল পাঠানো হয়েছে, %1$s}}" "তালিকা সাফ করুন" "খুলুন" "তালিকা থেকে সাফ করুন" @@ -130,4 +129,10 @@ "ব্লুটুথ অডিও" "৪GB থেকে বড় ফটো ট্রান্সফার করা যাবে না" "ব্লুটুথের সাথে কানেক্ট করুন" + "\'বিমান মোড\'-এ থাকাকালীন ব্লুটুথ চালু থাকে" + "আপনি ওয়াই-ফাই চালু রাখলে, আপনি এরপর \'বিমান মোডে\' থাকলে আপনার ফোন এটি চালু রাখবে" + "ব্লুটুথ চালু থাকে" + "\'বিমান মোড\'-এ থাকাকালীন আপনার ফোন ব্লুটুথ চালু রাখে। আপনি ব্লুটুথ চালু না রাখতে চাইলে এটি বন্ধ করুন।" + "ওয়াই-ফাই ও ব্লুটুথ চালু থাকে" + "\'বিমান মোড\'-এ থাকাকালীন আপনার ফোন ওয়াই-ফাই ও ব্লুটুথ চালু রাখে। আপনি যদি ওয়াই-ফাই এবং ব্লুটুথ চালু রাখতে না চান, সেগুলি বন্ধ করে দিন।" diff --git a/android/app/res/values-bs/strings.xml b/android/app/res/values-bs/strings.xml index 0d1d2e9c6ca..f21cce84a95 100644 --- a/android/app/res/values-bs/strings.xml +++ b/android/app/res/values-bs/strings.xml @@ -23,6 +23,7 @@ "Bluetooth" "Nepoznat uređaj" "Nepoznato" + "Nije navedeno" "Način rada u avionu" "Ne možete koristiti Bluetooth u načinu rada u avionu." @@ -38,11 +39,11 @@ "Isteklo je vrijeme prilikom prihvatanja dolaznog fajla koji šalje \"%1$s\"" "Dolazni fajl" "%1$s je spreman/na za slanje fajla: %2$s" - "Bluetooth dijeljenje: Prima se fajl %1$s" + "Bluetooth dijeljenje: primanje fajla %1$s" "Bluetooth dijeljenje: Primljen fajl %1$s" "Bluetooth dijeljenje: Fajl %1$s nije primljen" - "Bluetooth dijeljenje: Slanje fajla %1$s" - "Bluetooth dijeljenje: Poslan fajl %1$s" + "Bluetooth dijeljenje: slanje fajla %1$s" + "Bluetooth dijeljenje: poslan fajl %1$s" "Dovršeno 100%" "Bluetooth dijeljenje: Fajl %1$s nije poslan" "Prenošenje fajla" @@ -107,12 +108,10 @@ "Odlazna prenošenja" "Historija prijenosa je prazna." "Sve stavke će biti izbrisane sa spiska." - "Bluetooth dijeljenje: Poslani fajlovi" - "Bluetooth dijeljenje: Primljeni fajlovi" - - - - + "Bluetooth dijeljenje: poslani fajlovi" + "Bluetooth dijeljenje: primljeni fajlovi" + "{count,plural, =1{# neuspješno.}one{# neuspješno.}few{# neuspješno.}other{# neuspješno.}}" + "{count,plural, =1{# uspješno, %1$s}one{# uspješno, %1$s}few{# uspješno, %1$s}other{# uspješno, %1$s}}" "Obriši spisak" "Otvori" "Obriši sa spiska" @@ -130,4 +129,10 @@ "Bluetooth Audio" "Nije moguće prenijeti fajlove veće od 4 GB" "Poveži se na Bluetooth" + "Bluetooth je uključen u načinu rada u avionu" + "Ako ostavite Bluetooth uključenim, telefon će zapamtiti da ga ostavi uključenog sljedeći put kada budete u načinu rada u avionu" + "Bluetooth ostaje uključen" + "Telefon pamti da Bluetooth treba biti uključen u načinu rada u avionu. Isključite Bluetooth ako ne želite da ostane uključen." + "WiFi i Bluetooth ostaju uključeni" + "Telefon pamti da WiFi i Bluetooth trebaju biti uključeni u načinu rada u avionu. Isključite WiFi i Bluetooth ako ne želite da ostanu uključeni." diff --git a/android/app/res/values-ca/strings.xml b/android/app/res/values-ca/strings.xml index 76ee2ec8d77..b476c4e0761 100644 --- a/android/app/res/values-ca/strings.xml +++ b/android/app/res/values-ca/strings.xml @@ -23,6 +23,7 @@ "Bluetooth" "Dispositiu desconegut" "Desconegut" + "Sense proporcionar" "Mode d\'avió" "No pots utilitzar el Bluetooth en mode d\'avió." @@ -109,10 +110,8 @@ "S\'esborraran tots els elements de la llista." "Bluetooth: fitxers enviats" "Bluetooth: fitxers rebuts" - - - - + "{count,plural, =1{# no completat.}other{# no completats.}}" + "{count,plural, =1{# completat, %1$s}other{# completats, %1$s}}" "Esborra la llista" "Obre" "Esborra de la llista" @@ -130,4 +129,10 @@ "Àudio per Bluetooth" "No es poden transferir fitxers més grans de 4 GB" "Connecta el Bluetooth" + "El Bluetooth està activat en mode d\'avió" + "Si tens activat el Bluetooth, el telèfon recordarà mantenir-lo així la pròxima vegada que utilitzis el mode d\'avió" + "El Bluetooth es mantindrà activat" + "El telèfon recorda mantenir el Bluetooth activat en mode d\'avió. Desactiva el Bluetooth si no vols que es quedi activat." + "La Wi‑Fi i el Bluetooth es mantenen activats" + "El telèfon recorda mantenir la Wi‑Fi i el Bluetooth activats en mode d\'avió. Desactiva la Wi‑Fi i el Bluetooth si no vols que es quedin activats." diff --git a/android/app/res/values-cs/strings.xml b/android/app/res/values-cs/strings.xml index 067970d3eef..09dc67bbb06 100644 --- a/android/app/res/values-cs/strings.xml +++ b/android/app/res/values-cs/strings.xml @@ -23,6 +23,7 @@ "Bluetooth" "Neznámé zařízení" "Neznámé" + "Neposkytnuto" "Režim Letadlo" "V režimu Letadlo není možné Bluetooth použít." @@ -109,10 +110,8 @@ "Ze seznamu budou vymazány všechny položky." "Sdílení Bluetooth: Odeslané soubory" "Sdílení Bluetooth: Přijaté soubory" - - - - + "{count,plural, =1{# neúspěšně.}few{# neúspěšně.}many{# neúspěšně.}other{# neúspěšně.}}" + "{count,plural, =1{# úspěšně, %1$s}few{# úspěšně, %1$s}many{# úspěšně, %1$s}other{# úspěšně, %1$s}}" "Vymazat obsah seznamu" "Otevřít" "Vymazat ze seznamu" @@ -130,4 +129,10 @@ "Bluetooth Audio" "Soubory větší než 4 GB nelze přenést" "Připojit k Bluetooth" + "Zapnutý Bluetooth v režimu Letadlo" + "Pokud Bluetooth necháte zapnutý, telefon si zapamatuje, že ho má příště v režimu Letadlo ponechat zapnutý" + "Bluetooth zůstane zapnutý" + "Telefon si pamatuje, že má v režimu Letadlo ponechat zapnutý Bluetooth. Pokud nechcete, aby Bluetooth zůstal zapnutý, vypněte ho." + "Wi-Fi a Bluetooth zůstávají zapnuté" + "Telefon si pamatuje, že má v režimu Letadlo ponechat zapnutou Wi-Fi a Bluetooth. Pokud nechcete, aby Wi-Fi a Bluetooth zůstaly zapnuté, vypněte je." diff --git a/android/app/res/values-da/strings.xml b/android/app/res/values-da/strings.xml index b57dc358e24..47f0b5405c2 100644 --- a/android/app/res/values-da/strings.xml +++ b/android/app/res/values-da/strings.xml @@ -23,6 +23,7 @@ "Bluetooth" "Ukendt enhed" "Ukendt" + "Ikke angivet" "Flytilstand" "Du kan ikke anvende Bluetooth i flytilstand." @@ -109,10 +110,8 @@ "Alle elementer vil blive fjernet fra listen." "Bluetooth-deling: Sendte filer" "Bluetooth-deling: Modtagne filer" - - - - + "{count,plural, =1{# blev ikke sendt.}one{# unsuccessful.}other{# blev ikke sendt.}}" + "{count,plural, =1{# blev sendt, %1$s}one{# successful, %1$s}other{# blev sendt, %1$s}}" "Ryd liste" "Åbn" "Fjern fra listen" @@ -130,4 +129,10 @@ "Bluetooth-lyd" "File, der er større end 4 GB, kan ikke overføres" "Opret forbindelse til Bluetooth" + "Bluetooth er aktiveret i flytilstand" + "Hvis du holder Bluetooth aktiveret, sørger din telefon for, at Bluetooth forbliver aktiveret, næste gang du sætter den til flytilstand" + "Bluetooth forbliver aktiveret" + "Din telefon beholder Bluetooth aktiveret i flytilstand. Deaktiver Bluetooth, hvis du ikke vil have, at det forbliver aktiveret." + "Wi-Fi og Bluetooth forbliver aktiveret" + "Din telefon husker at holde Wi-Fi og Bluetooth aktiveret i flytilstand. Deaktiver Wi-Fi og Bluetooth, hvis du ikke vil have, at de forbliver aktiveret." diff --git a/android/app/res/values-de/strings.xml b/android/app/res/values-de/strings.xml index 1364f7d39a8..7d9ade34d72 100644 --- a/android/app/res/values-de/strings.xml +++ b/android/app/res/values-de/strings.xml @@ -23,6 +23,7 @@ "Bluetooth" "Unbekanntes Gerät" "Unbekannter Anrufer" + "Keine Angabe" "Flugmodus" "Du kannst Bluetooth im Flugmodus nicht verwenden." @@ -80,9 +81,9 @@ "Die Datei wird empfangen. Überprüfe den Fortschritt in der Benachrichtigungskonsole." "Die Datei kann nicht empfangen werden." "Der Empfang der Datei von \"%1$s\" wurde angehalten." - "Datei wird an \"%1$s\" gesendet..." + "Datei wird an „%1$s“ gesendet..." "%1$s Dateien werden an \"%2$s\" gesendet." - "Die Übertragung der Datei an \"%1$s\" wurde abgebrochen" + "Die Übertragung der Datei an „%1$s“ wurde abgebrochen" "Auf dem USB-Speicher ist nicht genügend Platz, um die Datei zu speichern." "Auf der SD-Karte ist nicht genügend Platz, um die Datei zu speichern." "Erforderlicher Speicherplatz: %1$s" @@ -109,10 +110,8 @@ "Alle Elemente werden aus der Liste gelöscht." "Bluetooth-Freigabe: Gesendete Dateien" "Bluetooth-Freigabe: Empfangene Dateien" - - - - + "{count,plural, =1{# fehlgeschlagen.}other{# fehlgeschlagen.}}" + "{count,plural, =1{# erfolgreich, %1$s}other{# erfolgreich, %1$s}}" "Liste löschen" "Öffnen" "Aus Liste löschen" @@ -130,4 +129,10 @@ "Bluetooth-Audio" "Dateien mit mehr als 4 GB können nicht übertragen werden" "Mit Bluetooth verbinden" + "Bluetooth im Flugmodus eingeschaltet" + "Wenn du Bluetooth nicht ausschaltest, bleibt es eingeschaltet, wenn du das nächste Mal in den Flugmodus wechselst" + "Bluetooth bleibt aktiviert" + "Auf deinem Smartphone bleibt Bluetooth im Flugmodus eingeschaltet. Schalte Bluetooth aus, wenn du das nicht möchtest." + "WLAN und Bluetooth bleiben eingeschaltet" + "Auf deinem Smartphone bleiben WLAN und Bluetooth im Flugmodus eingeschaltet. Schalte sie aus, wenn du das nicht möchtest." diff --git a/android/app/res/values-el/strings.xml b/android/app/res/values-el/strings.xml index a9abf2b586b..36ebd165d3d 100644 --- a/android/app/res/values-el/strings.xml +++ b/android/app/res/values-el/strings.xml @@ -23,6 +23,7 @@ "Bluetooth" "Άγνωστη συσκευή" "Άγνωστος" + "Δεν παρέχεται" "Λειτουργία πτήσης" "Δεν μπορείτε να χρησιμοποιήσετε το Bluetooth σε Λειτουργία πτήσης." @@ -41,8 +42,8 @@ "Μοιραστείτε μέσω Bluetooth: Λήψη του %1$s" "Μοιραστείτε μέσω Bluetooth: Ελήφθη το %1$s" "Μοιραστείτε μέσω Bluetooth: Το αρχείο %1$s δεν ελήφθη" - "Μοιραστείτε μέσω Bluetooth: Αποστολή του %1$s" - "Μοιραστείτε μέσω Bluetooth: Εστάλη το %1$s" + "Μοιραστείτε με Bluetooth: Αποστολή του %1$s" + "Μοιραστείτε με Bluetooth: %1$s" "Ολοκληρώθηκε το 100%" "Μοιραστείτε μέσω Bluetooth: Το αρχείο %1$s δεν εστάλη" "Μεταφορά αρχείου" @@ -109,10 +110,8 @@ "Όλα τα στοιχεία από τη λίστα θα διαγραφούν." "Κοινή χρήση Bluetooth: Απεσταλμένα αρχεία" "Κοινή χρήση Bluetooth: Ληφθέντα αρχεία" - - - - + "{count,plural, =1{# ανεπιτυχής.}other{# ανεπιτυχείς.}}" + "{count,plural, =1{# επιτυχής, %1$s}other{# επιτυχείς, %1$s}}" "Διαγραφή λίστας" "Άνοιγμα" "Διαγραφή από τη λίστα" @@ -130,4 +129,10 @@ "Ήχος Bluetooth" "Δεν είναι δυνατή η μεταφορά αρχείων που ξεπερνούν τα 4 GB" "Σύνδεση σε Bluetooth" + "Bluetooth ενεργοποιημένο σε λειτουργία πτήσης" + "Αν διατηρήσετε το Bluetooth ενεργοποιημένο, το τηλέφωνό σας θα θυμάται να το διατηρήσει ενεργοποιημένο την επόμενη φορά που θα βρεθεί σε λειτουργία πτήσης" + "Το Bluetooth παραμένει ενεργό" + "Το τηλέφωνο θυμάται να διατηρεί ενεργοποιημένο το Bluetooth σε λειτουργία πτήσης. Απενεργοποιήστε το Bluetooth αν δεν θέλετε να παραμένει ενεργοποιημένο." + "Το Wi-Fi και το Bluetooth παραμένουν ενεργοποιημένα" + "Το τηλέφωνο θυμάται να διατηρεί ενεργοποιημένο το Wi‑Fi και το Bluetooth σε λειτουργία πτήσης. Απενεργοποιήστε το Wi-Fi και το Bluetooth αν δεν θέλετε να παραμένουν ενεργοποιημένα." diff --git a/android/app/res/values-en-rAU/strings.xml b/android/app/res/values-en-rAU/strings.xml index 482c645bd49..6db8bfaf7c0 100644 --- a/android/app/res/values-en-rAU/strings.xml +++ b/android/app/res/values-en-rAU/strings.xml @@ -23,6 +23,7 @@ "Bluetooth" "Unknown device" "Unknown" + "Not provided" "Aeroplane mode" "You can\'t use Bluetooth in Aeroplane mode." @@ -109,10 +110,8 @@ "All items will be cleared from the list." "Bluetooth share: Sent files" "Bluetooth share: Received files" - - - - + "{count,plural, =1{# unsuccessful.}other{# unsuccessful.}}" + "{count,plural, =1{# successful, %1$s}other{# successful, %1$s}}" "Clear list" "Open" "Clear from list" @@ -130,4 +129,10 @@ "Bluetooth audio" "Files bigger than 4 GB cannot be transferred" "Connect to Bluetooth" + "Bluetooth on in aeroplane mode" + "If you keep Bluetooth on, your phone will remember to keep it on the next time that you\'re in aeroplane mode" + "Bluetooth stays on" + "Your phone remembers to keep Bluetooth on in aeroplane mode. Turn off Bluetooth if you don\'t want it to stay on." + "Wi-Fi and Bluetooth stay on" + "Your phone remembers to keep Wi-Fi and Bluetooth on in aeroplane mode. Turn off Wi-Fi and Bluetooth if you don\'t want them to stay on." diff --git a/android/app/res/values-en-rCA/strings.xml b/android/app/res/values-en-rCA/strings.xml index e1109f711bc..545853f2c55 100644 --- a/android/app/res/values-en-rCA/strings.xml +++ b/android/app/res/values-en-rCA/strings.xml @@ -17,12 +17,13 @@ "Access download manager." - "Allows the application to access the Bluetooth Share manager and to use it to transfer files." - "Acceptlist Bluetooth device access." + "Allows the app to access the BluetoothShare manager and use it to transfer files." + "Acceptlist bluetooth device access." "Allows the app to temporarily acceptlist a Bluetooth device, allowing that device to send files to this device without user confirmation." "Bluetooth" "Unknown device" "Unknown" + "Not Provided" "Airplane mode" "You can\'t use Bluetooth in Airplane mode." @@ -87,13 +88,13 @@ "There isn\'t enough space on the SD card to save the file." "Space needed: %1$s" "Too many requests are being processed. Try again later." - "File transfer not started yet" + "File transfer not started yet." "File transfer is ongoing." "File transfer completed successfully." "Content isn\'t supported." "Transfer forbidden by target device." - "Transfer cancelled by user." - "Storage issue" + "Transfer canceled by user." + "Storage issue." "No USB storage." "No SD card. Insert an SD card to save transferred files." "Connection unsuccessful." @@ -109,25 +110,29 @@ "All items will be cleared from the list." "Bluetooth share: Sent files" "Bluetooth share: Received files" - - - - + "{count,plural, =1{# unsuccessful.}other{# unsuccessful.}}" + "{count,plural, =1{# successful, %1$s}other{# successful, %1$s}}" "Clear list" "Open" "Clear from list" "Clear" - "Now playing" + "Now Playing" "Save" "Cancel" - "Select the accounts that you want to share through Bluetooth. You still have to accept any access to the accounts when connecting." + "Select the accounts you want to share through Bluetooth. You still have to accept any access to the accounts when connecting." "Slots left:" - "Application icon" - "Bluetooth message sharing settings" + "Application Icon" + "Bluetooth Message Sharing Settings" "Cannot select account. 0 slots left" "Bluetooth audio connected" "Bluetooth audio disconnected" - "Bluetooth audio" - "Files bigger than 4 GB cannot be transferred" + "Bluetooth Audio" + "Files bigger than 4GB cannot be transferred" "Connect to Bluetooth" + "Bluetooth on in Airplane mode" + "If you keep Bluetooth on, your phone will remember to keep it on the next time you\'re in Airplane mode" + "Bluetooth stays on" + "Your phone remembers to keep Bluetooth on in Airplane mode. Turn off Bluetooth if you don\'t want it to stay on." + "Wi-Fi and Bluetooth stay on" + "Your phone remembers to keep Wi-Fi and Bluetooth on in Airplane mode. Turn off Wi-Fi and Bluetooth if you don\'t want them to stay on." diff --git a/android/app/res/values-en-rGB/strings.xml b/android/app/res/values-en-rGB/strings.xml index 482c645bd49..6db8bfaf7c0 100644 --- a/android/app/res/values-en-rGB/strings.xml +++ b/android/app/res/values-en-rGB/strings.xml @@ -23,6 +23,7 @@ "Bluetooth" "Unknown device" "Unknown" + "Not provided" "Aeroplane mode" "You can\'t use Bluetooth in Aeroplane mode." @@ -109,10 +110,8 @@ "All items will be cleared from the list." "Bluetooth share: Sent files" "Bluetooth share: Received files" - - - - + "{count,plural, =1{# unsuccessful.}other{# unsuccessful.}}" + "{count,plural, =1{# successful, %1$s}other{# successful, %1$s}}" "Clear list" "Open" "Clear from list" @@ -130,4 +129,10 @@ "Bluetooth audio" "Files bigger than 4 GB cannot be transferred" "Connect to Bluetooth" + "Bluetooth on in aeroplane mode" + "If you keep Bluetooth on, your phone will remember to keep it on the next time that you\'re in aeroplane mode" + "Bluetooth stays on" + "Your phone remembers to keep Bluetooth on in aeroplane mode. Turn off Bluetooth if you don\'t want it to stay on." + "Wi-Fi and Bluetooth stay on" + "Your phone remembers to keep Wi-Fi and Bluetooth on in aeroplane mode. Turn off Wi-Fi and Bluetooth if you don\'t want them to stay on." diff --git a/android/app/res/values-en-rIN/strings.xml b/android/app/res/values-en-rIN/strings.xml index 482c645bd49..6db8bfaf7c0 100644 --- a/android/app/res/values-en-rIN/strings.xml +++ b/android/app/res/values-en-rIN/strings.xml @@ -23,6 +23,7 @@ "Bluetooth" "Unknown device" "Unknown" + "Not provided" "Aeroplane mode" "You can\'t use Bluetooth in Aeroplane mode." @@ -109,10 +110,8 @@ "All items will be cleared from the list." "Bluetooth share: Sent files" "Bluetooth share: Received files" - - - - + "{count,plural, =1{# unsuccessful.}other{# unsuccessful.}}" + "{count,plural, =1{# successful, %1$s}other{# successful, %1$s}}" "Clear list" "Open" "Clear from list" @@ -130,4 +129,10 @@ "Bluetooth audio" "Files bigger than 4 GB cannot be transferred" "Connect to Bluetooth" + "Bluetooth on in aeroplane mode" + "If you keep Bluetooth on, your phone will remember to keep it on the next time that you\'re in aeroplane mode" + "Bluetooth stays on" + "Your phone remembers to keep Bluetooth on in aeroplane mode. Turn off Bluetooth if you don\'t want it to stay on." + "Wi-Fi and Bluetooth stay on" + "Your phone remembers to keep Wi-Fi and Bluetooth on in aeroplane mode. Turn off Wi-Fi and Bluetooth if you don\'t want them to stay on." diff --git a/android/app/res/values-en-rXC/strings.xml b/android/app/res/values-en-rXC/strings.xml index 883e31e84bc..ab3c717f0ef 100644 --- a/android/app/res/values-en-rXC/strings.xml +++ b/android/app/res/values-en-rXC/strings.xml @@ -23,6 +23,7 @@ "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‎‎‎‏‏‏‎‏‏‏‏‏‏‏‏‎‎‏‏‏‏‎‎‏‎‏‏‏‎‎‎‎‎‎‏‏‎‏‎‎‎‎‏‏‎‎‏‏‏‏‏‎‏‏‏‏‎‏‎‎‎‏‎‏‎‎‎‏‏‎‏‎‎‎‎‎‎Bluetooth‎‏‎‎‏‎" "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‎‎‎‏‏‏‎‏‏‏‏‏‎‏‎‎‎‎‎‎‎‏‎‏‎‏‎‎‎‎‎‏‏‎‏‎‎‏‏‏‏‏‎‏‏‎‏‎‏‎‏‎‎‏‎‎‏‏‏‏‎‏‎‏‎‏‏‎‎‎‏‎‏‏‎‎Unknown device‎‏‎‎‏‎" "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‎‎‎‏‏‏‎‏‏‏‏‎‏‏‎‎‎‏‎‏‎‎‎‏‏‏‏‏‎‎‎‏‏‏‏‎‏‎‎‏‎‎‎‎‏‎‎‏‏‎‏‏‎‎‎‎‏‏‏‏‎‎‎‎‎‏‎‏‎‎‎‏‎‏‎Unknown‎‏‎‎‏‎" + "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‎‎‎‏‏‏‎‏‏‏‏‏‏‏‏‎‎‎‎‎‎‏‎‎‏‎‏‏‎‏‎‏‏‎‏‏‏‎‏‏‎‏‏‏‎‏‏‏‎‏‎‎‎‎‏‎‎‎‏‏‏‎‎‏‎‏‎‎‎‏‎‎‎‏‏‎‎Not Provided‎‏‎‎‏‎" "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‎‎‎‏‏‏‎‏‏‏‏‏‎‏‎‎‎‏‏‏‎‏‎‏‎‏‎‏‏‎‏‏‏‏‎‏‏‏‏‏‏‎‏‎‏‎‎‎‎‎‏‏‎‏‏‎‏‏‎‎‏‎‏‏‎‎‏‎‎‏‎‏‏‎‎‎Airplane mode‎‏‎‎‏‎" "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‎‎‎‏‏‏‎‏‏‏‏‏‏‏‎‎‎‎‏‏‎‏‎‏‏‎‎‏‏‎‏‏‎‏‏‎‏‏‎‏‏‎‏‎‏‎‏‎‎‏‏‏‏‎‎‏‏‎‏‏‏‏‏‎‏‏‎‎‏‎‎‏‏‎‏‎‎You can\'t use Bluetooth in Airplane mode.‎‏‎‎‏‎" @@ -109,10 +110,8 @@ "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‎‎‎‏‏‏‎‏‏‏‏‎‎‏‎‎‎‎‎‏‎‎‎‏‎‎‏‎‎‏‏‏‏‎‎‏‎‎‏‏‏‎‎‎‏‏‏‏‏‎‏‏‎‏‎‏‎‏‏‏‏‎‎‏‎‏‏‎‎‏‏‏‏‎All items will be cleared from the list.‎‏‎‎‏‎" "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‎‎‎‏‏‏‎‏‏‏‏‎‏‏‏‏‎‎‎‏‏‎‎‎‏‏‎‏‎‎‏‎‏‎‏‏‎‎‏‏‎‎‎‎‏‏‏‏‎‏‎‏‎‏‏‏‎‎‏‏‏‎‎‏‎‎‏‎‏‎‎‎‏‏‎Bluetooth share: Sent files‎‏‎‎‏‎" "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‎‎‎‏‏‏‎‏‏‏‏‏‎‏‏‎‎‏‏‏‏‎‎‎‏‏‏‎‎‏‎‎‏‏‎‏‏‎‎‎‏‎‎‏‏‏‏‎‎‎‏‏‎‏‎‏‎‎‏‎‎‎‏‏‎‎‏‏‎‎‏‏‎‎‏‎Bluetooth share: Received files‎‏‎‎‏‎" - - - - + "{count,plural, =1{‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‎‎‎‏‏‏‎‏‏‏‏‏‏‏‎‏‏‏‎‎‏‎‏‏‎‎‎‏‏‎‎‏‏‎‎‏‎‎‎‏‎‎‎‎‎‎‎‎‎‏‎‏‎‎‎‎‏‏‎‎‏‏‎‏‏‎‎‏‎‏‎‏‎‎‏‏‎# unsuccessful.‎‏‎‎‏‎}other{‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‎‎‎‏‏‏‎‏‏‏‏‏‏‏‎‏‏‏‎‎‏‎‏‏‎‎‎‏‏‎‎‏‏‎‎‏‎‎‎‏‎‎‎‎‎‎‎‎‎‏‎‏‎‎‎‎‏‏‎‎‏‏‎‏‏‎‎‏‎‏‎‏‎‎‏‏‎# unsuccessful.‎‏‎‎‏‎}}" + "{count,plural, =1{‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‎‎‎‏‏‏‎‏‏‏‏‏‏‏‏‎‏‎‏‎‎‎‏‏‎‏‎‎‎‎‏‎‎‎‎‎‏‎‎‏‏‎‏‎‎‏‎‏‎‎‏‏‏‎‏‎‎‎‏‏‎‎‏‎‏‎‎‏‏‎‏‏‎‎‎‏‎# successful, %1$s‎‏‎‎‏‎}other{‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‎‎‎‏‏‏‎‏‏‏‏‏‏‏‏‎‏‎‏‎‎‎‏‏‎‏‎‎‎‎‏‎‎‎‎‎‏‎‎‏‏‎‏‎‎‏‎‏‎‎‏‏‏‎‏‎‎‎‏‏‎‎‏‎‏‎‎‏‏‎‏‏‎‎‎‏‎# successful, %1$s‎‏‎‎‏‎}}" "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‎‎‎‏‏‏‎‏‏‏‏‏‎‏‎‏‎‎‏‏‏‎‏‎‏‎‏‏‎‎‎‎‎‏‏‎‎‏‎‏‏‎‏‏‏‏‎‎‎‎‎‎‏‏‎‏‏‎‏‎‎‎‏‎‏‎‎‎‏‎‎‎‏‎‎‎Clear list‎‏‎‎‏‎" "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‎‎‎‏‏‏‎‏‏‏‏‏‏‏‎‎‏‎‎‎‎‎‎‏‎‎‏‎‎‏‏‏‎‏‏‏‎‏‏‎‏‏‏‎‏‏‏‏‎‏‏‎‎‏‎‏‎‎‏‏‏‏‎‏‎‏‎‎‏‎‎‎‎‎‏‏‎Open‎‏‎‎‏‎" "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‎‎‎‏‏‏‎‏‏‏‏‏‏‏‏‎‎‏‎‎‎‎‎‏‏‎‏‏‎‏‏‏‏‎‎‎‎‎‎‏‏‎‏‎‎‎‏‎‎‏‏‏‏‏‏‎‏‎‏‏‎‎‏‎‏‏‏‏‏‎‏‏‏‎‏‎‎Clear from list‎‏‎‎‏‎" @@ -130,4 +129,10 @@ "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‎‎‎‏‏‏‎‏‏‏‏‏‏‏‎‏‎‎‏‏‏‏‎‎‎‎‎‏‏‏‏‎‏‏‎‏‏‎‏‏‎‏‏‏‎‎‏‎‏‎‎‎‏‎‎‏‏‎‎‏‏‎‎‏‎‏‎‎‏‏‏‏‎‎‏‏‎Bluetooth Audio‎‏‎‎‏‎" "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‎‎‎‏‏‏‎‏‏‏‏‏‏‏‎‏‏‎‏‏‏‏‎‎‎‎‏‎‏‏‏‎‏‏‏‎‏‏‏‎‎‎‏‎‏‎‏‎‎‏‏‎‎‎‎‏‎‎‎‏‎‎‏‏‎‎‏‎‏‎‎‎‏‎‏‎‎Files bigger than 4GB cannot be transferred‎‏‎‎‏‎" "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‎‎‎‏‏‏‎‏‏‏‏‏‎‏‎‎‎‎‎‎‎‏‏‎‎‎‎‎‏‎‏‎‏‏‎‏‎‏‎‏‎‎‏‎‏‎‎‎‎‎‏‏‎‏‎‎‏‏‎‏‏‎‏‎‏‏‎‏‏‎‏‎‎‎‏‎Connect to Bluetooth‎‏‎‎‏‎" + "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‎‎‎‏‏‏‎‏‏‏‏‏‏‏‎‏‏‏‏‏‏‏‏‏‎‏‎‏‎‎‎‏‏‎‎‏‏‏‎‎‎‏‏‏‏‎‎‏‎‎‏‎‏‎‎‎‏‎‎‏‏‎‏‏‎‏‎‎‎‎‏‏‎‏‎‎‎Bluetooth on in airplane mode‎‏‎‎‏‎" + "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‎‎‎‏‏‏‎‏‏‏‏‏‏‏‏‏‎‏‎‎‏‎‏‏‎‏‎‏‏‏‏‏‏‎‎‎‎‎‎‎‎‎‎‏‎‎‎‎‎‏‏‏‏‏‎‏‏‏‎‎‏‏‎‏‎‏‎‏‎‏‏‎‎‎‎‏‎If you keep Bluetooth on, your phone will remember to keep it on the next time you\'re in airplane mode‎‏‎‎‏‎" + "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‎‎‎‏‏‏‎‏‏‏‎‎‎‏‎‎‎‏‏‎‏‎‎‎‏‏‏‎‏‏‏‏‎‎‎‎‎‎‏‎‎‏‏‏‏‎‎‏‏‏‎‎‎‏‏‏‎‏‏‎‎‎‏‏‏‎‏‏‎‎Bluetooth stays on‎‏‎‎‏‎" + "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‎‎‎‏‏‏‎‏‏‏‏‏‏‏‏‎‎‎‏‏‎‎‎‏‏‏‏‏‎‎‎‏‎‏‏‏‎‏‏‏‏‏‏‏‏‎‏‏‎‎‎‎‎‏‏‏‏‏‏‎‎‏‎‏‎‎‎‏‏‏‏‎‏‏‎‏‎Your phone remembers to keep Bluetooth on in airplane mode. Turn off Bluetooth if you don\'t want it to stay on.‎‏‎‎‏‎" + "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‎‎‎‏‏‏‎‏‏‏‏‏‏‏‎‏‎‎‎‎‏‏‎‎‏‎‏‏‏‎‏‎‏‎‎‏‎‎‎‎‏‎‎‎‏‏‎‏‏‏‏‎‎‏‎‎‏‎‏‏‏‎‎‎‎‎‏‎‏‏‏‏‏‏‎‎‎Wi-Fi and Bluetooth stay on‎‏‎‎‏‎" + "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‎‎‎‏‏‏‎‏‏‏‏‏‎‏‎‎‎‎‏‎‎‏‎‏‏‎‏‏‎‏‎‎‏‏‎‎‏‎‎‏‏‎‏‏‎‎‎‎‎‎‎‎‎‏‏‏‏‎‎‎‎‏‎‎‏‏‏‎‎‎‎‎‏‎‎‎Your phone remembers to keep Wi-Fi and Bluetooth on in airplane mode. Turn off Wi-Fi and Bluetooth if you don\'t want them to stay on.‎‏‎‎‏‎" diff --git a/android/app/res/values-es-rUS/strings.xml b/android/app/res/values-es-rUS/strings.xml index dab60f5d679..9969588c3b7 100644 --- a/android/app/res/values-es-rUS/strings.xml +++ b/android/app/res/values-es-rUS/strings.xml @@ -23,6 +23,7 @@ "Bluetooth" "Dispositivo desconocido" "Desconocido" + "No se proporcionó" "Modo de avión" "No puedes usar Bluetooth en Modo avión." @@ -37,7 +38,7 @@ "Aceptar" "Tiempo de espera agotado al aceptar un archivo entrante de \"%1$s\"" "Archivo entrante" - "%1$s se preparó para enviar un archivo: %2$s" + "%1$s está listo para enviar un archivo: %2$s" "Bluetooth: recibiendo %1$s" "Bluetooth: %1$s recibido" "Bluetooth: no se recibió el archivo %1$s" @@ -109,10 +110,8 @@ "Se borrarán todos los elementos de la lista." "Bluetooth: archivos enviados" "Bluetooth: archivos recibidos" - - - - + "{count,plural, =1{# con error.}other{# con error.}}" + "{count,plural, =1{# con éxito, %1$s}other{# con éxito, %1$s}}" "Eliminar lista" "Abrir" "Eliminar de la lista" @@ -130,4 +129,10 @@ "Audio Bluetooth" "No se pueden transferir los archivos de más de 4 GB" "Conectarse a Bluetooth" + "Bluetooth activado en modo de avión" + "Si mantienes el Bluetooth activado, el teléfono lo dejará activado la próxima vez que actives el modo de avión" + "El Bluetooth permanece activado" + "El teléfono dejará activado el Bluetooth en el modo de avión. Desactívalo si no quieres que permanezca activado." + "El Wi-Fi y el Bluetooth permanecen activados" + "El teléfono dejará activado el Wi-Fi y el Bluetooth en el modo de avión. Si no quieres que permanezcan activados, desactívalos." diff --git a/android/app/res/values-es/strings.xml b/android/app/res/values-es/strings.xml index 08ecc54915b..59550d79099 100644 --- a/android/app/res/values-es/strings.xml +++ b/android/app/res/values-es/strings.xml @@ -23,6 +23,7 @@ "Bluetooth" "Dispositivo desconocido" "Desconocido" + "Sin proporcionar" "Modo Avión" "No puedes utilizar el Bluetooth en el modo Avión." @@ -37,7 +38,7 @@ "Aceptar" "Se ha agotado el tiempo para aceptar el archivo entrante de \"%1$s\"." "Archivo entrante" - "%1$s ya puede enviar un archivo: %2$s" + "%1$s está listo para enviar un archivo: %2$s" "Bluetooth: recibiendo %1$s" "Compartir con Bluetooth: %1$s recibido" "Bluetooth: %1$s no recibido" @@ -109,10 +110,8 @@ "Se borrarán todos los elementos de la lista." "Bluetooth: archivos enviados" "Bluetooth: archivos recibidos" - - - - + "{count,plural, =1{# con error.}other{# con error.}}" + "{count,plural, =1{# con éxito, %1$s}other{# con éxito, %1$s}}" "Borrar lista" "Abrir" "Borrar de la lista" @@ -130,4 +129,10 @@ "Audio por Bluetooth" "No se pueden transferir archivos de más de 4 GB" "Conectarse a un dispositivo Bluetooth" + "Bluetooth activado en modo Avión" + "Si dejas el Bluetooth activado, tu teléfono se acordará de mantenerlo así la próxima vez que uses el modo Avión" + "El Bluetooth permanece activado" + "Tu teléfono se acordará de mantener activado el Bluetooth en modo Avión. Desactiva el Bluetooth si no quieres que permanezca activado." + "El Wi-Fi y el Bluetooth permanecen activados" + "Tu teléfono se acordará de mantener activados el Wi-Fi y el Bluetooth en modo Avión. Desactívalos si no quieres que permanezcan activados." diff --git a/android/app/res/values-et/strings.xml b/android/app/res/values-et/strings.xml index 965d003f6e6..95163ce8d2b 100644 --- a/android/app/res/values-et/strings.xml +++ b/android/app/res/values-et/strings.xml @@ -23,6 +23,7 @@ "Bluetooth" "Tundmatu seade" "Tundmatu" + "Pole esitatud" "Lennukirežiim" "Te ei saa Bluetoothi lennurežiimis kasutada." @@ -109,10 +110,8 @@ "Kõik üksused eemaldatakse loendist." "Bluetoothi jagamine: saadetud failid" "Bluetoothi jagamine: vastuvõetud failid" - - - - + "{count,plural, =1{# ebaõnnestus.}other{# ebaõnnestus.}}" + "{count,plural, =1{# õnnestus, %1$s}other{# õnnestus, %1$s}}" "Tühjendage loend" "Ava" "Eemaldage loendist" @@ -130,4 +129,10 @@ "Bluetoothi heli" "Faile, mis on üle 4 GB, ei saa üle kanda" "Ühenda Bluetoothiga" + "Bluetooth on lennukirežiimis sisse lülitatud" + "Kui hoiate Bluetoothi sisselülitatuna, jätab telefon teie valiku meelde ja kasutab seda järgmisel korral lennukirežiimi aktiveerimisel." + "Bluetooth jääb sisselülitatuks" + "Teie telefon hoiab Bluetoothi lennukirežiimis sisselülitatuna. Lülitage Bluetooth välja, kui te ei soovi, et see oleks sisse lülitatud." + "WiFi ja Bluetoothi jäävad sisselülitatuks" + "Teie telefon hoiab WiFi ja Bluetoothi lennukirežiimis sisselülitatuna. Lülitage WiFi ja Bluetooth välja, kui te ei soovi, et need oleksid sisse lülitatud." diff --git a/android/app/res/values-eu/strings.xml b/android/app/res/values-eu/strings.xml index f36de666292..72a8773ed4c 100644 --- a/android/app/res/values-eu/strings.xml +++ b/android/app/res/values-eu/strings.xml @@ -20,14 +20,15 @@ "Bluetooth bidezko partekatzeen kudeatzailea atzitzea eta fitxategiak transferitzeko erabiltzeko baimena ematen die aplikazioei." "Ezarri Bluetooth bidezko gailuak onartutakoen zerrendan." "Bluetooth bidezko gailu bat aldi baterako onartutakoen zerrendan ezartzeko baimena ematen die aplikazioei, gailu honetara fitxategiak bidaltzeko baimena izan dezan, baina gailu honen erabiltzaileari berrespena eskatu beharrik gabe." - "Bluetooth-a" + "Bluetootha" "Identifikatu ezin den gailua" "Ezezaguna" + "Ez dira zehaztu" "Hegaldi modua" - "Ezin duzu erabili Bluetooth-a Hegaldi moduan." + "Ezin duzu erabili Bluetootha Hegaldi moduan." - "Bluetooth-zerbitzuak erabiltzeko, Bluetooth-a aktibatu behar duzu." - "Bluetooth-a aktibatu nahi duzu?" + "Bluetooth-zerbitzuak erabiltzeko, Bluetootha aktibatu behar duzu." + "Bluetootha aktibatu nahi duzu?" "Utzi" "Aktibatu" "Fitxategi-transferentzia" @@ -38,11 +39,11 @@ "\"%1$s\" igorlearen sarrerako fitxategia onartzeko denbora-muga gainditu da" "Sarrerako fitxategia" "%1$s igorlea prest dago fitxategi hau bidaltzeko: %2$s" - "Bluetooth bidez partekatzea: %1$s fitxategia jasotzen" + "Bluetooth bidez partekatzea: %1$s jasotzen" "Bluetooth bidez partekatzea: %1$s fitxategia jaso da" "Bluetooth bidez partekatzea: ez da jaso %1$s fitxategia" - "Bluetooth bidez partekatzea: %1$s fitxategia bidaltzen" - "Bluetooth bidez partekatzea: %1$s fitxategia bidali da" + "Bluetooth bidez partekatzea: %1$s bidaltzen" + "Bluetooth bidez partekatzea: %1$s bidali da" "% 100ean osatuta" "Bluetooth bidez partekatzea: ez da bidali %1$s fitxategia" "Fitxategi-transferentzia" @@ -76,7 +77,7 @@ "Ez dago fitxategirik" "Ez dago horrelako fitxategirik. \n" "Itxaron…" - "Bluetooth-a aktibatzen…" + "Bluetootha aktibatzen…" "Fitxategia jasoko da. Egoera kontrolatzeko, joan Jakinarazpenen panelera." "Ezin da fitxategia jaso." "\"%1$s\" igorlearen fitxategia jasotzeari utzi zaio" @@ -109,10 +110,8 @@ "Elementu guztiak zerrendatik garbituko dira." "Bluetooth bidez partekatzea: fitxategiak bidali dira" "Bluetooth bidez partekatzea: fitxategiak jaso dira" - - - - + "{count,plural, =1{# hutsegite.}other{# hutsegite.}}" + "{count,plural, =1{# partekatze, %1$s}other{# partekatze, %1$s}}" "Garbitu zerrenda" "Ireki" "Garbitu zerrendatik" @@ -129,5 +128,11 @@ "Deskonektatu da Bluetooth bidezko audioa" "Bluetooth bidezko audioa" "Ezin dira transferitu 4 GB baino gehiagoko fitxategiak" - "Konektatu Bluetooth-era" + "Konektatu Bluetoothera" + "Bluetootha aktibatuta mantentzen da hegaldi moduan" + "Bluetootha aktibatuta utziz gero, hura aktibatuta mantentzeaz gogoratuko da telefonoa hegaldi modua erabiltzen duzun hurrengoan" + "Bluetootha aktibatuta mantenduko da" + "Hegaldi moduan, Bluetootha aktibatuta mantentzeaz gogoratzen da telefonoa. Halakorik nahi ez baduzu, desaktiba ezazu zuk zeuk." + "Wifia eta Bluetootha aktibatuta mantentzen dira" + "Hegaldi moduan, wifia eta Bluetootha aktibatuta mantentzeaz gogoratzen da telefonoa. Halakorik nahi ez baduzu, desaktiba itzazu zuk zeuk." diff --git a/android/app/res/values-fa/strings.xml b/android/app/res/values-fa/strings.xml index cf6a5a5524e..a6234d2ef37 100644 --- a/android/app/res/values-fa/strings.xml +++ b/android/app/res/values-fa/strings.xml @@ -23,6 +23,7 @@ "بلوتوث" "دستگاه ناشناس" "ناشناس" + "ارائه نشده است" "حالت هواپیما" "در حالت هواپیما نمی‌توانید از بلوتوث استفاده کنید." @@ -37,7 +38,7 @@ "تأیید" "هنگام پذیرش یک فایل ورودی از \"%1$s\" درنگ پیش آمد" "فایل ورودی" - "%1$s آماده ارسال فایل است: %2$s" + "‏%1$s آماده ارسال فایل است: %2$s" "اشتراک بلوتوث: در حال دریافت %1$s" "اشتراک بلوتوث: %1$s دریافت شد" "اشتراک بلوتوث: فایل %1$sدریافت نشد" @@ -109,10 +110,8 @@ "همهٔ موارد از فهرست پاک می‌شوند." "اشتراک بلوتوث: فایل‌های ارسال شده" "اشتراک بلوتوث: فایل‌های دریافت شده" - - - - + "{count,plural, =1{# مورد ناموفق.}one{# مورد ناموفق.}other{# مورد ناموفق.}}" + "{count,plural, =1{‏# مورد موفق، %1$s}one{‏# مورد موفق، %1$s}other{‏# مورد موفق، %1$s}}" "پاک کردن فهرست" "باز کردن" "پاک کردن از فهرست" @@ -130,4 +129,10 @@ "بلوتوث‌ صوتی" "فایل‌های بزرگ‌تر از ۴ گیگابایت نمی‌توانند منتقل شوند" "اتصال به بلوتوث" + "بلوتوث در «حالت هواپیما» روشن باشد" + "اگر بلوتوث را روشن نگه دارید، تلفنتان به‌یاد خواهد داشت تا دفعه بعدی که در «حالت هواپیما» هستید آن را روشن نگه دارد" + "بلوتوث روشن بماند" + "تلفنتان به‌یاد می‌آورد که بلوتوث را در «حالت هواپیما» روشن نگه دارد. اگر نمی‌خواهید بلوتوث روشن بماند، آن را خاموش کنید." + "‏‫Wi-Fi و بلوتوث روشن بماند" + "‏تلفنتان به‌یاد می‌آورد که Wi-Fi و بلوتوث را در «حالت هواپیما» روشن نگه دارد. اگر نمی‌خواهید Wi-Fi و بلوتوث روشن بمانند، آن‌ها را خاموش کنید." diff --git a/android/app/res/values-fi/strings.xml b/android/app/res/values-fi/strings.xml index daa17cf0dbc..dadce8f0870 100644 --- a/android/app/res/values-fi/strings.xml +++ b/android/app/res/values-fi/strings.xml @@ -23,6 +23,7 @@ "Bluetooth" "Tuntematon laite" "Tuntematon" + "Ei saatavilla" "Lentokonetila" "Et voi käyttää Bluetoothia lentokonetilassa." @@ -42,7 +43,7 @@ "Bluetooth-jako: %1$s vastaanotettu" "Bluetooth-jako: tiedostoa %1$s ei vastaanotettu" "Bluetooth-jako: lähetetään tiedostoa %1$s" - "Bluetooth-jako: lähetä %1$s" + "Bluetooth-jako: %1$s lähetetty" "100 % valmis" "Bluetooth-jako: tiedostoa %1$s ei lähetetty" "Tiedostonsiirto" @@ -109,10 +110,8 @@ "Koko luettelo tyhjennetään." "Bluetooth-jako: Lähetetyt tiedostot" "Bluetooth-jako: Vastaanotetut tiedostot" - - - - + "{count,plural, =1{# epäonnistui}other{# epäonnistui}}" + "{count,plural, =1{# onnistui, %1$s}other{# onnistui, %1$s}}" "Tyhjennä luettelo" "Avaa" "Poista luettelosta" @@ -130,4 +129,10 @@ "Bluetooth-ääni" "Yli 4 Gt:n kokoisia tiedostoja ei voi siirtää." "Muodosta Bluetooth-yhteys" + "Bluetooth päällä lentokonetilassa" + "Jos pidät Bluetooth-yhteyden päällä, puhelin pitää sen päällä, kun seuraavan kerran olet lentokonetilassa" + "Bluetooth pysyy päällä" + "Puhelimen Bluetooth pysyy päällä lentokonetilassa. Voit halutessasi laittaa Bluetooth-yhteyden pois päältä." + "Wi-Fi ja Bluetooth pysyvät päällä" + "Puhelimen Wi-Fi-yhteys ja Bluetooth pysyvät päällä lentokonetilassa. Voit halutessasi laittaa ne pois päältä." diff --git a/android/app/res/values-fr-rCA/strings.xml b/android/app/res/values-fr-rCA/strings.xml index 9e45c9833a0..a31fd1f34d3 100644 --- a/android/app/res/values-fr-rCA/strings.xml +++ b/android/app/res/values-fr-rCA/strings.xml @@ -23,6 +23,7 @@ "Bluetooth" "Périphérique inconnu" "Inconnu" + "Non fourni" "Mode Avion" "Bluetooth ne peut être utilisé en mode Avion." @@ -38,10 +39,10 @@ "Expiration du délai de réception du fichier de \"%1$s\"" "Fichier entrant" "%1$s est prêt à vous envoyer un fichier : %2$s" - "Partage Bluetooth : réception de %1$s" + "Partage Bluetooth : réception de %1$s en cours…" "Partage Bluetooth : %1$s reçu(s)" "Partage Bluetooth : fichier %1$s non reçu" - "Partage Bluetooth : envoi de %1$s" + "Partage Bluetooth : envoi de %1$s en cours…" "Partage Bluetooth : %1$s envoyé" "100 % effectués" "Partage Bluetooth : fichier %1$s non envoyé" @@ -80,9 +81,9 @@ "La réception du fichier va commencer. La progression va s\'afficher dans le panneau de notification." "Impossible de recevoir le fichier." "Réception du fichier de \"%1$s\" interrompue" - "Envoi du fichier à \"%1$s\"" + "Envoi du fichier à « %1$s »" "Envoi de %1$s fichiers à \"%2$s\"" - "Envoi du fichier à \"%1$s\" interrompu" + "Envoi du fichier à « %1$s » interrompu" "Espace insuffisant sur la mémoire de stockage USB pour l\'enregistrement du fichier." "Espace insuffisant sur la carte SD pour l\'enregistrement du fichier." "Espace requis : %1$s" @@ -109,10 +110,8 @@ "Tous les éléments de la liste seront effacés." "Partage Bluetooth : fichiers envoyés" "Partage Bluetooth : fichiers reçus" - - - - + "{count,plural, =1{# fichier non transféré.}one{# fichier non transféré.}other{# fichiers non transférés.}}" + "{count,plural, =1{# fichier transféré, %1$s}one{# fichier transféré, %1$s}other{# fichiers transférés, %1$s}}" "Effacer la liste" "ouvrir" "Effacer de la liste" @@ -130,4 +129,10 @@ "Audio Bluetooth" "Les fichiers dépassant 4 Go ne peuvent pas être transférés" "Connexion au Bluetooth" + "Bluetooth activé en mode Avion" + "Si vous laissez le Bluetooth activé, votre téléphone se souviendra qu\'il doit le laisser activé la prochaine fois que vous serez en mode Avion" + "Le Bluetooth reste activé" + "Votre téléphone se souvient de garder le Bluetooth activé en mode Avion. Désactivez le Bluetooth si vous ne souhaitez pas qu\'il reste activé." + "Le Wi-Fi et le Bluetooth restent activés" + "Votre téléphone se souvient de garder le Wi-Fi et le Bluetooth activés en mode Avion. Désactivez le Wi-Fi et le Bluetooth si vous ne souhaitez pas qu\'ils restent activés." diff --git a/android/app/res/values-fr/strings.xml b/android/app/res/values-fr/strings.xml index ccce11a9e0b..c21ab432091 100644 --- a/android/app/res/values-fr/strings.xml +++ b/android/app/res/values-fr/strings.xml @@ -23,6 +23,7 @@ "Bluetooth" "Périphérique inconnu" "Inconnu" + "Non fourni" "Mode Avion" "Bluetooth ne peut être utilisé en mode Avion." @@ -109,10 +110,8 @@ "Tous les éléments de la liste seront effacés." "Partage Bluetooth : fichiers envoyés" "Partage Bluetooth : fichiers reçus" - - - - + "{count,plural, =1{# échec.}one{# échec.}other{# échecs.}}" + "{count,plural, =1{# succès, %1$s}one{# succès, %1$s}other{# succès, %1$s}}" "Effacer la liste" "Ouvrir" "Effacer de la liste" @@ -130,4 +129,10 @@ "Audio Bluetooth" "Impossible de transférer les fichiers supérieurs à 4 Go" "Se connecter au Bluetooth" + "Bluetooth activé en mode Avion" + "Si vous laissez le Bluetooth activé, votre téléphone s\'en souviendra et le Bluetooth restera activé la prochaine fois que vous serez en mode Avion" + "Le Bluetooth reste activé" + "Le Bluetooth restera activé en mode Avion. Vous pouvez le désactiver si vous le souhaitez." + "Le Wi-Fi et le Bluetooth restent activés" + "Le Wi‑Fi et le Bluetooth de votre téléphone resteront activés en mode Avion. Vous pouvez les désactivez si vous le souhaitez." diff --git a/android/app/res/values-gl/strings.xml b/android/app/res/values-gl/strings.xml index 33467182096..65c367f494d 100644 --- a/android/app/res/values-gl/strings.xml +++ b/android/app/res/values-gl/strings.xml @@ -23,6 +23,7 @@ "Bluetooth" "Dispositivo descoñecido" "Descoñecido" + "Non fornecidos" "Modo avión" "Non se pode usar o Bluetooth no modo avión." @@ -109,10 +110,8 @@ "Borraranse todos os elementos da lista." "Uso compartido por Bluetooth: ficheiros enviados" "Uso compartido por Bluetooth: ficheiros recibidos" - - - - + "{count,plural, =1{# non transferido.}other{# non transferidos.}}" + "{count,plural, =1{# transferido, %1$s}other{# transferidos, %1$s}}" "Borrar lista" "Abrir" "Borrar da lista" @@ -130,4 +129,10 @@ "Audio por Bluetooth" "Non se poden transferir ficheiros de máis de 4 GB" "Conectar ao Bluetooth" + "Bluetooth activado no modo avión" + "Se mantés o Bluetooth activado, o teléfono lembrará que ten que deixalo nese estado a próxima vez que esteas no modo avión" + "O Bluetooth permanece activado" + "O teu teléfono lembrará manter o Bluetooth activado no modo avión. Se non queres que permaneza nese estado, desactívao." + "A wifi e o Bluetooth permanecen activados" + "O teu teléfono lembrará manter a wifi e o Bluetooth activados no modo avión. Se non queres que permanezan nese estado, desactívaos." diff --git a/android/app/res/values-gu/strings.xml b/android/app/res/values-gu/strings.xml index 966d907931a..d33df6b00b7 100644 --- a/android/app/res/values-gu/strings.xml +++ b/android/app/res/values-gu/strings.xml @@ -23,6 +23,7 @@ "બ્લૂટૂથ" "અજાણ્યું ઉપકરણ" "અજાણ્યો" + "આપ્યો નથી" "એરપ્લેન મોડ" "તમે એરપ્લેન મોડમાં બ્લૂટૂથ નો ઉપયોગ કરી શકતા નથી." @@ -109,10 +110,8 @@ "સૂચિમાંથી તમામ આઇટમ્સ સાફ કરવામાં આવશે." "બ્લૂટૂથ શેર: મોકલેલી ફાઇલો" "બ્લૂટૂથ શેર: પ્રાપ્ત ફાઇલો" - - - - + "{count,plural, =1{# અસફળ.}one{# અસફળ.}other{# અસફળ.}}" + "{count,plural, =1{# સફળ, %1$s}one{# સફળ, %1$s}other{# સફળ, %1$s}}" "સૂચિ સાફ કરો" "ખોલો" "સૂચિમાંથી સાફ કરો" @@ -130,4 +129,10 @@ "બ્લૂટૂથ ઑડિઓ" "4GB કરતા મોટી ફાઇલ ટ્રાન્સફર કરી શકાતી નથી" "બ્લૂટૂથ સાથે કનેક્ટ કરો" + "એરપ્લેન મોડમાં બ્લૂટૂથ ચાલુ છે" + "જો તમે બ્લૂટૂથ ચાલુ રાખો, તો તમે જ્યારે આગલી વખતે એરપ્લેન મોડ પર જશો, ત્યારે તમારો ફોન તેને ચાલુ રાખવાનું યાદ રાખશે" + "બ્લૂટૂથ ચાલુ રહેશે" + "તમારો ફોન બ્લૂટૂથને એરપ્લેન મોડમાં ચાલુ રાખવાનું યાદ રાખે છે. જો તમે બ્લૂટૂથ ચાલુ રાખવા માગતા ન હો, તો તેને બંધ કરો." + "વાઇ-ફાઇ અને બ્લૂટૂથ ચાલુ રહે છે" + "તમારો ફોન વાઇ-ફાઇ અને બ્લૂટૂથને એરપ્લેન મોડમાં ચાલુ રાખવાનું યાદ રાખે છે. જો તમે વાઇ-ફાઇ અને બ્લૂટૂથ ચાલુ રાખવા માગતા ન હો, તો તેને બંધ કરો." diff --git a/android/app/res/values-hi/strings.xml b/android/app/res/values-hi/strings.xml index 1e202e15617..829042394ea 100644 --- a/android/app/res/values-hi/strings.xml +++ b/android/app/res/values-hi/strings.xml @@ -23,6 +23,7 @@ "ब्लूटूथ" "अज्ञात डिवाइस" "अज्ञात" + "नहीं दिया गया है" "हवाई जहाज़ मोड" "आप हवाई जहाज मोड में ब्लूटूथ का उपयोग नहीं कर सकते हैं." @@ -31,14 +32,14 @@ "रद्द करें" "चालू करें" "फ़ाइल ट्रांसफ़र करें" - "आवक फ़ाइल स्वीकार करें?" + "इनकमिंग फ़ाइल स्वीकार करें?" "अस्वीकारें" "स्वीकारें" "ठीक है" "\"%1$s\" से आने वाली फ़ाइल स्वीकार करते हुए टाइम आउट हो गया." - "आवक फ़ाइल" + "इनकमिंग फ़ाइल" "%1$s, इस फ़ाइल को भेजने के लिए तैयार है: %2$s" - "ब्लूटूथ शेयर: %1$s पा रहा है" + "ब्लूटूथ शेयर: %1$s मिल रही है" "ब्लूटूथ शेयर: %1$s पाई गई" "ब्लूटूथ शेयर: फ़ाइल %1$s नहीं मिली" "ब्लूटूथ शेयर: %1$s भेज रहा है" @@ -53,9 +54,9 @@ "फ़ाइल पा रहा है…" "रोकें" "छुपाएं" - "प्रेषक" - "फ़ाइल नाम" - "आकार" + "भेजने वाला" + "फ़ाइल का नाम" + "साइज़" "फ़ाइल नहीं मिली" "फ़ाइल: %1$s" "कारण: %1$s" @@ -109,10 +110,8 @@ "सूची से सभी आइटम साफ़ कर दिए जाएंगे." "ब्लूटूथ शेयर: भेजी गई फ़ाइलें" "ब्लूटूथ शेयर: पाई गई फ़ाइलें" - - - - + "{count,plural, =1{# फ़ाइल शेयर नहीं की जा सकी.}one{# फ़ाइल शेयर नहीं की जा सकी.}other{# फ़ाइलें शेयर नहीं की जा सकीं.}}" + "{count,plural, =1{# फ़ाइल शेयर की गई, %1$s}one{# फ़ाइल शेयर की गई, %1$s}other{# फ़ाइलें शेयर की गईं, %1$s}}" "सूची साफ़ करें" "खोलें" "सूची से साफ़ करें" @@ -130,4 +129,10 @@ "ब्लूटूथ ऑडियो" "4 जीबी से बड़ी फ़ाइलें ट्रांसफ़र नहीं की जा सकतीं" "ब्लूटूथ से कनेक्ट करें" + "हवाई जहाज़ मोड में ब्लूटूथ चालू है" + "ब्लूटूथ चालू रखने पर आपका फ़ोन, अगली बार हवाई जहाज़ मोड चालू होने पर भी ब्लूटूथ चालू रखेगा" + "ब्लूटूथ चालू रहता है" + "हवाई जहाज़ मोड में भी, आपका फ़ोन ब्लूटूथ चालू रखता है. अगर ब्लूटूथ चालू नहीं रखना है, तो उसे बंद कर दें." + "वाई-फ़ाई और ब्लूटूथ चालू रहते हैं" + "हवाई जहाज़ मोड में भी, आपका फ़ोन वाई-फ़ाई और ब्लूटूथ को चालू रखता है. अगर आपको वाई-फ़ाई और ब्लूटूथ चालू नहीं रखना है, तो उन्हें बंद कर दें." diff --git a/android/app/res/values-hr/strings.xml b/android/app/res/values-hr/strings.xml index f3094a432f8..f660c0ba248 100644 --- a/android/app/res/values-hr/strings.xml +++ b/android/app/res/values-hr/strings.xml @@ -23,6 +23,7 @@ "Bluetooth" "Nepoznati uređaj" "Nepoznato" + "Nije navedeno" "Način rada u zrakoplovu" "Bluetooth se ne može upotrebljavati u načinu rada u zrakoplovu." @@ -38,13 +39,13 @@ "Za vrijeme primanja datoteke koju šalje \"%1$s\" došlo je do privremenog prekida" "Dolazna datoteka" "%1$s sada može poslati datoteku: %2$s" - "Dijeljenje Bluetoothom: Primanje datoteke %1$s" - "Dijeljenje Bluetoothom: Primljena datoteka %1$s" - "Dijeljenje Bluetoothom: Datoteka %1$s nije primljena" - "Dijeljenje Bluetoothom: Slanje datoteke %1$s" - "Dijeljenje Bluetoothom: Datoteka %1$s poslana" + "Dijeljenje Bluetoothom: primanje datoteke %1$s" + "Dijeljenje Bluetoothom: primljena datoteka %1$s" + "Dijeljenje Bluetoothom: datoteka %1$s nije primljena" + "Dijeljenje Bluetoothom: slanje datoteke %1$s" + "Dijeljenje Bluetoothom: datoteka %1$s poslana" "100% dovršeno" - "Dijeljenje Bluetoothom: Datoteka %1$s nije poslana" + "Dijeljenje Bluetoothom: datoteka %1$s nije poslana" "Prijenos datoteke" "Šalje: \"%1$s\"" "Datoteka: %1$s" @@ -107,12 +108,10 @@ "Odlazni prijenosi" "Povijest prijenosa je prazna." "S popisa će biti izbrisane sve stavke." - "Bluetooth dijeljenje: poslane datoteke" - "Bluetooth dijeljenje: primljene datoteke" - - - - + "Dijeljenje Bluetoothom: poslane datoteke" + "Dijeljenje Bluetoothom: primljene datoteke" + "{count,plural, =1{# neuspješno.}one{# neuspješno.}few{# neuspješno.}other{# neuspješno.}}" + "{count,plural, =1{# uspješno, %1$s}one{# uspješno, %1$s}few{# uspješno, %1$s}other{# uspješno, %1$s}}" "Izbriši popis" "Otvori" "Izbriši s popisa" @@ -130,4 +129,10 @@ "Bluetooth Audio" "Datoteke veće od 4 GB ne mogu se prenijeti" "Povezivanje s Bluetoothom" + "Bluetooth je uključen u načinu rada u zrakoplovu" + "Ako Bluetooth ostane uključen, telefon će zapamtiti da treba ostati uključen u načinu rada u zrakoplovu" + "Bluetooth ostaje uključen" + "Telefon će zapamtiti da Bluetooth treba ostati uključen u načinu rada u zrakoplovu. Isključite Bluetooth ako ne želite da ostane uključen." + "Wi-Fi i Bluetooth ostat će uključeni" + "Telefon će zapamtiti da Wi‑Fi i Bluetooth trebaju ostati uključeni u načinu rada u zrakoplovu. Uključite Wi-Fi i Bluetooth ako ne želite da ostanu uključeni." diff --git a/android/app/res/values-hu/strings.xml b/android/app/res/values-hu/strings.xml index 104a9a94cf4..85a1c3ecd85 100644 --- a/android/app/res/values-hu/strings.xml +++ b/android/app/res/values-hu/strings.xml @@ -23,6 +23,7 @@ "Bluetooth" "Ismeretlen eszköz" "Ismeretlen" + "Nincs megadva" "Repülőgép üzemmód" "A Bluetooth nem használható Repülőgép üzemmódban." @@ -109,10 +110,8 @@ "Minden elemet töröl a listáról." "Bluetooth-megosztás: elküldött fájlok" "Bluetooth-megosztás: fogadott fájlok" - - - - + "{count,plural, =1{# sikertelen.}other{# sikertelen.}}" + "{count,plural, =1{# sikeres, %1$s}other{# sikeres, %1$s}}" "Lista törlése" "Megnyitás" "Törlés a listáról" @@ -130,4 +129,10 @@ "Bluetooth audió" "A 4 GB-nál nagyobb fájlokat nem lehet átvinni" "Csatlakozás Bluetooth-eszközhöz" + "Bluetooth bekapcsolva Repülős üzemmódban" + "Ha bekapcsolva tartja a Bluetootht, a telefon emlékezni fog arra, hogy a következő alkalommal, amikor Repülős üzemmódban van, bekapcsolva tartsa a funkciót." + "A Bluetooth bekapcsolva marad" + "A telefon bekapcsolva tartja a Bluetootht Repülős üzemmódban. Kapcsolja ki a Bluetootht, ha nem szeretné, hogy bekapcsolva maradjon." + "A Wi-Fi és a Bluetooth bekapcsolva marad" + "A telefon bekapcsolva tartja a Wi‑Fi-t és a Bluetootht Repülős üzemmódban. Ha nem szeretné, hogy bekapcsolva maradjon a Wi-Fi és a Bluetooth, kapcsolja ki őket." diff --git a/android/app/res/values-hy/strings.xml b/android/app/res/values-hy/strings.xml index 4ccc27eea96..af488cef809 100644 --- a/android/app/res/values-hy/strings.xml +++ b/android/app/res/values-hy/strings.xml @@ -23,6 +23,7 @@ "Bluetooth" "Անհայտ սարք" "Անհայտ" + "Մետատվյալներ չեն տրամադրվել" "Ավիառեժիմ" "Դուք չեք կարող օգտվել Bluetooth-ից Ավիառեժիմում:" @@ -31,20 +32,20 @@ "Չեղարկել" "Միացնել" "Ֆայլերի փոխանցում" - "Ընդունե՞լ մուտքային ֆայլը:" + "Ընդունե՞լ մուտքային ֆայլը" "Մերժել" "Ընդունել" "Եղավ" %1$s»-ից մուտքային ֆայլի ընդունման ժամանակը սպառվեց" "Մուտքային ֆայլ" %1$s» սարքը պատրաստ է ուղարկել այս ֆայլը՝ %2$s" - "Bluetooth համօգտագործում՝ %1$s-ը ստացվում է" - "Bluetooth համօգտագործում՝ ստացվեց %1$s-ը" - "Bluetooth համօգտագործում՝ %1$s ֆայլը չի ստացվել" - "Bluetooth համօգտագործում՝ ուղարկվում է %1$s-ը" - "Bluetooth համօգտագործում՝ %1$s-ն ուղարկված է" + "Bluetooth-ով փոխանցում․ %1$s ֆայլն ընդունվում է" + "Bluetooth-ով փոխանցում․ %1$s ֆայլն ընդունվեց" + "Bluetooth-ով փոխանցում․ %1$s ֆայլը չի ընդունվել" + "Bluetooth-ով փոխանցում․ ուղարկվում է %1$s ֆայլը" + "Bluetooth-ով փոխանցում․ %1$s ֆայլն ուղարկվեց" "100% ավարտուն" - "Bluetooth համօգտագործում՝ %1$s ֆայլը չի ուղարկվել" + "Bluetooth-ով փոխանցում․ %1$s ֆայլը չի ուղարկվել" "Ֆայլերի փոխանցում" "Ումից՝ «%1$s»" "Ֆայլ՝ %1$s" @@ -55,7 +56,7 @@ "Թաքցնել" "Ումից" "Ֆայլի անունը" - "Չափը" + "Չափսը" "Ֆայլը չհաջողվեց ստանալ" "Ֆայլ՝ %1$s" "Պատճառը՝ %1$s" @@ -100,19 +101,17 @@ "Հարցումը հնարավոր չէ ճշգրտորեն մշակել:" "Անհայտ սխալ:" "Bluetooth-ով ստացված" - "Bluetooth համօգտագործում" + "Bluetooth-ով փոխանցում" "%1$s ստացումն ավարտված է:" "%1$s ուղարկումն ավարտված է:" "Մուտքային փոխանցումներ" "Ելքային փոխանցումներ" "Փոխանցումների պատմությունը դատարկ է:" "Ցուցակի բոլոր տվյալները կջնջվեն:" - "Bluetooth համօգտագործում՝ ֆայլերն ուղարկված են" - "Bluetooth համօգտագործում՝ ֆայլերը ստացված են" - - - - + "Bluetooth-ով փոխանցում․ ֆայլերն ուղարկված են" + "Bluetooth-ով փոխանցում․ ֆայլերը ստացված են" + "{count,plural, =1{# չհաջողված։}one{# չհաջողված։}other{# չհաջողված։}}" + "{count,plural, =1{# հաջողված, %1$s}one{# հաջողված, %1$s}other{# հաջողված, %1$s}}" "Ջնջել ցուցակը" "Բաց" "Ջնջել ցուցակից" @@ -130,4 +129,10 @@ "Bluetooth աուդիո" "4 ԳԲ-ից մեծ ֆայլերը հնարավոր չէ փոխանցել" "Միանալ Bluetooth-ին" + "Bluetooth-ը միացված է ավիառեժիմում" + "Եթե Bluetooth-ը միացված թողնեք, հաջորդ անգամ այն ավտոմատ միացված կմնա ավիառեժիմում" + "Bluetooth-ը կմնա միացված" + "Ավիառեժիմում Bluetooth-ը միացված կմնա։ Ցանկության դեպքում կարող եք անջատել Bluetooth-ը։" + "Wi-Fi-ը և Bluetooth-ը մնում են միացված" + "Ավիառեժիմում Wi-Fi-ը և Bluetooth-ը միացված կմնան։ Ցանկության դեպքում կարող եք անջատել Wi-Fi-ը և Bluetooth-ը։" diff --git a/android/app/res/values-in/strings.xml b/android/app/res/values-in/strings.xml index 07223ec90f5..5aeac7db04e 100644 --- a/android/app/res/values-in/strings.xml +++ b/android/app/res/values-in/strings.xml @@ -23,6 +23,7 @@ "Bluetooth" "Perangkat tidak diketahui" "Tidak diketahui" + "Tidak Tersedia" "Mode pesawat" "Anda tidak dapat menggunakan Bluetooth dalam mode Pesawat." @@ -38,13 +39,13 @@ "Terjadi waktu tunggu saat menerima file masuk dari \"%1$s\"" "File masuk" "%1$s siap mengirim file: %2$s" - "Berbagi Bluetooth: Menerima %1$s" - "Berbagi Bluetooth: Telah menerima %1$s" - "Berbagi Bluetooth: File %1$s tidak diterima" - "Berbagi Bluetooth: Mengirim %1$s" - "Berbagi Bluetooth: Telah mengirim %1$s" + "Berbagi via Bluetooth: Sedang menerima %1$s" + "Berbagi via Bluetooth: Telah menerima %1$s" + "Berbagi via Bluetooth: File %1$s gagal diterima" + "Berbagi via Bluetooth: Sedang mengirim %1$s" + "Berbagi via Bluetooth: Telah mengirim %1$s" "100% selesai" - "Berbagi Bluetooth: File %1$s tidak terkirim" + "Berbagi via Bluetooth: File %1$s gagal dikirim" "Transfer file" "Dari: \"%1$s\"" "File: %1$s" @@ -100,19 +101,17 @@ "Permintaan tidak dapat ditangani dengan semestinya." "Kesalahan tidak dikenal." "Bluetooth diterima" - "Berbagi Bluetooth" + "Berbagi via Bluetooth" "%1$s Telah selesai diterima." "%1$s Telah selesai dikirim." "Transfer masuk" "Transfer keluar" "Histori transfer kosong." "Semua item akan dihapus dari daftar." - "Berbagi bluetooth: Telah mengirimkan file" - "Berbagi Bluetooth: File yang diterima" - - - - + "Berbagi via Bluetooth: Telah mengirim file" + "Berbagi via Bluetooth: Telah menerima file" + "{count,plural, =1{# gagal.}other{# gagal.}}" + "{count,plural, =1{# berhasil, %1$s}other{# berhasil, %1$s}}" "Hapus daftar" "Buka" "Hapus dari daftar" @@ -130,4 +129,10 @@ "Bluetooth Audio" "File yang berukuran lebih dari 4GB tidak dapat ditransfer" "Hubungkan ke Bluetooth" + "Bluetooth aktif dalam mode pesawat" + "Jika Bluetooth tetap diaktifkan, ponsel akan ingat untuk tetap mengaktifkannya saat berikutnya ponsel Anda disetel ke mode pesawat" + "Bluetooth tetap aktif" + "Ponsel akan mengingat untuk tetap mengaktifkan Bluetooth dalam mode pesawat. Nonaktifkan jika Anda tidak ingin Bluetooth terus aktif." + "Wi-Fi dan Bluetooth tetap aktif" + "Ponsel akan mengingat untuk tetap mengaktifkan Wi-Fi dan Bluetooth dalam mode pesawat. Nonaktifkan jika Anda tidak ingin Wi-Fi dan Bluetooth terus aktif." diff --git a/android/app/res/values-is/strings.xml b/android/app/res/values-is/strings.xml index 1b4232416ba..eecd43f453b 100644 --- a/android/app/res/values-is/strings.xml +++ b/android/app/res/values-is/strings.xml @@ -23,6 +23,7 @@ "Bluetooth" "Óþekkt tæki" "Óþekkt" + "Ekki gefið upp" "Flugstilling" "Þú getur ekki notað Bluetooth í flugstillingu." @@ -109,10 +110,8 @@ "Öll atriði verða hreinsuð af listanum." "Bluetooth-deiling: Sendar skrár" "Bluetooth-deiling: Mótteknar skrár" - - - - + "{count,plural, =1{# mistókst.}one{# mistókst.}other{# mistókust.}}" + "{count,plural, =1{# tókst, %1$s}one{# tókst, %1$s}other{# tókust, %1$s}}" "Hreinsa lista" "Opna" "Hreinsa af lista" @@ -130,4 +129,10 @@ "Bluetooth-hljóð" "Ekki er hægt að flytja skrár sem eru stærri en 4 GB" "Tengjast við Bluetooth" + "Kveikt á Bluetooth í flugstillingu" + "Ef þú hefur kveikt á Bluetooth mun síminn muna að hafa kveikt á því næst þegar þú stillir á flugstillingu" + "Áfram kveikt á Bluetooth" + "Síminn man að hafa kveikt á Bluetooth í flugstillingu. Slökktu á Bluetooth ef þú vilt ekki hafa kveikt á því." + "Áfram verður kveikt á Wi-Fi og Bluetooth" + "Síminn man að hafa kveikt á Wi-Fi og Bluetooth í flugstillingu. Slökktu á Wi-Fi og Bluetooth ef þú vilt ekki hafa kveikt á þessu." diff --git a/android/app/res/values-it/strings.xml b/android/app/res/values-it/strings.xml index 6da3cb55a18..289a8e572d7 100644 --- a/android/app/res/values-it/strings.xml +++ b/android/app/res/values-it/strings.xml @@ -23,6 +23,7 @@ "Bluetooth" "Dispositivo sconosciuto" "Sconosciuto" + "Non fornito" "Modalità aereo" "Non puoi utilizzare Bluetooth in modalità aereo." @@ -109,10 +110,8 @@ "Tutti gli elementi verranno cancellati dall\'elenco." "Bluetooth: file inviati" "Bluetooth: file ricevuti" - - - - + "{count,plural, =1{# non a buon fine.}other{# non a buon fine.}}" + "{count,plural, =1{# a buon fine, %1$s}other{# a buon fine, %1$s}}" "Cancella elenco" "Apri" "Cancella da elenco" @@ -130,4 +129,10 @@ "Audio Bluetooth" "Impossibile trasferire file con dimensioni superiori a 4 GB" "Connettiti a Bluetooth" + "Bluetooth attivo in modalità aereo" + "Se tieni attivo il Bluetooth, il telefono ricorderà di tenerlo attivo la prossima volta che sarai in modalità aereo" + "Il Bluetooth rimane attivo" + "Il telefono memorizza che deve tenere attivo il Bluetooth in modalità aereo. Disattiva il Bluetooth se non vuoi tenerlo attivo." + "Wi-Fi e Bluetooth rimangono attivi" + "Il telefono memorizza che deve tenere attivi il Wi‑Fi e il Bluetooth in modalità aereo. Disattiva il Wi-Fi e il Bluetooth se non vuoi tenerli attivi." diff --git a/android/app/res/values-iw/strings.xml b/android/app/res/values-iw/strings.xml index 09667181289..5b6c45a60a1 100644 --- a/android/app/res/values-iw/strings.xml +++ b/android/app/res/values-iw/strings.xml @@ -23,6 +23,7 @@ "Bluetooth" "מכשיר לא ידוע" "לא ידוע" + "לא מוגדרים" "מצב טיסה" "‏לא ניתן להשתמש ב-Bluetooth במצב טיסה." @@ -109,10 +110,8 @@ "כל הפריטים ינוקו מהרשימה." "‏שיתוף Bluetooth: נשלחו קבצים" "‏שיתוף Bluetooth: התקבלו קבצים" - - - - + "{count,plural, =1{# נכשל}one{# נכשלו}two{# נכשלו}other{# נכשלו}}" + "{count,plural, =1{‏# הצליח, %1$s}one{‏# הצליחו, %1$s}two{‏# הצליחו, %1$s}other{‏# הצליחו, %1$s}}" "ניקוי רשימה" "פתיחה" "ניקוי מהרשימה" @@ -130,4 +129,10 @@ "‏אודיו Bluetooth" "‏לא ניתן להעביר קבצים שגדולים מ-4GB" "‏התחברות באמצעות Bluetooth" + "‏חיבור ה-Bluetooth מופעל במצב טיסה" + "‏אם חיבור ה-Bluetooth נשאר מופעל, הטלפון יזכור להשאיר אותו מופעל בפעם הבאה שהוא יועבר למצב טיסה" + "‏Bluetooth יישאר מופעל" + "‏חיבור ה-Bluetooth בטלפון יישאר מופעל במצב טיסה. אפשר להשבית את ה-Bluetooth אם לא רוצים שהוא יפעל." + "‏חיבורי ה-Wi‑Fi וה-Bluetooth יישארו מופעלים" + "‏חיבורי ה-Wi‑Fi וה-Bluetooth בטלפון יישארו מופעלים במצב טיסה. אפשר להשבית את ה-Wi-Fi וה-Bluetooth אם לא רוצים שהם יפעלו." diff --git a/android/app/res/values-ja/strings.xml b/android/app/res/values-ja/strings.xml index f2da90e7caf..80ca7afc69e 100644 --- a/android/app/res/values-ja/strings.xml +++ b/android/app/res/values-ja/strings.xml @@ -23,6 +23,7 @@ "Bluetooth" "不明なモバイルデバイス" "不明" + "未指定" "機内モード" "機内モードではBluetoothを使用できません。" @@ -108,11 +109,9 @@ "転送履歴が空です。" "すべてのアイテムがリストから消去されます。" "Bluetooth共有: 送信したファイル" - "Bluetooth共有: 受信したファイル" - - - - + "Bluetooth 共有: 受信したファイル" + "{count,plural, =1{# 件失敗。}other{# 件失敗。}}" + "{count,plural, =1{# 件成功、%1$s}other{# 件成功、%1$s}}" "リストを消去" "開く" "リストから消去" @@ -130,4 +129,10 @@ "Bluetooth オーディオ" "4 GB を超えるファイルは転送できません" "Bluetooth に接続する" + "機内モードで Bluetooth を ON にする" + "Bluetooth を ON にしておくと、次に機内モードになったときも ON のままになります" + "Bluetooth を ON にしておく" + "機内モードでも、スマートフォンの Bluetooth は ON のままになります。Bluetooth を ON にしたくない場合は OFF にしてください。" + "Wi-Fi と Bluetooth を ON のままにする" + "機内モードでも、スマートフォンの Wi-Fi と Bluetooth は ON のままになります。Wi-Fi と Bluetooth を ON にしたくない場合は OFF にしてください。" diff --git a/android/app/res/values-ka/strings.xml b/android/app/res/values-ka/strings.xml index 1ccbf2d8874..7eec41ad237 100644 --- a/android/app/res/values-ka/strings.xml +++ b/android/app/res/values-ka/strings.xml @@ -23,6 +23,7 @@ "Bluetooth" "უცნობი მოწყობილობა" "უცნობი" + "არ არის მითითებული" "თვითმფრინავის რეჟიმი" "თვითმფრინავის რეჟიმში Bluetooth-ს ვერ გამოიყენებთ." @@ -109,10 +110,8 @@ "სიიდან ყველა ერთეული ამოიშლება." "Bluetooth გაზიარება: გაგზავნილი ფაილები" "Bluetooth გაზიარება: მიღებული ფაილები" - - - - + "{count,plural, =1{# წარუმატებელი.}other{# წარუმატებელი.}}" + "{count,plural, =1{# წარმატებული, %1$s}other{# წარმატებული, %1$s}}" "სიის გასუფთავება" "გახსნა" "სიიდან ამოშლა" @@ -130,4 +129,10 @@ "Bluetooth აუდიო" "4 გბაიტზე დიდი მოცულობის ფაილების გადატანა ვერ მოხერხდება" "Bluetooth-თან დაკავშირება" + "Bluetooth ჩართულია თვითმფრინავის რეჟიმში" + "თუ Bluetooth-ს ჩართულს დატოვებთ, თქვენი ტელეფონი დაიმახსოვრებს და ჩართულს დატოვებს მას, როდესაც შემდეგ ჯერზე თვითმფრინავის რეჟიმში იქნებით" + "Bluetooth რᲩება Ჩართული" + "თქვენს ტელეფონს ემახსოვრება, რომ Bluetooth ჩართული უნდა იყოს თვითმფრინავის რეჟიმში. გამორთეთ Bluetooth, თუ არ გსურთ, რომ ის ჩართული იყოს." + "Wi-Fi და Bluetooth ჩართული დარჩება" + "თქვენს ტელეფონს ემახსოვრება, რომ Wi‑Fi და Bluetooth ჩართული უნდა იყოს თვითმფრინავის რეჟიმში. გამორთეთ Wi-Fi და Bluetooth, თუ არ გსურთ, რომ ისინი ჩართული იყოს." diff --git a/android/app/res/values-kk/strings.xml b/android/app/res/values-kk/strings.xml index e8f9a45b210..2280615c58c 100644 --- a/android/app/res/values-kk/strings.xml +++ b/android/app/res/values-kk/strings.xml @@ -23,6 +23,7 @@ "Bluetooth" "Белгісіз құрылғы" "Белгісіз" + "Берілмеген" "Ұшақ режимі" "Bluetooth байланысын ұшақ режимінде қолдану мүмкін емес." @@ -38,7 +39,7 @@ "\"%1$s\" жіберген файлды қабылдау барысында уақыт аяқталды." "Кіріс файл" "%1$s келесі файлды жіберуге дайын: %2$s" - "Bluetooth бөлісу: %1$s файлын қабылдауда" + "Bluetooth арқылы бөлісу: %1$s файлы қабылдануда" "Bluetooth бөлісу: %1$s файлы қабылданды" "Bluetooth бөлісу: %1$s файлы қабылданбады" "Bluetooth бөлісу: %1$s файлын жіберуде" @@ -90,7 +91,7 @@ "Файлды аудару әлі басталған жоқ." "Файлды аудару орындалуда." "Файлды аудару сәтті орындалды." - "Мазмұн қолдауы жоқ." + "Контент қолдауы жоқ." "Аударуға қабылдайтын құрылғы тыйым салды." "Тасымалды пайдаланушы тоқтатты." "Жад ақаулығы." @@ -108,11 +109,9 @@ "Тасымал туралы дерек жоқ." "Тізімнен барлық элементтер алынады." "Bluetooth бөлісу: Жіберілген файлдар" - "Bluetooth бөлісу: Қабылданған файлдар" - - - - + "Bluetooth арқылы бөлісу: қабылданған файлдар" + "{count,plural, =1{# жіберілмеді.}other{# жіберілмеді.}}" + "{count,plural, =1{# жіберілді, %1$s}other{# жіберілді, %1$s}}" "Тізімді өшіру" "Ашу" "Тізімнен өшіру." @@ -130,4 +129,10 @@ "Bluetooth aудиосы" "Көлемі 4 ГБ-тан асатын файлдар тасымалданбайды" "Bluetooth-қа қосылу" + "Bluetooth ұшақ режимінде қосулы" + "Bluetooth-ты қосулы қалдырсаңыз, келесі жолы ұшақ режиміне ауысқанда да ол қосылып тұрады." + "Bluetooth қосулы болады" + "Bluetooth ұшақ режимінде қосылып тұрады. Қаласаңыз, оны өшіріп қоюыңызға болады." + "Wi-Fi мен Bluetooth қосулы тұрады" + "Wi‑Fi мен Bluetooth ұшақ режимінде қосылып тұрады. Қаласаңыз, оларды өшіріп қоюыңызға болады." diff --git a/android/app/res/values-km/strings.xml b/android/app/res/values-km/strings.xml index bc5415c3466..b69eeb07c08 100644 --- a/android/app/res/values-km/strings.xml +++ b/android/app/res/values-km/strings.xml @@ -23,6 +23,7 @@ "ប៊្លូធូស" "មិន​ស្គាល់​ឧបករណ៍" "មិន​ស្គាល់" + "មិនបានផ្ដល់" "ពេល​ជិះ​យន្តហោះ" "អ្នក​មិន​អាច​ប្រើ​ប៊្លូ​ធូ​ស​ក្នុង​​​​​ពេល​ជិះ​យន្តហោះ​បាន​ទេ" @@ -31,18 +32,18 @@ "បោះ​បង់​" "បើក" "ការ​ផ្ទេរ​ឯកសារ" - "ទទួល​ឯកសារ​ចូល?" - "បោះបង់" - "ទទួល" + "ទទួលយក​ឯកសារ​ចូលឬ?" + "បដិសេធ" + "ទទួលយក" "យល់​ព្រម​" "អស់​ពេល​ទទួល​​ឯកសារ​ចូល​ពី \"%1$s\"" "ឯកសារចូល" "%1$s អាចផ្ញើឯកសារ​បានហើយ៖ %2$s" - "ការ​ចែក​រំលែក​ប៊្លូ​ធូ​ស៖ ទទួល %1$s" + "ចែក​រំលែកតាម​ប៊្លូ​ធូ​ស៖ កំពុងទទួល %1$s" "ការ​ចែក​រំលែក​ប៊្លូ​ធូ​ស៖ បាន​ទទួល​ %1$s" "ការ​ចែក​រំលែក​ប៊្លូ​ធូ​ស៖ មិន​បាន​ទទួល​ឯកសារ %1$s" - "ការ​ចែក​រំលែក​ប៊្លូ​ធូ​ស៖ ផ្ញើ %1$s" - "ការ​ចែក​រំលែក​ប៊្លូ​ធូ​ស៖ បាន​ផ្ញើ %1$s" + "ចែក​រំលែកតាម​ប៊្លូ​ធូ​ស៖ កំពុងបញ្ជូន %1$s" + "ចែក​រំលែកតាម​ប៊្លូ​ធូ​ស៖ បាន​បញ្ជូន %1$s" "​បញ្ចប់ 100​%" "ការ​ចែក​រំលែក​ប៊្លូ​ធូ​ស៖ មិន​បាន​ផ្ញើ​ឯកសារ %1$s" "ការ​ផ្ទេរ​ឯកសារ" @@ -107,12 +108,10 @@ "ការ​ផ្ទេរ​ចេញ" "មិន​មាន​ប្រវត្តិ​​ផ្ទេរ​។" "នឹង​សម្អាត​ធាតុ​ទាំងអស់​ពី​បញ្ជី។" - "ការ​ចែក​រំលែក​ប៊្លូ​ធូ​ស៖ បាន​ផ្ញើ​ឯកសារ" - "ការ​ចែក​រំលែក​ប៊្លូ​ធូ​ស៖ បាន​ទទួល​​​ឯកសារ" - - - - + "ចែក​រំលែកតាម​ប៊្លូ​ធូ​ស៖ បាន​បញ្ជូនឯកសារ" + "ចែក​រំលែក​តាមប៊្លូ​ធូ​ស៖ បាន​ទទួល​​​ឯកសារ" + "{count,plural, =1{មិនជោគជ័យ #។}other{មិនជោគជ័យ #។}}" + "{count,plural, =1{ជោគជ័យ #, %1$s}other{ជោគជ័យ #, %1$s}}" "សម្អាត​បញ្ជី" "បើក" "សម្អាត​ពី​បញ្ជី" @@ -130,4 +129,10 @@ "សំឡេងប៊្លូធូស" "ឯកសារ​ដែល​មាន​ទំហំ​ធំ​ជាង 4 GB មិន​អាចផ្ទេរ​បាន​ទេ" "ភ្ជាប់​ប៊្លូធូស" + "បើកប៊្លូធូស​នៅក្នុង​មុខងារពេលជិះយន្តហោះ" + "ប្រសិនបើអ្នក​បើកប៊្លូធូស នោះទូរសព្ទ​របស់អ្នកនឹង​ចាំថាត្រូវបើកវា នៅលើកក្រោយ​ដែលអ្នកស្ថិតក្នុង​មុខងារពេលជិះយន្តហោះ" + "ប៊្លូធូសបន្តបើក" + "ទូរសព្ទរបស់អ្នក​ចាំថាត្រូវបើកប៊្លូធូស​នៅក្នុង​មុខងារពេលជិះយន្តហោះ។ បិទប៊្លូធូស ប្រសិនបើអ្នក​មិនចង់បើកទេ។" + "Wi-Fi និងប៊្លូធូស​បន្តបើក" + "ទូរសព្ទរបស់អ្នក​ចាំថាត្រូវបើក Wi-Fi និងប៊្លូធូស​នៅក្នុង​មុខងារពេលជិះយន្តហោះ។ បិទ Wi-Fi និង​ប៊្លូធូស ប្រសិនបើអ្នក​មិនចង់បើកទេ។" diff --git a/android/app/res/values-kn/strings.xml b/android/app/res/values-kn/strings.xml index 79a7305bc71..878f9135708 100644 --- a/android/app/res/values-kn/strings.xml +++ b/android/app/res/values-kn/strings.xml @@ -23,6 +23,7 @@ "ಬ್ಲೂಟೂತ್‌" "ಅಪರಿಚಿತ ಸಾಧನ" "ಅಪರಿಚಿತ" + "ಒದಗಿಸಿಲ್ಲ" "ಏರ್‌ಪ್ಲೇನ್ ಮೋಡ್" "ಏರ್‌ಪ್ಲೇನ್‌ ಮೋಡ್‌ನಲ್ಲಿ ನೀವು ಬ್ಲೂಟೂತ್‌‌ ಬಳಸಲು ಸಾಧ್ಯವಿಲ್ಲ." @@ -109,10 +110,8 @@ "ಪಟ್ಟಿಯಿಂದ ಎಲ್ಲ ಐಟಂಗಳನ್ನು ತೆರವುಗೊಳಿಸಲಾಗುವುದು." "ಬ್ಲೂಟೂತ್‌ ಹಂಚಿಕೆ: ಕಳುಹಿಸಲಾಗಿರುವ ಫೈಲ್‌‌ಗಳು" "ಬ್ಲೂಟೂತ್‌ ಹಂಚಿಕೆ: ಫೈಲ್‌ಗಳನ್ನು ಸ್ವೀಕರಿಸಲಾಗಿದೆ" - - - - + "{count,plural, =1{# ವಿಫಲಗೊಂಡಿದೆ.}one{# ವಿಫಲಗೊಂಡಿದೆ.}other{# ವಿಫಲಗೊಂಡಿದೆ.}}" + "{count,plural, =1{# ಯಶಸ್ವಿಯಾಗಿದೆ, %1$s}one{# ಯಶಸ್ವಿಯಾಗಿದೆ, %1$s}other{# ಯಶಸ್ವಿಯಾಗಿದೆ, %1$s}}" "ಪಟ್ಟಿಯನ್ನು ತೆರವುಗೊಳಿಸಿ" "ತೆರೆಯಿರಿ" "ಪಟ್ಟಿಯಿಂದ ತೆರವುಗೊಳಿಸಿ" @@ -125,9 +124,15 @@ "ಅಪ್ಲಿಕೇಶನ್‌ ಐಕಾನ್‌" "ಬ್ಲೂಟೂತ್ ಸಂದೇಶ ಹಂಚಿಕೆ ಸೆಟ್ಟಿಂಗ್‌ಗಳು" "ಖಾತೆಯನ್ನು ಆಯ್ಕೆಮಾಡಲು ಸಾಧ್ಯವಿಲ್ಲ. 0 ಸ್ಲಾಟ್‌ಗಳು ಉಳಿದಿವೆ" - "ಬ್ಲೂಟೂತ್‌ ಆಡಿಯೊ ಸಂಪರ್ಕಗೊಂಡಿದೆ" - "ಬ್ಲೂಟೂತ್‌ ಆಡಿಯೊ ಸಂಪರ್ಕ ಕಡಿತಗೊಂಡಿದೆ" - "ಬ್ಲೂಟೂತ್‌ ಆಡಿಯೊ" + "ಬ್ಲೂಟೂತ್‌ ಆಡಿಯೋ ಸಂಪರ್ಕಗೊಂಡಿದೆ" + "ಬ್ಲೂಟೂತ್‌ ಆಡಿಯೋ ಸಂಪರ್ಕ ಕಡಿತಗೊಂಡಿದೆ" + "ಬ್ಲೂಟೂತ್‌ ಆಡಿಯೋ" "4GB ಗಿಂತ ದೊಡ್ಡದಾದ ಫೈಲ್‌ಗಳನ್ನು ವರ್ಗಾಯಿಸಲು ಸಾಧ್ಯವಿಲ್ಲ" "ಬ್ಲೂಟೂತ್‌ಗೆ ಕನೆಕ್ಟ್ ಮಾಡಿ" + "ಏರ್‌ಪ್ಲೇನ್ ಮೋಡ್‌ನಲ್ಲಿ ಬ್ಲೂಟೂತ್ ಆನ್ ಆಗಿದೆ" + "ನೀವು ಬ್ಲೂಟೂತ್ ಆನ್ ಆಗಿರಿಸಿದರೆ, ಮುಂದಿನ ಬಾರಿ ನೀವು ಏರ್‌ಪ್ಲೇನ್ ಮೋಡ್‌ನಲ್ಲಿರುವಾಗ ಅದನ್ನು ಆನ್ ಆಗಿರಿಸಿಕೊಳ್ಳುವುದನ್ನು ನಿಮ್ಮ ಫೋನ್ ನೆನಪಿಸಿಕೊಳ್ಳುತ್ತದೆ" + "ಬ್ಲೂಟೂತ್ ಆನ್ ಆಗಿರುತ್ತದೆ" + "ಏರ್‌ಪ್ಲೇನ್ ಮೋಡ್‌ನಲ್ಲಿ ಬ್ಲೂಟೂತ್ ಆನ್ ಆಗಿರಿಸಿಕೊಳ್ಳುವುದನ್ನು ನಿಮ್ಮ ಫೋನ್ ನೆನಪಿಸಿಕೊಳ್ಳುತ್ತದೆ. ಬ್ಲೂಟೂತ್ ಆನ್ ಆಗಿರಿಸಲು ನೀವು ಬಯಸದಿದ್ದರೆ ಅದನ್ನು ಆಫ್ ಮಾಡಿ." + "ವೈ-ಫೈ ಮತ್ತು ಬ್ಲೂಟೂತ್ ಆನ್ ಆಗಿರುತ್ತದೆ" + "ಏರ್‌ಪ್ಲೇನ್ ಮೋಡ್‌ನಲ್ಲಿ ವೈಫೈ ಮತ್ತು ಬ್ಲೂಟೂತ್ ಆನ್ ಆಗಿರಿಸಿಕೊಳ್ಳುವುದನ್ನು ನಿಮ್ಮ ಫೋನ್ ನೆನಪಿಸಿಕೊಳ್ಳುತ್ತದೆ. ವೈಫೈ ಮತ್ತು ಬ್ಲೂಟೂತ್ ಆನ್ ಆಗಿರಿಸಲು ನೀವು ಬಯಸದಿದ್ದರೆ ಅವುಗಳನ್ನು ಆಫ್ ಮಾಡಿ." diff --git a/android/app/res/values-ko/strings.xml b/android/app/res/values-ko/strings.xml index 2d3e8f7ec3b..2a6bcea99de 100644 --- a/android/app/res/values-ko/strings.xml +++ b/android/app/res/values-ko/strings.xml @@ -23,6 +23,7 @@ "블루투스" "알 수 없는 장치" "알 수 없음" + "제공되지 않음" "비행기 모드" "비행기 모드에서는 블루투스를 사용할 수 없습니다." @@ -31,12 +32,12 @@ "취소" "사용" "파일 전송" - "수신 파일을 수락하시겠습니까?" + "파일 수신을 수락하시겠습니까?" "거부" "수락" "확인" "\'%1$s\'님이 보내는 파일을 수락하는 동안 제한 시간을 초과했습니다." - "수신 파일" + "파일 수신" "%1$s에서 %2$s 파일을 전송할 준비가 되었습니다." "블루투스 공유: %1$s 받는 중" "블루투스 공유: %1$s 받음" @@ -109,10 +110,8 @@ "목록에서 모든 항목이 삭제됩니다." "블루투스 공유: 파일 보냄" "블루투스 공유: 파일 받음" - - - - + "{count,plural, =1{#개 실패}other{#개 실패}}" + "{count,plural, =1{#개 성공, %1$s}other{#개 성공, %1$s}}" "목록 지우기" "열기" "목록에서 지우기" @@ -130,4 +129,10 @@ "블루투스 오디오" "4GB보다 큰 파일은 전송할 수 없습니다" "블루투스에 연결" + "비행기 모드에서 블루투스 사용 설정" + "블루투스를 켜진 상태로 유지하면 다음에 비행기 모드를 사용할 때도 블루투스 연결이 유지됩니다." + "블루투스가 켜진 상태로 유지됨" + "휴대전화가 비행기 모드에서 블루투스를 켜진 상태로 유지합니다. 유지하지 않으려면 블루투스를 사용 중지하세요." + "Wi-Fi 및 블루투스 계속 사용" + "휴대전화가 비행기 모드에서 Wi-Fi 및 블루투스를 켜진 상태로 유지합니다. 유지하지 않으려면 Wi-Fi와 블루투스를 사용 중지하세요." diff --git a/android/app/res/values-ky/strings.xml b/android/app/res/values-ky/strings.xml index c59d1bf2330..4f1f7a1826f 100644 --- a/android/app/res/values-ky/strings.xml +++ b/android/app/res/values-ky/strings.xml @@ -23,6 +23,7 @@ "Bluetooth" "Белгисиз түзмөк" "Белгисиз" + "Берилген эмес" "Учак тартиби" "Учак тартибинде Bluetooth колдоно албайсыз." @@ -31,20 +32,20 @@ "Айнуу" "Жандыруу" "Файл өткөрүү" - "Келүүчү файл кабыл алынсынбы?" - "Баш тартуу" - "Кабыл алуу" + "Файлды кабыл аласызбы?" + "Жок" + "Ооба" "OK" - "\"%1$s\" жөнөткөн файлды алуу мөөнөтү өтүп кетти." - "Кирүүчү файл" + "\"%1$s\" жөнөткөн файлды алуу процесси узакка созулуп кетти." + "Файл келди" "%1$s түзмөгү %2$s файлын жөнөтүүгө даяр" - "Bluetooth бөлүшүү: %1$s алынууда" - "Bluetooth бөлүшүү: %1$s алынды" - "Bluetooth бөлүшүү: %1$s алынган жок" - "Bluetooth бөлүшүү: %1$s жөнөтүлүүдө" - "Bluetooth бөлүшүү: %1$s жөнөтүлдү" + "Bluetooth аркылуу алынууда: %1$s" + "Bluetooth аркылуу алынды: %1$s" + "Файл алынган жок: %1$s" + "Bluetooth аркылуу жөнөтүлдү: %1$s" + "Bluetooth аркылуу жөнөтүлдү: %1$s" "100% бүттү" - "Bluetooth бөлүшүү: %1$s жөнөтүлгөн жок" + "Файл жөнөтүлгөн жок: %1$s" "Файл өткөрүү" "Жөнөтүүчү: \"%1$s\"" "Файл: %1$s" @@ -107,12 +108,10 @@ "Чыгуучу өткөрүүлөр" "Эч нерсе алына элек" "Тизмек толугу менен тазаланат." - "Bluetooth бөлүшүү: Файлдар жөнөтүлдү" - "Bluetooth бөлүшүү: Алынган файлдар" - - - - + "Bluetooth аркылуу жөнөтүлдү" + "Bluetooth аркылуу алынган файлдар" + "{count,plural, =1{# жөнөтүлгөн жок.}other{# жөнөтүлгөн жок.}}" + "{count,plural, =1{# жөнөтүлдү, %1$s}other{# жөнөтүлдү, %1$s}}" "Тизмекти тазалоо" "Ачуу" "Тизмектен алып салуу" @@ -120,14 +119,20 @@ "Эмне ойноп жатат?" "Сактоо" "Жокко чыгаруу" - "Bluetooth аркылуу бөлүшө турган каттоо эсептерин тандаңыз. Туташкан сайын аккаунттарына кирүү мүмкүнчүлүгүн ырастап турушуңуз керек." + "Bluetooth аркылуу бөлүшө турган аккаунттарды тандаңыз. Туташкан сайын аккаунттарга кирүүгө уруксат берип турушуңуз керек." "Калган көзөнөктөр:" "Колдонмонун сүрөтчөсү" - "Bluetooth билдирүү бөлүшүү жөндөөлөрү" + "Bluetooth билдирүү бөлүшүү параметрлери" "Аккаунт тандалбай жатат: 0 орун калды" "Bluetooth аудио туташты" "Bluetooth аудио ажыратылды" "Bluetooth аудио" "4Гб чоң файлдарды өткөрүү мүмкүн эмес" "Bluetooth\'га туташуу" + "Учак режиминде Bluetooth күйүк" + "Эгер Bluetooth күйүк бойдон калса, кийинки жолу учак режимине өткөнүңүздө телефонуңуз аны эстеп калат" + "Bluetooth күйүк бойдон калат" + "Телефонуңуз учак режиминде Bluetooth\'га туташкан бойдон калат. Кааласаңыз, Bluetooth\'ду өчүрүп койсоңуз болот." + "Wi-Fi менен Bluetooth күйүк бойдон калат" + "Телефонуңуз учак режиминде Wi‑Fi\'га жана Bluetooth\'га туташкан бойдон калат. Кааласаңыз, Wi-Fi менен Bluetooth\'ду өчүрүп койсоңуз болот." diff --git a/android/app/res/values-lo/strings.xml b/android/app/res/values-lo/strings.xml index 0bea8630d7a..9c60428aa9e 100644 --- a/android/app/res/values-lo/strings.xml +++ b/android/app/res/values-lo/strings.xml @@ -23,6 +23,7 @@ "Bluetooth" "ອຸປະກອນທີ່ບໍ່ຮູ້ຈັກ" "ບໍ່ຮູ້ຈັກ" + "ບໍ່ໄດ້ລະບຸ" "ໂໝດຢູ່ເທິງຍົນ" "ທ່ານບໍ່ສາມາດໃຊ້ Bluetooth ໃນໂໝດຢູ່ເທິງຍົນໄດ້." @@ -31,7 +32,7 @@ "ຍົກເລີກ" "ເປີດ" "ການໂອນໄຟລ໌" - "ຮັບເອົາ​ໄຟລ໌​ທີ່​ເຂົາ​ມາ​ບໍ?" + "ຮັບເອົາໄຟລ໌ທີ່ເຂົ້າມາບໍ?" "ປະຕິເສດ" "ຮັບເອົາ" "ຕົກລົງ" @@ -107,12 +108,10 @@ "ການໂອນອອກ" "ປະຫວັດການໂອນຫວ່າງເປົ່າ." "ລາຍການທັງໝົດຈະຖືກລຶບອອກຈາກລາຍການດັ່ງກ່າວ." - "ແບ່ງປັນໃນ Bluetooth: ໄຟລ໌ສົ່ງແລ້ວ" - "ແບ່ງປັນໃນ Bluetooth: ໄຟລ໌ໄດ້ຮັບແລ້ວ" - - - - + "ແບ່ງປັນໃນ Bluetooth: ສົ່ງໄຟລ໌ແລ້ວ" + "ແບ່ງປັນໃນ Bluetooth: ໄດ້ຮັບໄຟລ໌ແລ້ວ" + "{count,plural, =1{# ບໍ່ສຳເລັດ.}other{# ບໍ່ສຳເລັດ.}}" + "{count,plural, =1{# ສຳເລັດ, %1$s}other{# ສຳເລັດ, %1$s}}" "ລຶບລາຍການ" "ເປີດ" "ລຶບອອກຈາກລາຍການ" @@ -130,4 +129,10 @@ "ສຽງ Bluetooth" "ບໍ່ສາມາດໂອນຍ້າຍໄຟລ໌ທີ່ໃຫຍກວ່າ 4GB ໄດ້" "ເຊື່ອມຕໍ່ກັບ Bluetooth" + "ເປີດ Bluetooth ໃນໂໝດຢູ່ໃນຍົນ" + "ຫາກທ່ານເປີດ Bluetooth ປະໄວ້, ໂທລະສັບຂອງທ່ານຈະຈື່ວ່າຕ້ອງເປີດ Wi‑Fi ໃນເທື່ອຕໍ່ໄປທີ່ທ່ານຢູ່ໃນໂໝດຢູ່ໃນຍົນ" + "Bluetooth ເປີດຢູ່" + "ໂທລະສັບຂອງທ່ານຈື່ວ່າຈະຕ້ອງເປີດ Bluetooth ປະໄວ້ໃນໂໝດຢູ່ໃນຍົນ. ປິດ Bluetooth ຫາກທ່ານບໍ່ຕ້ອງການໃຫ້ເປີດປະໄວ້." + "Wi-Fi ແລະ Bluetooth ຈະເປີດປະໄວ້" + "ໂທລະສັບຂອງທ່ານຈື່ວ່າຈະຕ້ອງເປີດ Wi-Fi ແລະ Bluetooth ປະໄວ້ໃນໂໝດຢູ່ໃນຍົນ. ປິດ Wi-Fi ແລະ Bluetooth ຫາກທ່ານບໍ່ຕ້ອງການໃຫ້ເປີດປະໄວ້." diff --git a/android/app/res/values-lt/strings.xml b/android/app/res/values-lt/strings.xml index 02ff6e74607..de0c13f5930 100644 --- a/android/app/res/values-lt/strings.xml +++ b/android/app/res/values-lt/strings.xml @@ -23,6 +23,7 @@ "Bluetooth" "Nežinomas įrenginys" "Nežinoma" + "Nepateikta" "Lėktuvo režimas" "Negalima naudoti „Bluetooth“ lėktuvo režimu." @@ -109,10 +110,8 @@ "Visi sąrašo elementai bus išvalyti." "„Bluetooth“ bendrinimas: išsiųsti failai" "„Bluetooth“ bendrinimas: gauti failai" - - - - + "{count,plural, =1{nesėkmingų: #.}one{nesėkmingų: #.}few{nesėkmingų: #.}many{nesėkmingų: #.}other{nesėkmingų: #.}}" + "{count,plural, =1{Sėkmingų: #, %1$s}one{Sėkmingų: #, %1$s}few{Sėkmingų: #, %1$s}many{Sėkmingų: #, %1$s}other{Sėkmingų: #, %1$s}}" "Išvalyti sąrašą" "Atidaryti" "Išvalyti iš sąrašo" @@ -130,4 +129,10 @@ "„Bluetooth“ garsas" "Negalima perkelti didesnių nei 4 GB failų" "Prisijungti prie „Bluetooth“" + "„Bluetooth“ ryšys įjungtas lėktuvo režimu" + "Jei paliksite „Bluetooth“ ryšį įjungtą, telefonas, prisimins palikti jį įjungtą, kai kitą kartą įjungsite lėktuvo režimą" + "„Bluetooth“ liks įjungtas" + "Telefonas prisimena, kad naudojant lėktuvo režimą reikia palikti įjungtą „Bluetooth“ ryšį. Išjunkite „Bluetooth“, jei nenorite, kad jis liktų įjungtas." + "„Wi‑Fi“ ir „Bluetooth“ ryšys lieka įjungtas" + "Telefonas prisimena, kad lėktuvo režimu reikia palikti įjungtą „Wi‑Fi“ ir „Bluetooth“ ryšį. Išjunkite „Wi-Fi“ ir „Bluetooth“, jei nenorite, kad jie liktų įjungti." diff --git a/android/app/res/values-lv/strings.xml b/android/app/res/values-lv/strings.xml index e1d686d533e..eee75d98490 100644 --- a/android/app/res/values-lv/strings.xml +++ b/android/app/res/values-lv/strings.xml @@ -23,6 +23,7 @@ "Bluetooth" "Nezināma ierīce" "Nezināms" + "Dati nav norādīti" "Lidojuma režīms" "Pakalpojumu Bluetooth nevar izmantot lidmašīnas režīmā." @@ -109,10 +110,8 @@ "No saraksta tiks notīrīti visi vienumi." "Bluetooth Share: nosūtītie faili" "Bluetooth Share: saņemtie faili" - - - - + "{count,plural, =1{neizdevās: #.}zero{neizdevās: #.}one{neizdevās: #.}other{neizdevās: #.}}" + "{count,plural, =1{Izdevās: #; %1$s}zero{Izdevās: #; %1$s}one{Izdevās: #; %1$s}other{Izdevās: #; %1$s}}" "Notīrīt sarakstu" "Atvērt" "Notīrīt no saraksta" @@ -130,4 +129,10 @@ "Bluetooth audio" "Nevar pārsūtīt failus, kas lielāki par 4 GB." "Izveidot savienojumu ar Bluetooth" + "Tehnoloģija Bluetooth lidojuma režīmā paliek ieslēgta" + "Ja Bluetooth savienojums paliks ieslēgts, tālrunī tas paliks ieslēgts arī nākamreiz, kad ieslēgsiet lidojuma režīmu." + "Bluetooth savienojums joprojām ir ieslēgts" + "Lidojuma režīmā tālrunī joprojām būs ieslēgts Bluetooth savienojums. Izslēdziet Bluetooth savienojumu, ja nevēlaties, lai tas paliktu ieslēgts." + "Wi-Fi savienojums un tehnoloģija Bluetooth paliek ieslēgta" + "Lidojuma režīmā tālrunī joprojām būs ieslēgti Wi-Fi un Bluetooth savienojumi. Izslēdziet Wi-Fi un Bluetooth savienojumus, ja nevēlaties, lai tie paliktu ieslēgti." diff --git a/android/app/res/values-mk/strings.xml b/android/app/res/values-mk/strings.xml index 296db6c4d7c..d7f99077e44 100644 --- a/android/app/res/values-mk/strings.xml +++ b/android/app/res/values-mk/strings.xml @@ -23,6 +23,7 @@ "Bluetooth" "Непознат уред" "Непознат" + "Не е обезбедено" "Авионски режим" "Не можете да користите Bluetooth во режим на авион." @@ -38,13 +39,13 @@ "Времето истече додека се прифаќаше дојдовната датотека од „%1$s“." "Дојдовна датотека" "%1$s е подготвен да испрати датотека: %2$s" - "Сподели преку Bluetooth: Се прима %1$s" - "Сподели преку Bluetooth: Примена %1$s" - "Сподели преку Bluetooth: Датотеката %1$s не е примена." - "Сподели преку Bluetooth: Се испраќа %1$s" - "Сподели преку Bluetooth: Испратена %1$s" + "Bluetooth: се прима %1$s" + "Bluetooth: %1$s е примена" + "Bluetooth: датотеката %1$s не е примена" + "Bluetooth: се испраќа %1$s" + "Bluetooth: %1$s е испратена" "100% завршено" - "Сподели преку Bluetooth: Датотеката %1$s не е испратена" + "Bluetooth: датотеката %1$s не е испратена" "Пренос на датотеки" "Од: „%1$s“" "Датотека: %1$s" @@ -52,7 +53,7 @@ "Примање датотеки..." "Запри" - "Сокриј" + "Скриј" "Од" "Име на датотека" "Големина" @@ -107,12 +108,10 @@ "Излезни преноси" "Историјата на пренос е празна." "Сите ставки ќе бидат избришани од списокот." - "Сподели преку Bluetooth: Пратени датотеки" - "Сподели преку Bluetooth: Примени датотеки" - - - - + "Bluetooth: испратени датотеки" + "Bluetooth: примени датотеки" + "{count,plural, =1{# неуспешна.}one{# неуспешна.}other{# неуспешни.}}" + "{count,plural, =1{# успешна, %1$s}one{# успешна, %1$s}other{# успешни, %1$s}}" "Исчисти список" "Отвори" "Исчисти од списокот" @@ -130,4 +129,10 @@ "Аудио преку Bluetooth" "Не може да се пренесуваат датотеки поголеми од 4 GB" "Поврзи се со Bluetooth" + "Вклучен Bluetooth во авионски режим" + "Ако го оставите Bluetooth вклучен, телефонот ќе запомни да го остави вклучен до следниот пат кога ќе бидете во авионски режим" + "Bluetooth останува вклучен" + "Телефонот помни да го задржи Bluetooth вклучен во авионски режим. Исклучете го Bluetooth ако не сакате да остане вклучен." + "Wi-Fi и Bluetooth остануваат вклучени" + "Телефонот помни да ги задржи Wi‑Fi и Bluetooth вклучени во авионски режим. Исклучете ги Wi-Fi и Bluetooth ако не сакате да бидат вклучени." diff --git a/android/app/res/values-ml/strings.xml b/android/app/res/values-ml/strings.xml index 72776d60f75..e0f76f43f2c 100644 --- a/android/app/res/values-ml/strings.xml +++ b/android/app/res/values-ml/strings.xml @@ -23,6 +23,7 @@ "Bluetooth" "അജ്ഞാത ഉപകരണം" "അറിയില്ല" + "നൽകിയിട്ടില്ല" "ഫ്ലൈറ്റ് മോഡ്" "നിങ്ങൾക്ക് വിമാന മോഡിൽ ബ്ലൂടൂത്ത് ഉപയോഗിക്കാനാകില്ല." @@ -38,11 +39,11 @@ "\"%1$s\" -ൽ നിന്നും ഇൻകമിംഗ് ഫയൽ സ്വീകരിക്കുമ്പോൾ സമയപരിധി കഴിഞ്ഞിരുന്നു" "ഇൻകമിംഗ് ഫയൽ" "%1$s, ഫയൽ അയയ്‌ക്കാൻ തയ്യാറാണ്: %2$s" - "ബ്ലൂടൂത്ത് പങ്കിടൽ: %1$s എന്ന ഫയൽ ലഭിക്കുന്നു" + "Bluetooth പങ്കിടൽ: %1$s എന്നത് സ്വീകരിക്കുന്നു" "ബ്ലൂടൂത്ത് പങ്കിടൽ: %1$s ലഭിച്ചു" "ബ്ലൂടൂത്ത് പങ്കിടൽ: %1$s എന്ന ഫയൽ ലഭിച്ചില്ല." - "ബ്ലൂടൂത്ത് പങ്കിടൽ: %1$s എന്ന ഫയൽ അയയ്‌ക്കുന്നു" - "ബ്ലൂടൂത്ത് പങ്കിടൽ: %1$s എന്ന ഫയൽ അയച്ചു" + "Bluetooth പങ്കിടൽ: %1$s എന്ന ഫയൽ അയയ്‌ക്കുന്നു" + "Bluetooth പങ്കിടൽ: %1$s എന്ന ഫയൽ അയച്ചു" "100% പൂർത്തിയായി" "ബ്ലൂടൂത്ത് പങ്കിടൽ: %1$s എന്ന ഫയൽ അയച്ചില്ല" "ഫയൽ കൈമാറൽ" @@ -107,12 +108,10 @@ "ഔട്ട്‌ബൗണ്ട് കൈമാറലുകൾ" "കൈമാറൽ ചരിത്രം ശൂന്യമാണ്." "ലിസ്റ്റിൽ നിന്നും എല്ലാ ഇനങ്ങളും മായ്‌ക്കും." - "ബ്ലൂടൂത്ത് പങ്കിടൽ: അയച്ച ഫയലുകൾ" - "ബ്ലൂടൂത്ത് പങ്കിടൽ: ലഭിച്ച ഫയലുകൾ" - - - - + "Bluetooth പങ്കിടൽ: അയച്ച ഫയലുകൾ" + "Bluetooth പങ്കിടൽ: ലഭിച്ച ഫയലുകൾ" + "{count,plural, =1{# എണ്ണം പരാജയപ്പെട്ടു.}other{# എണ്ണം പരാജയപ്പെട്ടു.}}" + "{count,plural, =1{# എണ്ണം വിജയകരം, %1$s}other{# എണ്ണം വിജയകരം, %1$s}}" "ലിസ്റ്റ് മായ്‌ക്കുക" "തുറക്കുക" "ലിസ്റ്റിൽ നിന്നും മായ്‌ക്കുക" @@ -130,4 +129,10 @@ "Bluetooth ഓഡിയോ" "4GB-യിൽ കൂടുതലുള്ള ഫയലുകൾ കൈമാറാനാവില്ല" "Bluetooth-ലേക്ക് കണക്‌റ്റ് ചെയ്യുക" + "ഫ്ലൈറ്റ് മോഡിൽ Bluetooth ഓണാണ്" + "Bluetooth ഓണാക്കി വച്ചാൽ, അടുത്ത തവണ നിങ്ങൾ ഫ്ലൈറ്റ് മോഡിൽ ആയിരിക്കുമ്പോൾ നിങ്ങളുടെ ഫോൺ അത് ഓണാക്കി വയ്ക്കാൻ ഓർക്കും" + "Bluetooth ഓണാക്കിയ നിലയിൽ തുടരും" + "ഫ്ലൈറ്റ് മോഡിലായിരിക്കുമ്പോൾ Bluetooth ഓണാക്കി വയ്ക്കാൻ നിങ്ങളുടെ ഫോൺ ഓർമ്മിക്കുന്നു. Bluetooth ഓണാക്കി വയ്ക്കാൻ താൽപ്പര്യമില്ലെങ്കിൽ അത് ഓഫാക്കുക." + "വൈഫൈ, Bluetooth എന്നിവ ഓണായ നിലയിൽ തുടരും" + "ഫ്ലൈറ്റ് മോഡിലായിരിക്കുമ്പോൾ വൈഫൈ, Bluetooth എന്നിവ ഓണാക്കി വയ്ക്കാൻ നിങ്ങളുടെ ഫോൺ ഓർമ്മിക്കുന്നു. വൈഫൈ, Bluetooth എന്നിവ ഓണാക്കി വയ്‌ക്കാൻ താൽപ്പര്യമില്ലെങ്കിൽ അവ ഓഫാക്കുക." diff --git a/android/app/res/values-mn/strings.xml b/android/app/res/values-mn/strings.xml index 039c7966599..b39de67f03e 100644 --- a/android/app/res/values-mn/strings.xml +++ b/android/app/res/values-mn/strings.xml @@ -23,6 +23,7 @@ "Bluetooth" "Үл мэдэгдэх төхөөрөмж" "Тодорхойгүй" + "Олгоогүй" "Нислэгийн горим" "Та Нислэгийн горимд Bluetooth ашиглах боломжгүй." @@ -109,10 +110,8 @@ "Жагсаалтаас бүгдийг нь арилгах болно." "Bluetooth хуваалцах: Илгээсэн файлууд" "Bluetooth хуваалцах: Хүлээн авсан файлууд" - - - - + "{count,plural, =1{# амжилтгүй.}other{# амжилтгүй.}}" + "{count,plural, =1{# амжилттай, %1$s}other{# амжилттай, %1$s}}" "Жагсаалтыг арилгах" "Нээх" "Жагсаалтаас арилгах" @@ -130,4 +129,10 @@ "Bluetooth Аудио" "4ГБ-с дээш хэмжээтэй файлыг шилжүүлэх боломжгүй" "Bluetooth-тэй холбогдох" + "Нислэгийн горимд Bluetooth асаалттай" + "Хэрэв та Bluetooth-г асаалттай байлгавал таныг дараагийн удаа нислэгийн горимд байх үед утас тань үүнийг асаалттай байлгахыг санана" + "Bluetooth асаалттай хэвээр байна" + "Таны утас Bluetooth-г нислэгийн горимд асаалттай байлгахыг санана. Хэрэв та асаалттай байлгахыг хүсэхгүй байгаа бол Bluetooth-г унтрааж болно." + "Wi-Fi болон Bluetooth асаалттай хэвээр байна" + "Таны утас Wi-Fi болон Bluetooth-г нислэгийн горимд асаалттай байлгахыг санана. Хэрэв та асаалттай байлгахыг хүсэхгүй байгаа бол Wi-Fi болон Bluetooth-г унтрааж болно." diff --git a/android/app/res/values-mr/strings.xml b/android/app/res/values-mr/strings.xml index 9097a639a80..f45a9a55dd6 100644 --- a/android/app/res/values-mr/strings.xml +++ b/android/app/res/values-mr/strings.xml @@ -23,6 +23,7 @@ "ब्लूटूथ" "अज्ञात डिव्हाइस" "अज्ञात" + "पुरवला नाही" "विमान मोड" "तुम्ही विमान मोड मध्ये ब्लूटूथ वापरू शकत नाही." @@ -37,7 +38,7 @@ "ठीक" "\"%1$s\" कडील फाइल स्‍वीकार करताना वेळ संपली." "येणारी फाइल" - "%1$sफाइल पाठवण्यास तयार आहे: %2$s" + "%1$s फाइल पाठवण्यास तयार आहे: %2$s" "ब्लूटूथ शेअर: %1$s मिळवत आहे" "ब्लूटूथ शेअर: %1$s प्राप्त केली" "ब्लूटूथ शेअर: %1$s फाइल प्राप्त केली नाही" @@ -90,7 +91,7 @@ "फाइल स्थानांतरणाचा अद्याप सुरू झाला नाही." "फाइल स्थानांतर सुरू आहे." "फाइल स्थानांतरण यशस्वीरित्या पूर्ण झाले." - "आशय समर्थित नाही." + "आशयाला सपोर्ट नाही." "लक्ष्‍य डिव्‍हाइसद्वारे स्‍थानांतरण निषिद्ध केले." "वापरकर्त्याने स्‍थानांतरण रद्द केले." "संचयन समस्‍या." @@ -109,10 +110,8 @@ "सूचीमधून सर्व आयटम साफ केले जातील." "ब्लूटूथ शेअर: पाठवलेल्या फाइल" "ब्लूटूथ शेअर: मिळवलेल्‍या फाइल" - - - - + "{count,plural, =1{# यशस्वी झाले नाही.}other{# यशस्वी झाले नाही.}}" + "{count,plural, =1{# यशस्वी झाले, %1$s}other{# यशस्वी झाले, %1$s}}" "सूची साफ करा" "उघडा" "सूचीमधून साफ करा" @@ -130,4 +129,10 @@ "ब्लूटूथ ऑडिओ" "4 GB हून मोठ्या फाइल ट्रान्सफर करता येणार नाहीत" "ब्लूटूथशी कनेक्ट करा" + "विमान मोडमध्ये ब्लूटूथ सुरू आहे" + "तुम्ही ब्लूटूथ सुरू ठेवल्यास, पुढील वेळी विमान मोडमध्ये असाल, तेव्हा तुमचा फोन ते सुरू ठेवण्याचे लक्षात ठेवेल" + "ब्लूटूथ सुरू राहते" + "तुमचा फोन विमान मोडमध्ये ब्लूटूथ सुरू ठेवण्याचे लक्षात ठेवतो. तुम्हाला ब्लूटूथ सुरू ठेवायचे नसल्यास ते बंद करा." + "वाय-फाय आणि ब्लूटूथ सुरू राहते" + "तुमचा फोन विमान मोडमध्ये वाय-फाय आणि ब्लूटूथ सुरू ठेवण्याचे लक्षात ठेवतो. तुम्हाला वाय-फाय आणि ब्लूटूथ सुरू ठेवायचे नसल्यास ते बंद करा." diff --git a/android/app/res/values-ms/strings.xml b/android/app/res/values-ms/strings.xml index 92cbeaa5745..53064c86969 100644 --- a/android/app/res/values-ms/strings.xml +++ b/android/app/res/values-ms/strings.xml @@ -23,6 +23,7 @@ "Bluetooth" "Peranti tidak diketahui" "Tidak diketahui" + "Tidak Diberikan" "Mod pesawat" "Anda tidak boleh menggunakan Bluetooth dalam mod Pesawat." @@ -42,7 +43,7 @@ "Perkongsian Bluetooth: Diterima %1$s" "Perkongsian Bluetooth: Fail %1$s tidak diterima" "Perkongsian Bluetooth: Menghantar %1$s" - "Perkongsian Bluetooth: Dihantar %1$s" + "Perkongsian Bluetooth: %1$s dihantar" "Selesai 100%" "Perkongsian Bluetooth: Fail %1$s tidak dihantar" "Pemindahan fail" @@ -107,12 +108,10 @@ "Pemindahan keluar" "Sejarah pemindahan kosong." "Semua item akan dipadam bersih daripada senarai." - "Perkongsian Bluetooth: Fail diterima" + "Perkongsian Bluetooth: Fail dihantar" "Perkongsian Bluetooth: Fail diterima" - - - - + "{count,plural, =1{# tidak berjaya.}other{# tidak berjaya.}}" + "{count,plural, =1{# berjaya, %1$s}other{# berjaya, %1$s}}" "Padam bersih senarai" "Buka" "Padam bersih daripada senarai" @@ -130,4 +129,10 @@ "Audio Bluetooth" "Fail lebih besar daripada 4GB tidak boleh dipindahkan" "Sambung ke Bluetooth" + "Bluetooth dihidupkan dalam mod pesawat" + "Jika anda terus menghidupkan Bluetooth, telefon anda akan ingat untuk membiarkan Bluetooth hidup pada kali seterusnya telefon anda berada dalam mod pesawat" + "Bluetooth kekal dihidupkan" + "Telefon anda diingatkan untuk terus menghidupkan Bluetooth dalam mod pesawat. Matikan Bluetooth jika anda tidak mahu Bluetooth sentiasa hidup." + "Wi-Fi dan Bluetooth kekal dihidupkan" + "Telefon anda diingatkan untuk terus menghidupkan Wi-Fi dan Bluetooth dalam mod pesawat. Matikan Wi-Fi dan Bluetooth jika anda tidak mahu Wi-Fi dan Bluetooth sentiasa hidup." diff --git a/android/app/res/values-my/strings.xml b/android/app/res/values-my/strings.xml index 161d6045ba5..fb9a38360b1 100644 --- a/android/app/res/values-my/strings.xml +++ b/android/app/res/values-my/strings.xml @@ -23,6 +23,7 @@ "ဘလူးတုသ်" "မသိသော စက်" "မသိ" + "ပေးမထားပါ" "လေယာဉ်ပျံမုဒ်" "လေယာဥ်ပျံပေါ်သုံးစနစ်တွင် ဘလူးတုသ်အသုံးပြုမရပါ" @@ -31,17 +32,17 @@ "မလုပ်တော့" "ဖွင့်မည်" "ဖိုင်လွှဲပြောင်းခြင်း" - "ဝင်လာသည့် ဖိုင်ကို လက်ခံမလား?" + "အဝင်ဖိုင်ကို လက်ခံမလား။" "လက်မခံပါ" "လက်ခံရန်" "OK" "\"%1$s\"မှ အဝင်ဖိုင်ကို လက်ခံနေစဥ် အချိန်ကုန်ဆုံးသွားပါပြီ" "အဝင် ဖိုင်" "%1$s သည် ဤဖိုင်ကို ပို့ရန်အသင့်ဖြစ်ပါပြီ- %2$s" - "ဘလူးတုသ် ဝေမျှမှု - %1$s လက်ခံနေသည်" + "ဘလူးတုသ် ဝေမျှမှု - လက်ခံနေသည့်ဖိုင် %1$s" "ဘလူးတုသ် ဝေမျှမှု - ရရှိပြီး%1$s" "ဘလူးတုသ် ဝေမျှမှု - ဖိုင် %1$s မရရှိပါ" - "ဘလူးတုသ် ဝေမျှမှု - %1$s ပို့နေသည်" + "ဘလူးတုသ် ဝေမျှမှု - ပို့နေသည့်ဖိုင် %1$s" "ဘလူးတုသ် ဝေမျှမှု - %1$s ပို့ပြီး" "၁၀၀%ပြီးပါပြီ" "ဘလူးတုသ် ဝေမျှမှု - ဖိုင်%1$s မပို့ပါ" @@ -109,10 +110,8 @@ "အရာများအားလုံး စာရင်းမှ ရှင်းလင်းပစ်လိမ့်မည်" "ဘလူးတုသ် ဝေမျှမှု - ဖိုင်ပို့ပြီး" "ဘလူးတုသ် ဝေမျှမှု - ရရှိပြီးဖိုင်များ" - - - - + "{count,plural, =1{# ခု မအောင်မြင်ပါ။}other{# ခု မအောင်မြင်ပါ။}}" + "{count,plural, =1{# ခု အောင်မြင်သည်။ %1$s}other{# ခု အောင်မြင်သည်။ %1$s}}" "စာရင်းကို ဖယ်ရှားရန်" "ဖွင့်ရန်" "စာရင်းမှ ရှင်းပစ်မည်" @@ -130,4 +129,10 @@ "ဘလူးတုသ် အသံ" "4GB ထက်ပိုကြီးသည့် ဖိုင်များကို လွှဲပြောင်းမရနိုင်ပါ" "ဘလူးတုသ်သို့ ချိတ်ဆက်ရန်" + "လေယာဉ်ပျံမုဒ်တွင် ဘလူးတုသ် ပွင့်နေသည်" + "ဘလူးတုသ် ဆက်ဖွင့်ထားပါက နောက်တစ်ကြိမ်လေယာဉ်ပျံမုဒ် သုံးချိန်တွင် ၎င်းဆက်ဖွင့်ရန် သင့်ဖုန်းက မှတ်ထားမည်။" + "ဘလူးတုသ် ဆက်ပွင့်နေသည်" + "လေယာဉ်ပျံမုဒ်သုံးစဉ် ဘလူးတုသ် ဆက်ဖွင့်ထားရန် သင့်ဖုန်းက မှတ်မိသည်။ ဘလူးတုသ် ဆက်ဖွင့်မထားလိုပါက ပိတ်နိုင်သည်။" + "Wi-Fi နှင့် ဘလူးတုသ် ဆက်ဖွင့်ထားသည်" + "လေယာဉ်ပျံမုဒ်သုံးစဉ် Wi-Fi နှင့် ဘလူးတုသ် ဆက်ဖွင့်ထားရန် သင့်ဖုန်းက မှတ်မိသည်။ Wi-Fi နှင့် ဘလူးတုသ် ဆက်ဖွင့်မထားလိုပါက ပိတ်နိုင်သည်။" diff --git a/android/app/res/values-nb/strings.xml b/android/app/res/values-nb/strings.xml index 1969699bb83..3ff0bbc8fad 100644 --- a/android/app/res/values-nb/strings.xml +++ b/android/app/res/values-nb/strings.xml @@ -23,6 +23,7 @@ "Bluetooth" "Ukjent enhet" "Ukjent" + "Ikke oppgitt" "Flymodus" "Du kan ikke bruke Bluetooth i flymodus." @@ -109,10 +110,8 @@ "Alle elementer fjernes fra listen." "Bluetooth-deling: Filer sendt" "Bluetooth-deling: Filer mottatt" - - - - + "{count,plural, =1{# mislykket.}other{# mislykket.}}" + "{count,plural, =1{# vellykket, %1$s}other{# vellykket, %1$s}}" "Tøm listen" "Åpne" "Fjern fra listen" @@ -130,4 +129,10 @@ "Bluetooth-lyd" "Filer som er større enn 4 GB, kan ikke overføres" "Koble til Bluetooth" + "Bluetooth er på i flymodus" + "Hvis du lar Bluetooth være på, husker telefonen dette til den neste gangen du bruker flymodus" + "Bluetooth blir værende på" + "Telefonen husker at Bluetooth skal være på i flymodus. Slå av Bluetooth hvis du ikke vil at det skal være på." + "Wifi og Bluetooth holdes påslått" + "Telefonen husker at wifi og Bluetooth skal være på i flymodus. Slå av wifi og Bluetooth hvis du ikke vil at de skal være på." diff --git a/android/app/res/values-ne/strings.xml b/android/app/res/values-ne/strings.xml index c0e723ddfb2..eccb49f4077 100644 --- a/android/app/res/values-ne/strings.xml +++ b/android/app/res/values-ne/strings.xml @@ -23,6 +23,7 @@ "ब्लुटुथ" "अज्ञात उपकरण" "अज्ञात" + "प्रदान गरिएको छैन" "हवाइजहाज मोड" "हवाइजहाज मोडमा तपाईँले ब्लुटुथ प्रयोग गर्न पाउनु हुन्न।" @@ -38,13 +39,13 @@ "\"%1$s\" बाट आगमन फाइल स्वीकार्दा समय सकिएको थियो" "आगमन फाइल" "%1$s निम्न फाइल पठाउन तयार हुनुहुन्छ: %2$s" - "ब्लुटुथ साझेदारी:%1$s प्राप्त गर्दै" - "ब्लुटुथ साझेदारी: %1$s प्राप्त भयो" - "ब्लुटुथ साझेदारी: फाइल: %1$s प्राप्त भएन" - "ब्लुटुथ साझेदारी: %1$s पठाउँदै" - "ब्लुटुथ साझेदारी: %1$s पठाइयो" + "ब्लुटुथ सेयर:%1$s प्राप्त गर्दै" + "ब्लुटुथ सेयर: %1$s प्राप्त भयो" + "ब्लुटुथ सेयर: फाइल: %1$s प्राप्त भएन" + "ब्लुटुथ सेयर: %1$s पठाउँदै" + "ब्लुटुथ सेयर: %1$s पठाइयो" "१००% पुरा" - "ब्लुटुथ साझेदारी: फाइल%1$s पठाइएन" + "ब्लुटुथ सेयर: फाइल%1$s पठाइएन" "फाइल स्थानान्तरण" "बाट: \"%1$s\"" "फाइल: %1$s" @@ -107,12 +108,10 @@ "आउटबाउन्ड स्थानान्तरण" "अहिलेसम्म कुनै वस्तु ट्रान्सफर गरिएको छैन।" "सूचीबाट सम्पूर्ण वस्तुहरू मेटाइने छन्।" - "ब्लुटुथ साझेदारी: पठाइएका फाइलहरू" - "ब्लुटुथ साझेदारी: प्राप्त फाइलहरू" - - - - + "ब्लुटुथ सेयर: पठाइएका फाइलहरू" + "ब्लुटुथ सेयर: प्राप्त फाइलहरू" + "{count,plural, =1{# वटा फाइल सेयर गर्न सकिएन।}other{# वटा फाइल सेयर गर्न सकिएन।}}" + "{count,plural, =1{# वटा फाइल सेयर गरियो, %1$s}other{# वटा फाइल सेयर गरियो, %1$s}}" "सूची हटाउनुहोस्" "खोल्नुहोस्" "सूचीबाट हटाउनुहोस्" @@ -130,4 +129,10 @@ "ब्लुटुथको अडियो" "४ जि.बि. भन्दा ठूला फाइलहरूलाई स्थानान्तरण गर्न सकिँदैन" "ब्लुटुथमा कनेक्ट गर्नुहोस्" + "हवाइजहाज मोडमा ब्लुटुथ अन राखियोस्" + "तपाईंले ब्लुटुथ अन राखिराख्नुभयो भने तपाईंले आफ्नो फोन अर्को पटक हवाइजहाज मोडमा लैजाँदा तपाईंको फोनले ब्लुटुथ अन राख्नु पर्ने कुरा याद गर्छ" + "ब्लुटुथ अन रहन्छ" + "तपाईंको फोन अर्को पटक हवाइजहाज मोडमा लैजाँदा तपाईंको फोनले ब्लुटुथ अन राख्नु पर्ने कुरा याद गर्छ तपाईं ब्लुटुथ अन भइनरहोस् भन्ने चाहनुहुन्छ भने ब्लुटुथ अफ गर्नुहोस्।" + "Wi-Fi र ब्लुटुथ अन रहिरहने छन्" + "हवाइजहाज मोडमा पनि तपाईंको फोनको Wi-Fi र ब्लुटुथ अन नै रहिरहने छन्। तपाईं Wi-Fi र ब्लुटुथ अन भइनरहोस् भन्ने चाहनुहुन्छ भने तिनलाई अफ गर्नुहोस्।" diff --git a/android/app/res/values-nl/strings.xml b/android/app/res/values-nl/strings.xml index 826d5cf0d5f..da9a3110f37 100644 --- a/android/app/res/values-nl/strings.xml +++ b/android/app/res/values-nl/strings.xml @@ -23,6 +23,7 @@ "Bluetooth" "Onbekend apparaat" "Onbekend" + "Niet opgegeven" "Vliegtuigmodus" "Je kunt Bluetooth niet gebruiken in Vliegtuigmodus." @@ -41,10 +42,10 @@ "Delen via bluetooth: %1$s ontvangen" "Delen via bluetooth: %1$s ontvangen" "Delen via bluetooth: bestand %1$s niet ontvangen" - "Delen via bluetooth: %1$s verzenden" - "Delen via bluetooth: %1$s verzonden" + "Delen via bluetooth: %1$s sturen" + "Delen via bluetooth: %1$s verstuurd" "100% voltooid" - "Delen via bluetooth: bestand %1$s niet verzonden" + "Delen via bluetooth: bestand %1$s niet verstuurd" "Bestandsoverdracht" "Van: \'%1$s\'" "Bestand: %1$s" @@ -107,12 +108,10 @@ "Uitgaande overdrachten" "Overdrachtsgeschiedenis is leeg." "Alle items op de lijst worden gewist." - "Delen via bluetooth: verzonden bestanden" + "Delen via bluetooth: verstuurde bestanden" "Delen via bluetooth: ontvangen bestanden" - - - - + "{count,plural, =1{# mislukt.}other{# mislukt.}}" + "{count,plural, =1{# geslaagd, %1$s}other{# geslaagd, %1$s}}" "Lijst wissen" "Openen" "Wissen uit lijst" @@ -130,4 +129,10 @@ "Bluetooth-audio" "Bestanden groter dan 4 GB kunnen niet worden overgedragen" "Verbinding maken met bluetooth" + "Bluetooth aan in de vliegtuigmodus" + "Als je bluetooth laat aanstaan, onthoudt je telefoon dit en blijft bluetooth aanstaan als je de vliegtuigmodus weer aanzet" + "Bluetooth blijft aan" + "Bluetooth op je telefoon blijft aan in de vliegtuigmodus. Zet bluetooth uit als je niet wilt dat dit aan blijft." + "Wifi en bluetooth blijven aan" + "Wifi en bluetooth op je telefoon blijven aan in de vliegtuigmodus. Zet wifi en bluetooth uit als je niet wilt dat ze aan blijven." diff --git a/android/app/res/values-or/strings.xml b/android/app/res/values-or/strings.xml index 111d8824bbe..a9e5cdbf1ce 100644 --- a/android/app/res/values-or/strings.xml +++ b/android/app/res/values-or/strings.xml @@ -16,25 +16,26 @@ - "ଡାଉନଲୋଡ୍‌ ମ୍ୟାନେଜର୍‌କୁ ଆକ୍ସେସ୍‌ କରନ୍ତୁ।" + "ଡାଉନଲୋଡ ମ୍ୟାନେଜର୍‌କୁ ଆକ୍ସେସ୍‌ କରନ୍ତୁ।" "BluetoothShare ମ୍ୟାନେଜର୍‌ ଆକ୍ସେସ୍‌ କରି ଫାଇଲ୍‌ଗୁଡ଼ିକ ଟ୍ରାନ୍ସଫର୍‌ କରିବାକୁ ବ୍ୟବହାର କରିବା ପାଇଁ ଆପ୍‌କୁ ଅନୁମତି ଦିଅନ୍ତୁ।" "ବ୍ଲୁଟୁଥ୍ ଡିଭାଇସର ଆକ୍ସେସକୁ ଗ୍ରହଣ-ସୂଚୀରେ ରଖନ୍ତୁ।" - "ଏକ ବ୍ଲୁଟୁଥ୍ ଡିଭାଇସକୁ ଅସ୍ଥାୟୀ ଭାବେ ଗ୍ରହଣ-ସୂଚୀରେ ରଖିବାକୁ ଆପଟିକୁ ଅନୁମତି ଦେଇଥାଏ, ଯାହା ଦ୍ୱାରା ଉପଯୋଗକର୍ତ୍ତାଙ୍କ ସୁନିଶ୍ଚିତକରଣ ବିନା ଏହି ଡିଭାଇସକୁ ଫାଇଲ୍ ପଠାଇବା ପାଇଁ ସେହି ଡିଭାଇସକୁ ଅନୁମତି ମିଳିଥାଏ।" + "ଏକ ବ୍ଲୁଟୁଥ ଡିଭାଇସକୁ ଅସ୍ଥାୟୀ ଭାବେ ଗ୍ରହଣ-ସୂଚୀରେ ରଖିବାକୁ ଆପଟିକୁ ଅନୁମତି ଦେଇଥାଏ, ଯାହା ଦ୍ୱାରା ୟୁଜରଙ୍କ ସୁନିଶ୍ଚିତକରଣ ବିନା ଏହି ଡିଭାଇସକୁ ଫାଇଲ ପଠାଇବା ପାଇଁ ସେହି ଡିଭାଇସକୁ ଅନୁମତି ମିଳିଥାଏ।" "ବ୍ଲୁଟୁଥ" "ଅଜଣା ଡିଭାଇସ୍" "ଅଜଣା" - "ଏରୋପ୍ଲେନ୍‍ ମୋଡ୍" + "ପ୍ରଦାନ କରାଯାଇନାହିଁ" + "ଏରୋପ୍ଲେନ ମୋଡ" "ଆପଣ, ଏୟାରପ୍ଲେନ୍‌ ମୋଡ୍‌ରେ ବ୍ଲୁଟୂଥ୍‍‌ ବ୍ୟବହାର କରିପାରିବେ ନାହିଁ।" "ବ୍ଲୁଟୂଥ୍‍‌ ସେବା ବ୍ୟବହାର କରିବା ପାଇଁ, ଆପଣଙ୍କୁ ପ୍ରଥମେ ବ୍ଲୁଟୂଥ୍‍‌ ଅନ୍‌ କରିବାକୁ ପଡ଼ିବ।" "ବ୍ଲୁ-ଟୁଥ୍‌କୁ ଏବେ ଅନ୍‌ କରିବେ?" - "ବାତିଲ୍ କରନ୍ତୁ" + "ବାତିଲ କରନ୍ତୁ" "ଚାଲୁ କରନ୍ତୁ" "ଫାଇଲ୍‌ ଟ୍ରାନ୍ସଫର୍‌ କରନ୍ତୁ" - "ଆସୁଥିବା ଫାଇଲ୍‌କୁ ସ୍ୱୀକାର କରିବେ?" + "ଆସୁଥିବା ଫାଇଲକୁ ଗ୍ରହଣ କରିବେ?" "ଅସ୍ୱୀକାର" "ସ୍ୱୀକାର କରନ୍ତୁ" - "ଠିକ୍‌ ଅଛି" + "ଠିକ ଅଛି" "\"%1$s\"ଙ୍କଠାରୁ ଆସୁଥିବା ଫାଇଲ୍‌ ସ୍ୱୀକାର କରୁଥିବାବେଳେ ସମୟ ସମାପ୍ତ ହୋଇଗଲା" "ଆସୁଥିବା ଫାଇଲ୍‌" "%1$s ଏକ ଫାଇଲ୍ ପଠାଇବାକୁ ପ୍ରସ୍ତୁତ ଅଛନ୍ତି: %2$s" @@ -59,18 +60,18 @@ "ଫାଇଲ୍‌ ପ୍ରାପ୍ତ ହେଲା ନାହିଁ" "ଫାଇଲ୍‌: %1$s" "କାରଣ: %1$s" - "ଠିକ୍‌ ଅଛି" + "ଠିକ ଅଛି" "ଫାଇଲ୍‌ ପ୍ରାପ୍ତ ହେଲା" "ଖୋଲନ୍ତୁ" "ପ୍ରାପ୍ତକର୍ତ୍ତା: \"%1$s\"" "ଫାଇଲ୍‌ ପ୍ରକାର: %1$s (%2$s)" "ଫାଇଲ୍‌ ପଠାଯାଉଛି…" "ଫାଇଲ୍‌ ପଠାଗଲା" - "ଠିକ୍‌ ଅଛି" + "ଠିକ ଅଛି" "ଫାଇଲ୍‌ \"%1$s\"ଙ୍କୁ ପଠାଯାଇନଥିଲା।" "ଫାଇଲ୍‌: %1$s" "ବନ୍ଦ କରନ୍ତୁ" - "ଠିକ୍‌ ଅଛି" + "ଠିକ ଅଛି" "ଅଜଣା ଫାଇଲ୍‌" "ଏହିଭଳି ଫାଇଲ୍‌କୁ ସମ୍ଭାଳିବା ପାଇଁ କୌଣସି ଆପ୍‌ ନାହିଁ। \n" "କୌଣସି ଫାଇଲ୍‌ ନାହିଁ" @@ -92,7 +93,7 @@ "ଫାଇଲ୍‌ ଟ୍ରାନ୍ସଫର୍‌ ସଫଳତାପୂର୍ବକ ସମ୍ପୂର୍ଣ୍ଣ ହେଲା।" "କଣ୍ଟେଣ୍ଟ ସପୋର୍ଟ କରୁନାହିଁ।" "ଟାର୍ଗେଟ୍‌ ଡିଭାଇସ୍‌ ଦ୍ୱାରା ଟ୍ରାନ୍ସଫର୍‌ ପ୍ରତିବନ୍ଧିତ କରାଯାଇଛି।" - "ୟୁଜର୍‌ଙ୍କ ଦ୍ୱାରା ଟ୍ରାନ୍ସଫର୍‌ କ୍ୟାନ୍ସଲ୍‌ କରାଗଲା।" + "ୟୁଜରଙ୍କ ଦ୍ୱାରା ଟ୍ରାନ୍ସଫର କେନ୍ସଲ କରାଯାଇଛି।" "ଷ୍ଟୋରେଜ୍‌ ସମସ୍ୟା।" "କୌଣସି USB ଷ୍ଟୋରେଜ୍‌ ନାହିଁ।" "କୌଣସି SD କାର୍ଡ ନାହିଁ। ଟ୍ରାନ୍ସଫର୍‌ କରାଯାଇଥିବା ଫାଇଲ୍‌ଗୁଡ଼ିକୁ ସେଭ୍‌ କରିବା ପାଇଁ ଗୋଟିଏ SD କାର୍ଡ ଭର୍ତ୍ତି କରନ୍ତୁ।" @@ -109,17 +110,15 @@ "ତାଲିକାରୁ ସମସ୍ତ ଆଇଟମ୍‌କୁ ଖାଲି କରିଦିଆଯିବ।" "ବ୍ଲୁଟୂଥ୍‍‌ ସେୟାର୍‌: ପଠାଯାଇଥିବା ଫାଇଲ୍‌" "ବ୍ଲୁଟୂଥ୍‍‌ ସେୟାର୍‌: ପ୍ରାପ୍ତ କରାଯାଇଥିବା ଫାଇଲ୍‌" - - - - + "{count,plural, =1{#ଟି ଅସଫଳ ହୋଇଛି।}other{#ଟି ଅସଫଳ ହୋଇଛି।}}" + "{count,plural, =1{#ଟି ସଫଳ ହୋଇଛି, %1$s}other{#ଟି ସଫଳ ହୋଇଛି, %1$s}}" "ତାଲିକା ଖାଲି କରନ୍ତୁ" "ଖୋଲନ୍ତୁ" "ତାଲିକାରୁ ଖାଲି କରନ୍ତୁ" "ଖାଲି କରନ୍ତୁ" "ବର୍ତ୍ତମାନ ଚାଲୁଛି" "ସେଭ୍‌ କରନ୍ତୁ" - "ବାତିଲ୍ କରନ୍ତୁ" + "ବାତିଲ କରନ୍ତୁ" "ବ୍ଲୁଟୂଥ୍‍‌ ମାଧ୍ୟମରେ ସେୟାର୍‌ କରିବାକୁ ଚାହୁଁଥିବା ଆକାଉଣ୍ଟଗୁଡ଼ିକୁ ଚୟନ କରନ୍ତୁ। ଆପଣଙ୍କୁ ତଥାପି ସଂଯୋଗ କରୁଥିବା ସମୟରେ ଆକାଉଣ୍ଟଗୁଡ଼ିକ ପ୍ରତି ଯେକୌଣସି ଆକ୍ସେସ୍‌କୁ ସ୍ୱୀକାର କରିବାକୁ ପଡ଼ିବ।" "ବଳକା ସ୍ଲଟ୍‌:" "ଆପ୍ଲିକେଶନ୍‌ ଆଇକନ୍‌" @@ -130,4 +129,10 @@ "ବ୍ଲୁଟୂଥ୍‍‌ ଅଡିଓ" "4GBରୁ ବଡ଼ ଫାଇଲ୍‌ଗୁଡ଼ିକୁ ଟ୍ରାନ୍ସଫର୍‌ କରାଯାଇପାରିବ ନାହିଁ" "ବ୍ଲୁଟୁଥ୍ ସହ ସଂଯୋଗ କରନ୍ତୁ" + "ଏୟାରପ୍ଲେନ ମୋଡରେ ବ୍ଲୁଟୁଥ ଚାଲୁ ଅଛି" + "ଯଦି ଆପଣ ବ୍ଲୁଟୁଥକୁ ଚାଲୁ ରଖନ୍ତି, ତେବେ ଆପଣ ପରବର୍ତ୍ତୀ ଥର ଏୟାରପ୍ଲେନ ମୋଡରେ ଥିବା ସମୟରେ ଆପଣଙ୍କ ଫୋନ ଏହାକୁ ଚାଲୁ ରଖିବା ପାଇଁ ମନେ ରଖିବ" + "ବ୍ଲୁଟୁଥ ଚାଲୁ ରହେ" + "ଆପଣଙ୍କ ଫୋନ ଏୟାରପ୍ଲେନ ମୋଡରେ ବ୍ଲୁଟୁଥକୁ ଚାଲୁ ରଖିବା ପାଇଁ ମନେ ରଖେ। ଯଦି ଆପଣ ବ୍ଲୁଟୁଥ ଚାଲୁ ରଖିବାକୁ ଚାହାଁନ୍ତି ନାହିଁ ତେବେ ଏହାକୁ ବନ୍ଦ କରନ୍ତୁ।" + "ୱାଇ-ଫାଇ ଏବଂ ବ୍ଲୁଟୁଥ ଚାଲୁ ରହେ" + "ଆପଣଙ୍କ ଫୋନ ଏୟାରପ୍ଲେନ ମୋଡରେ ୱାଇ-ଫାଇ ଏବଂ ବ୍ଲୁଟୁଥକୁ ଚାଲୁ ରଖିବା ପାଇଁ ମନେ ରଖେ। ଯଦି ଆପଣ ୱାଇ-ଫାଇ ଏବଂ ବ୍ଲୁଟୁଥ ଚାଲୁ ରଖିବାକୁ ଚାହାଁନ୍ତି ନାହିଁ ତେବେ ସେଗୁଡ଼ିକୁ ବନ୍ଦ କରନ୍ତୁ।" diff --git a/android/app/res/values-pa/strings.xml b/android/app/res/values-pa/strings.xml index b3120c00cd5..84c78ced7cc 100644 --- a/android/app/res/values-pa/strings.xml +++ b/android/app/res/values-pa/strings.xml @@ -23,6 +23,7 @@ "ਬਲੂਟੁੱਥ" "ਅਗਿਆਤ ਡੀਵਾਈਸ" "ਅਗਿਆਤ" + "ਮੁਹੱਈਆ ਨਹੀਂ ਕਰਵਾਇਆ ਗਿਆ" "ਏਅਰਪਲੇਨ ਮੋਡ" "ਤੁਸੀਂ ਏਅਰਪਲੇਨ ਮੋਡ ਵਿੱਚ Bluetooth ਨਹੀਂ ਵਰਤ ਸਕਦੇ।" @@ -31,30 +32,30 @@ "ਰੱਦ ਕਰੋ" "ਚਾਲੂ ਕਰੋ" "ਫਾਈਲ ਟ੍ਰਾਂਸਫਰ" - "ਕੀ ਇਨਕਮਿੰਗ ਫਾਈਲ ਸਵੀਕਾਰ ਕਰਨੀ ਹੈ?" + "ਕੀ ਇਨਕਮਿੰਗ ਫ਼ਾਈਲ ਸਵੀਕਾਰ ਕਰਨੀ ਹੈ?" "ਅਸਵੀਕਾਰ ਕਰੋ" "ਸਵੀਕਾਰ ਕਰੋ" "ਠੀਕ" "\"%1$s\" ਦੀ ਇੱਕ ਇਨਕਮਿੰਗ ਫਾਈਲ ਸਵੀਕਾਰ ਕਰਨ ਵੇਲੇ ਇੱਕ ਟਾਈਮਆਊਟ ਹੋਇਆ ਸੀ।" - "ਇਨਕਮਿੰਗ ਫਾਈਲ" + "ਇਨਕਮਿੰਗ ਫ਼ਾਈਲ" "%1$s ਫ਼ਾਈਲ ਭੇਜਣ ਲਈ ਤਿਆਰ ਹੈ: %2$s" "Bluetooth ਸ਼ੇਅਰ: %1$s ਪ੍ਰਾਪਤ ਕਰ ਰਿਹਾ ਹੈ" "Bluetooth ਸ਼ੇਅਰ: %1$s ਪ੍ਰਾਪਤ ਕੀਤੀ" "Bluetooth ਸ਼ੇਅਰ: ਫਾਈਲ %1$s ਪ੍ਰਾਪਤ ਨਹੀਂ ਕੀਤੀ" - "Bluetooth ਸ਼ੇਅਰ: %1$s ਭੇਜ ਰਿਹਾ ਹੈ" + "ਬਲੂਟੁੱਥ ਸਾਂਝਾਕਰਨ: %1$s ਨੂੰ ਭੇਜਿਆ ਜਾ ਰਿਹਾ ਹੈ" "Bluetooth ਸ਼ੇਅਰ: %1$s ਭੇਜੀ ਗਈ" "100% ਪੂਰਾ" "Bluetooth ਸ਼ੇਅਰ: ਫਾਈਲ %1$s ਨਹੀਂ ਭੇਜੀ ਗਈ" "ਫਾਈਲ ਟ੍ਰਾਂਸਫਰ" - "ਤੋਂ: \"%1$s\"" + "ਇਨ੍ਹਾਂ ਵੱਲੋਂ: \"%1$s\"" "ਫਾਈਲ: %1$s" "ਫਾਈਲ ਆਕਾਰ: %1$s" "ਫਾਈਲ ਪ੍ਰਾਪਤ ਕਰ ਰਿਹਾ ਹੈ…" "ਰੋਕੋ" "ਲੁਕਾਓ" - "ਤੋਂ" - "ਫਾਈਲ ਨਾਮ" + "ਇਨ੍ਹਾਂ ਵੱਲੋਂ" + "ਫ਼ਾਈਲ ਦਾ ਨਾਮ" "ਆਕਾਰ" "ਫਾਈਲ ਪ੍ਰਾਪਤ ਨਹੀਂ ਕੀਤੀ" "ਫਾਈਲ: %1$s" @@ -109,10 +110,8 @@ "ਸਾਰੀਆਂ ਆਈਟਮਾਂ ਸੂਚੀ ਵਿੱਚੋਂ ਹਟਾਈਆਂ ਜਾਣਗੀਆਂ।" "ਬਲੂਟੁੱਥ ਸਾਂਝਾਕਰਨ: ਭੇਜੀਆਂ ਗਈਆਂ ਫ਼ਾਈਲਾਂ" "ਬਲੂਟੁੱਥ ਸਾਂਝਾਕਰਨ: ਪ੍ਰਾਪਤ ਕੀਤੀਆਂ ਫ਼ਾਈਲਾਂ" - - - - + "{count,plural, =1{# ਅਸਫਲ।}one{# ਅਸਫਲ।}other{# ਅਸਫਲ।}}" + "{count,plural, =1{# ਸਫਲ, %1$s}one{# ਸਫਲ, %1$s}other{# ਸਫਲ, %1$s}}" "ਸੂਚੀ ਹਟਾਓ" "ਖੋਲ੍ਹੋ" "ਸੂਚੀ ਵਿੱਚੋਂ ਹਟਾਓ" @@ -130,4 +129,10 @@ "ਬਲੂਟੁੱਥ ਆਡੀਓ" "4GB ਤੋਂ ਜ਼ਿਆਦਾ ਵੱਡੀਆਂ ਫ਼ਾਈਲਾਂ ਨੂੰ ਟ੍ਰਾਂਸਫ਼ਰ ਨਹੀਂ ਕੀਤਾ ਜਾ ਸਕਦਾ" "ਬਲੂਟੁੱਥ ਨਾਲ ਕਨੈਕਟ ਕਰੋ" + "ਹਵਾਈ-ਜਹਾਜ਼ ਮੋਡ ਵਿੱਚ ਬਲੂਟੁੱਥ ਚਾਲੂ ਹੈ" + "ਜੇ ਤੁਸੀਂ ਬਲੂਟੁੱਥ ਨੂੰ ਚਾਲੂ ਰੱਖਦੇ ਹੋ, ਤਾਂ ਅਗਲੀ ਵਾਰ ਤੁਹਾਡਾ ਫ਼ੋਨ ਹਵਾਈ-ਜਹਾਜ਼ ਮੋਡ ਵਿੱਚ ਹੋਣ \'ਤੇ ਤੁਹਾਡਾ ਫ਼ੋਨ ਇਸਨੂੰ ਚਾਲੂ ਰੱਖਣਾ ਯਾਦ ਰੱਖੇਗਾ" + "ਬਲੂਟੁੱਥ ਚਾਲੂ ਰਹਿੰਦਾ ਹੈ" + "ਤੁਹਾਡਾ ਫ਼ੋਨ ਹਵਾਈ-ਜਹਾਜ਼ ਮੋਡ ਵਿੱਚ ਬਲੂਟੁੱਥ ਨੂੰ ਚਾਲੂ ਰੱਖਣਾ ਯਾਦ ਰੱਖਦਾ ਹੈ। ਜੇ ਤੁਸੀਂ ਇਸਨੂੰ ਚਾਲੂ ਨਹੀਂ ਰੱਖਣਾ ਚਾਹੁੰਦੇ, ਤਾਂ ਬਲੂਟੁੱਥ ਨੂੰ ਬੰਦ ਕਰੋ।" + "ਵਾਈ-ਫਾਈ ਅਤੇ ਬਲੂਟੁੱਥ ਚਾਲੂ ਰਹਿੰਦੇ ਹਨ" + "ਤੁਹਾਡਾ ਫ਼ੋਨ ਹਵਾਈ-ਜਹਾਜ਼ ਮੋਡ ਵਿੱਚ ਵਾਈ-ਫਾਈ ਅਤੇ ਬਲੂਟੁੱਥ ਨੂੰ ਚਾਲੂ ਰੱਖਣਾ ਯਾਦ ਰੱਖਦਾ ਹੈ। ਜੇ ਤੁਸੀਂ ਇਨ੍ਹਾਂ ਨੂੰ ਚਾਲੂ ਨਹੀਂ ਰੱਖਣਾ ਚਾਹੁੰਦੇ, ਤਾਂ ਵਾਈ-ਫਾਈ ਅਤੇ ਬਲੂਟੁੱਥ ਨੂੰ ਬੰਦ ਕਰੋ।" diff --git a/android/app/res/values-pl/strings.xml b/android/app/res/values-pl/strings.xml index 928ea45009a..1db2aa19cc5 100644 --- a/android/app/res/values-pl/strings.xml +++ b/android/app/res/values-pl/strings.xml @@ -23,6 +23,7 @@ "Bluetooth" "Nieznane urządzenie" "Nieznany" + "Nie podano" "Tryb samolotowy" "Funkcji Bluetooth nie można używać w trybie samolotowym." @@ -109,10 +110,8 @@ "Wszystkie elementy zostaną usunięte z listy." "Udostępnianie Bluetooth: wysłane pliki" "Udostępnianie Bluetooth: odebrane pliki" - - - - + "{count,plural, =1{nieudane: #.}few{nieudane: #.}many{nieudane: #.}other{nieudane: #.}}" + "{count,plural, =1{Udane: #, %1$s}few{Udane: #, %1$s}many{Udane: #, %1$s}other{Udane: #, %1$s}}" "Wyczyść listę" "Otwórz" "Usuń z listy" @@ -130,4 +129,10 @@ "Dźwięk Bluetooth" "Nie można przenieść plików przekraczających 4 GB" "Nawiązywanie połączeń przez Bluetooth" + "Bluetooth włączony w trybie samolotowym" + "Jeśli pozostawisz włączony Bluetooth, telefon zachowa się podobnie przy kolejnym przejściu w tryb samolotowy" + "Bluetooth pozostanie włączony" + "Bluetooth na telefonie pozostaje włączony w trybie samolotowym. Wyłącz Bluetooth, jeśli nie chcesz, żeby pozostawał włączony." + "Wi-Fi i Bluetooth pozostają włączone" + "Wi-Fi i Bluetooth na telefonie pozostają włączone w trybie samolotowym. Wyłącz Wi-Fi i Bluetooth, jeśli nie chcesz, żeby funkcje te pozostawały włączone." diff --git a/android/app/res/values-pt-rPT/strings.xml b/android/app/res/values-pt-rPT/strings.xml index 76d933e5c48..35b530a2032 100644 --- a/android/app/res/values-pt-rPT/strings.xml +++ b/android/app/res/values-pt-rPT/strings.xml @@ -23,6 +23,7 @@ "Bluetooth" "Dispositivo desconhecido" "Desconhecido" + "Não fornecidos" "Modo de avião" "Não pode utilizar o Bluetooth em modo de Avião." @@ -31,12 +32,12 @@ "Cancelar" "Ativar" "Transferência do ficheiro" - "Pretende aceitar o ficheiro a receber?" + "Aceitar e receber o ficheiro?" "Recusar" "Aceitar" "OK" "Foi excedido o tempo limite durante a aceitação de um ficheiro de \"%1$s\"" - "Ficheiro a receber" + "A receber ficheiro" "%1$s tem tudo pronto para enviar um ficheiro: %2$s" "Partilha Bluetooth: a receber %1$s" "Partilha Bluetooth: %1$s recebido" @@ -86,7 +87,7 @@ "Não existe espaço suficiente na memória USB para guardar o ficheiro." "Não existe espaço suficiente no cartão SD para guardar o ficheiro." "Espaço necessário: %1$s" - "Existem demasiados pedidos em processamento. Tente novamente mais tarde." + "Existem demasiados pedidos em processamento. Tente mais tarde." "Ainda não foi iniciada a transferência do ficheiro." "Transferência do ficheiro em curso." "Transferência de ficheiros concluída com êxito." @@ -109,10 +110,8 @@ "Todos os itens serão removidos da lista." "Partilha por Bluetooth: ficheiros enviados" "Partilha por Bluetooth: ficheiros recebidos" - - - - + "{count,plural, =1{# sem êxito.}other{# sem êxito.}}" + "{count,plural, =1{# com êxito, %1$s}other{# com êxito, %1$s}}" "Limpar lista" "Abrir" "Limpar da lista" @@ -130,4 +129,10 @@ "Áudio Bluetooth" "Não é possível transferir os ficheiros com mais de 4 GB." "Ligar ao Bluetooth" + "Bluetooth ativado no modo de avião" + "Se mantiver o Bluetooth ativado, o telemóvel vai lembrar-se de o manter ativado da próxima vez que estiver no modo de avião" + "O Bluetooth mantém-se ativado" + "O seu telemóvel mantém o Bluetooth ativado no modo de avião. Desative o Bluetooth se não quiser que fique ativado." + "O Wi-Fi e o Bluetooth mantêm-se ativados" + "O seu telemóvel mantém o Wi-Fi e o Bluetooth ativados no modo de avião. Desative o Wi-Fi e o Bluetooth se não quiser que fiquem ativados." diff --git a/android/app/res/values-pt/strings.xml b/android/app/res/values-pt/strings.xml index 2682f001615..b7e878172a2 100644 --- a/android/app/res/values-pt/strings.xml +++ b/android/app/res/values-pt/strings.xml @@ -23,6 +23,7 @@ "Bluetooth" "Dispositivo desconhecido" "Desconhecido" + "Não fornecidos" "Modo avião" "Não é possível usar o Bluetooth no modo avião." @@ -31,20 +32,20 @@ "Cancelar" "Ativar" "Transferência de arquivo" - "Aceitar o arquivo recebido?" + "Aceitar o arquivo transferido?" "Recusar" "Aceitar" "OK" "Tempo limite excedido ao receber um arquivo de \"%1$s\"" - "Arquivo recebido" + "Recebendo arquivo" "%1$s já pode enviar um arquivo: %2$s" - "Compart. Bluetooth: recebendo %1$s" - "Compart. Bluetooth: %1$s recebido" - "Compart. Bluetooth: o arquivo %1$s não foi recebido" - "Compart. Bluetooth: enviando %1$s" - "Compart. Bluetooth: %1$s enviado" + "Bluetooth: recebendo %1$s" + "Bluetooth: %1$s recebido" + "Bluetooth: arquivo %1$s não recebido" + "Bluetooth: enviando %1$s" + "Bluetooth: %1$s enviado" "100% concluído" - "Compart. Bluetooth: o arquivo %1$s não foi enviado" + "Bluetooth: arquivo %1$s não enviado" "Transferência de arquivo" "De: \"%1$s\"" "Arquivo: %1$s" @@ -100,19 +101,17 @@ "Não é possível tratar a solicitação corretamente." "Erro desconhecido." "Recebido por Bluetooth" - "Compartilhamento Bluetooth" + "Envio por Bluetooth" "%1$s Recebimento concluído." "%1$s Envio concluído." "Transferências de entrada" "Transferências de saída" "O histórico de transferências está vazio." "Todos os itens serão excluídos da lista." - "Compartilhamento Bluetooth: Arquivos enviados" - "Compartilhamento Bluetooth: Arquivos recebidos" - - - - + "Bluetooth: arquivos enviados" + "Bluetooth: arquivos recebidos" + "{count,plural, =1{# falhou.}one{# falhou.}other{# falharam.}}" + "{count,plural, =1{# enviado, %1$s}one{# enviado, %1$s}other{# enviados, %1$s}}" "Limpar lista" "Abrir" "Limpar da lista" @@ -130,4 +129,10 @@ "Áudio Bluetooth" "Não é possível transferir arquivos maiores que 4 GB" "Conectar ao Bluetooth" + "Bluetooth ativado no modo avião" + "Se você escolher manter o Bluetooth ativado, essa configuração vai ser aplicada na próxima vez que usar o modo avião" + "O Bluetooth fica ativado" + "O smartphone vai manter o Bluetooth ativado no modo avião. Ele pode ser desativado manualmente se você preferir." + "O Wi-Fi e o Bluetooth ficam ativados" + "O smartphone vai manter o Wi-Fi e o Bluetooth ativados no modo avião. Eles podem ser desativados manualmente se você preferir." diff --git a/android/app/res/values-ro/strings.xml b/android/app/res/values-ro/strings.xml index bd296e65c37..42d968415ad 100644 --- a/android/app/res/values-ro/strings.xml +++ b/android/app/res/values-ro/strings.xml @@ -16,24 +16,25 @@ - "Accesați managerul de descărcare." + "Accesează managerul de descărcare." "Permite aplicațiilor să acceseze managerul Distribuire prin Bluetooth și să-l utilizeze la transferul fișierelor." - "Acceptați accesul la dispozitivul Bluetooth." + "Acceptă accesul la dispozitivul Bluetooth." "Permite aplicației să accepte temporar un dispozitiv Bluetooth, permițându-i să trimită fișiere pe acest dispozitiv fără confirmare din partea utilizatorului." "Bluetooth" "Dispozitiv necunoscut" "Necunoscut" + "Nu s-a specificat" "Mod Avion" - "Nu puteți utiliza Bluetooth în modul Avion." + "Nu poți folosi Bluetooth în modul Avion." - "Pentru a putea utiliza serviciile Bluetooth, trebuie mai întâi să le activați." - "Activați acum Bluetooth?" - "Anulați" - "Activați" + "Pentru a putea folosi serviciile Bluetooth, trebuie mai întâi să le activezi." + "Activezi acum Bluetooth?" + "Anulează" + "Activează" "Transfer de fișier" - "Acceptați fișierul primit?" - "Refuzați" - "Acceptați" + "Accepți fișierul primit?" + "Refuză" + "Acceptă" "OK" "A fost atins timpul limită pentru acceptarea unui fișier primit de la „%1$s”" "Fișier primit" @@ -51,8 +52,8 @@ "Dimensiunea fișierului: %1$s" "Se primește fișierul..." - "Opriți" - "Ascundeți" + "Oprește" + "Ascunde" "De la" "Numele fișierului" "Dimensiunea" @@ -61,7 +62,7 @@ "Motiv: %1$s" "OK" "Fișier primit" - "Deschideți" + "Deschide" "Către: „%1$s”" "Tip de fișier: %1$s (%2$s)" "Se trimite fișierul..." @@ -69,24 +70,24 @@ "OK" "Fișierul nu a fost trimis la „%1$s”." "Fișier: %1$s" - "Închideți" + "Închide" "OK" "Fișier necunoscut" "Nu există nicio aplicație care să gestioneze acest tip de fișier. \n" "Niciun fișier" "Fișierul nu există. \n" - "Așteptați..." + "Așteaptă..." "Se activează Bluetooth..." - "Se va primi fișierul. Verificați progresul în panoul de notificări." + "Se va primi fișierul. Verifică progresul în panoul de notificări." "Fișierul nu poate fi primit." "Primirea fișierului de la „%1$s” a fost anulată" "Se trimite fișierul către „%1$s”" - "Se trimit %1$s fișiere către „%2$s”" + "Se trimit %1$s fișiere către „%2$s”" "Trimiterea fișierului către „%1$s” a fost anulată" "Nu există suficient spațiu de stocare USB pentru a salva fișierul." "Nu există spațiu suficient pe cardul SD pentru a salva fișierul." "Spațiu necesar: %1$s" - "Există prea multe solicitări în curs de procesare. Încercați din nou mai târziu." + "Există prea multe solicitări în curs de procesare. Încearcă din nou mai târziu." "Transferul fișierului nu a început încă." "Transferul fișierului este în curs de desfășurare." "Transferul fișierului s-a încheiat." @@ -95,7 +96,7 @@ "Transfer anulat de către utilizator." "Problemă de stocare." "Nu există spațiu de stocare USB." - "Nu există card SD. Introduceți un card SD pentru a salva fișierele transferate." + "Nu există card SD. Introdu un card SD pentru a salva fișierele transferate." "Conectare eșuată." "Solicitarea nu poate fi gestionată corect." "Eroare necunoscută." @@ -109,18 +110,16 @@ "Toate elementele din listă vor fi eliminate." "Distribuire prin Bluetooth: fișiere trimise" "Bluetooth: fișiere primite" - - - - - "Ștergeți lista" - "Deschideți" - "Ștergeți din listă" - "Ștergeți" + "{count,plural, =1{# netrimis.}few{# netrimise.}other{# netrimise.}}" + "{count,plural, =1{# trimis, %1$s}few{# trimise, %1$s}other{# trimise, %1$s}}" + "Șterge lista" + "Deschide" + "Șterge din listă" + "Șterge" "Now Playing" - "Salvați" - "Anulați" - "Selectați conturile la care doriți să permiteți accesul prin Bluetooth. Va trebui să acceptați accesul la conturi la conectare." + "Salvează" + "Anulează" + "Selectează conturile la care vrei să permiți accesul prin Bluetooth. Va trebui să accepți accesul la conturi la conectare." "Sloturi rămase:" "Pictograma aplicației" "Setări de permitere a accesului la mesajele prin Bluetooth" @@ -129,5 +128,11 @@ "Audio prin Bluetooth deconectat" "Audio prin Bluetooth" "Fișierele mai mari de 4 GB nu pot fi transferate" - "Conectați-vă la Bluetooth" + "Conectează-te la Bluetooth" + "Bluetooth activat în modul Avion" + "Dacă păstrezi Bluetooth activat, telefonul tău va reține să-l păstreze activat data viitoare când ești în modul Avion" + "Bluetooth rămâne activat" + "Telefonul reține să păstreze Bluetooth activat în modul Avion. Dezactivează Bluetooth dacă nu vrei să rămână activat." + "Wi-Fi și Bluetooth rămân activate" + "Telefonul reține să păstreze funcțiile Wi-Fi și Bluetooth activate în modul Avion. Dezactivează Wi-Fi și Bluetooth dacă nu vrei să rămână activate." diff --git a/android/app/res/values-ru/strings.xml b/android/app/res/values-ru/strings.xml index aee418cd307..9519a3a37f1 100644 --- a/android/app/res/values-ru/strings.xml +++ b/android/app/res/values-ru/strings.xml @@ -23,6 +23,7 @@ "Bluetooth" "Неизвестное устройство" "Неизвестно" + "Отсутствуют" "Режим полета" "В режиме полета нельзя использовать Bluetooth." @@ -109,10 +110,8 @@ "Все элементы будут удалены из списка." "Передано по Bluetooth" "Получено по Bluetooth" - - - - + "{count,plural, =1{неуспешно – # файл.}one{неуспешно – # файл.}few{неуспешно – # файла.}many{неуспешно – # файлов.}other{неуспешно – # файла.}}" + "{count,plural, =1{Успешно передан # файл, %1$s}one{Успешно передан # файл, %1$s}few{Успешно передано # файла, %1$s}many{Успешно передано # файлов, %1$s}other{Успешно передано # файла, %1$s}}" "Очистить список" "Открыть" "Удалить из списка" @@ -130,4 +129,10 @@ "Звук через Bluetooth" "Можно перенести только файлы размером до 4 ГБ." "Подключиться по Bluetooth" + "Функция Bluetooth будет включена в режиме полета" + "Если не отключить функцию Bluetooth, в следующий раз она останется включенной в режиме полета." + "Функция Bluetooth остается включенной" + "Функция Bluetooth останется включенной в режиме полета. Вы можете отключить ее, если хотите." + "Функции Wi‑Fi и Bluetooth остаются включенными" + "Wi‑Fi и Bluetooth останутся включенными в режиме полета. Вы можете отключить их, если хотите." diff --git a/android/app/res/values-si/strings.xml b/android/app/res/values-si/strings.xml index 0b5ddb80a0b..2757685fa62 100644 --- a/android/app/res/values-si/strings.xml +++ b/android/app/res/values-si/strings.xml @@ -23,6 +23,7 @@ "බ්ලූටූත්" "නොදන්නා උපාංගයකි" "නොදනී" + "සපයා නොමැත" "ගුවන්යානා ආකාරය" "ඔබට ගුවන්යානා ආකාරය තුළ බ්ලූටූත් භාවිතා කළ නොහැක." @@ -109,10 +110,8 @@ "ලැයිස්තුව වෙතින් සියලු අයිතම හිස් කරනු ඇත." "බ්ලූටූත් බෙදා ගන්න: ගොනු යැවිණි" "බ්ලූටූත් බෙදා ගැනීම: ගොනු ලැබිණි" - - - - + "{count,plural, =1{# අසාර්ථකයි.}one{# අසාර්ථකයි.}other{# අසාර්ථකයි.}}" + "{count,plural, =1{# සාර්ථකයි, %1$s}one{# සාර්ථකයි, %1$s}other{# සාර්ථකයි, %1$s}}" "ලැයිස්තුව හිස් කරන්න" "විවෘත කරන්න" "ලැයිස්තුව වෙතින් හිස් කරන්න" @@ -130,4 +129,10 @@ "බ්ලූටූත් ශ්‍රව්‍යය" "4GBට වඩා විශාල ගොනු මාරු කළ නොහැකිය" "බ්ලූටූත් වෙත සබඳින්න" + "අහස්යානා ආකාරයේ බ්ලූටූත් ක්‍රියාත්මකයි" + "ඔබ බ්ලූටූත් ක්‍රියාත්මක කර තබා ගන්නේ නම්, ඔබ අහස්යානා ආකාරයේ සිටින මීළඟ වතාවේ එය ක්‍රියාත්මක කිරීමට ඔබේ දුරකථනයට මතක තිබෙනු ඇත." + "බ්ලූටූත් ක්‍රියාත්මකව පවතී" + "ඔබේ දුරකථනයට අහස්යානා ආකාරයේ බ්ලූටූත් ක්‍රියාත්මකව තබා ගැනීමට මතකයි. ඔබට බ්ලූටූත් ක්‍රියාත්මක වීමට අවශ්‍ය නොවේ නම් එය ක්‍රියාවිරහිත කරන්න." + "Wi-Fi සහ බ්ලූටූත් ක්‍රියාත්මකව පවතී" + "ඔබේ දුරකථනයට අහස්යානා ආකාරයේ Wi-Fi සහ බ්ලූටූත් ක්‍රියාත්මකව තබා ගැනීමට මතකයි. Wi-Fi සහ බ්ලූටූත් ඒවා ක්‍රියාත්මක වීමට ඔබට අවශ්‍ය නැතිනම් ක්‍රියා විරහිත කරන්න." diff --git a/android/app/res/values-sk/strings.xml b/android/app/res/values-sk/strings.xml index b6fc4e338af..4b1c9782df2 100644 --- a/android/app/res/values-sk/strings.xml +++ b/android/app/res/values-sk/strings.xml @@ -23,6 +23,7 @@ "Bluetooth" "Neznáme zariadenie" "Neznáme" + "Neposkytnuté" "Režim v lietadle" "Technológiu Bluetooth nemôžete používať v režime V lietadle." @@ -109,10 +110,8 @@ "Zo zoznamu budú vymazané všetky položky." "Bluetooth: Odoslané súbory" "Bluetooth: Prijaté súbory" - - - - + "{count,plural, =1{# neúspech.}few{# neúspechy.}many{# neúspechu.}other{# neúspechov.}}" + "{count,plural, =1{# úspech, %1$s}few{# úspechy, %1$s}many{# úspechu, %1$s}other{# úspechov, %1$s}}" "Vymazať zoznam" "Otvoriť" "Vymazať zo zoznamu" @@ -130,4 +129,10 @@ "Bluetooth Audio" "Súbory väčšie ako 4 GB sa nedajú preniesť" "Pripojiť k zariadeniu Bluetooth" + "Rozhranie Bluetooth bude v režime v lietadle zapnuté" + "Ak ponecháte rozhranie Bluetooth zapnuté, váš telefón si zapamätá, že ho má ponechať zapnuté pri ďalšom aktivovaní režimu v lietadle" + "Rozhranie Bluetooth zostane zapnuté" + "Telefón si pamätá, aby v režime v lietadle nevypínal rozhranie Bluetooth. Ak ho nechcete ponechať zapnuté, vypnite ho." + "Wi‑Fi a Bluetooth zostanú zapnuté" + "Telefón si pamätá, aby v režime v lietadle nevypínal Wi‑Fi ani Bluetooth. Ak ich nechcete ponechať zapnuté, vypnite ich." diff --git a/android/app/res/values-sl/strings.xml b/android/app/res/values-sl/strings.xml index 9fb4e075299..696e4260fc7 100644 --- a/android/app/res/values-sl/strings.xml +++ b/android/app/res/values-sl/strings.xml @@ -23,6 +23,7 @@ "Bluetooth" "Neznana naprava" "Neznano" + "Ni navedeno" "Način za letalo" "Bluetootha ne morete uporabljati v načinu za letalo." @@ -109,10 +110,8 @@ "Vsi elementi bodo izbrisani s seznama." "Bluetooth: Poslane datoteke" "Bluetooth: Prejete datoteke" - - - - + "{count,plural, =1{neuspešno: #.}one{neuspešno: #.}two{neuspešno: #.}few{neuspešno: #.}other{neuspešno: #.}}" + "{count,plural, =1{Uspešno: #, %1$s}one{Uspešno: #, %1$s}two{Uspešno: #, %1$s}few{Uspešno: #, %1$s}other{Uspešno: #, %1$s}}" "Počisti seznam" "Odpri" "Počisti s seznama" @@ -130,4 +129,10 @@ "Zvok prek Bluetootha" "Datotek, večjih od 4 GB, ni mogoče prenesti" "Povezovanje z Bluetoothom" + "Bluetooth je vklopljen v načinu za letalo" + "Če pustite Bluetooth vklopljen, bo telefon ob naslednjem preklopu na način za letalo pustil Bluetooth vklopljen." + "Bluetooth ostane vklopljen" + "Telefon v načinu za letalo pusti Bluetooth vklopljen. Če ne želite, da ostane vklopljen, izklopite vmesnik Bluetooth." + "Wi-Fi in Bluetooth ostaneta vklopljena" + "Telefon v načinu za letalo pusti Wi-Fi in Bluetooth vklopljena. Če ne želite, da Wi-Fi in Bluetooth ostaneta vklopljena, ju izklopite." diff --git a/android/app/res/values-sq/strings.xml b/android/app/res/values-sq/strings.xml index 206eaca0adc..16a94408ba8 100644 --- a/android/app/res/values-sq/strings.xml +++ b/android/app/res/values-sq/strings.xml @@ -23,6 +23,7 @@ "Bluetooth" "Pajisje e panjohur" "I panjohur" + "Nuk ofrohet" "Modaliteti \"në aeroplan\"" "Nuk mund të përdorësh bluetooth në modalitetin \"në aeroplan\"." @@ -109,10 +110,8 @@ "Të gjithë artikujt do të pastrohen nga lista." "Shpërndarja përmes Bluetooth-it: Skedarët e dërguar" "Shpërndarja përmes bluetooth-it: Skedarët e pranuar" - - - - + "{count,plural, =1{# nuk u nda me sukses.}other{# nuk u ndanë me sukses.}}" + "{count,plural, =1{# u nda me sukses, %1$s}other{# u ndanë me sukses, %1$s}}" "Pastro listën" "Hap" "Pastro nga lista" @@ -130,4 +129,10 @@ "Audioja e \"bluetooth-it\"" "Skedarët më të mëdhenj se 4 GB nuk mund të transferohen" "Lidhu me Bluetooth" + "Bluetooth-i aktiv në modalitetin e aeroplanit" + "Nëse e mban Bluetooth-in të aktivizuar, telefoni yt do të kujtohet ta mbajë atë të aktivizuar herën tjetër kur të jesh në modalitetin e aeroplanit" + "Bluetooth qëndron i aktivizuar" + "Telefoni yt kujtohet që ta mbajë Bluetooth-in të aktivizuar në modalitetin e aeroplanit. Çaktivizo Bluetooth-in nëse nuk dëshiron që të qëndrojë i aktivizuar." + "Wi-Fi dhe Bluetooth-i qëndrojnë aktivë" + "Telefoni yt kujtohet që ta mbajë Wi-Fi dhe Bluetooth-in të aktivizuar në modalitetin e aeroplanit. Çaktivizo Wi-Fi dhe Bluetooth-in nëse nuk dëshiron që të qëndrojnë aktivë." diff --git a/android/app/res/values-sr/strings.xml b/android/app/res/values-sr/strings.xml index 6b125acb429..1ead9d5024b 100644 --- a/android/app/res/values-sr/strings.xml +++ b/android/app/res/values-sr/strings.xml @@ -23,6 +23,7 @@ "Bluetooth" "Непознати уређај" "Непознато" + "Није наведено" "Режим рада у авиону" "Не можете да користите Bluetooth у режиму рада у авиону." @@ -109,10 +110,8 @@ "Све ставке ће бити избрисане са листе." "Дељење преко Bluetooth-а: послате датотеке" "Дељење преко Bluetooth-а: примљене датотеке" - - - - + "{count,plural, =1{# неуспешно.}one{# неуспешно.}few{# неуспешна.}other{# неуспешних.}}" + "{count,plural, =1{# успешно, %1$s}one{# успешно, %1$s}few{# успешна, %1$s}other{# успешних, %1$s}}" "Обриши листу" "Отвори" "Обриши са листе" @@ -130,4 +129,10 @@ "Bluetooth аудио" "Не могу да се преносе датотеке веће од 4 GB" "Повежи са Bluetooth-ом" + "Bluetooth је укључен у режиму рада у авиону" + "Ако одлучите да не искључујете Bluetooth, телефон ће запамтити да га не искључује следећи пут када будете у режиму рада у авиону" + "Bluetooth се не искључује" + "Телефон памти да не треба да искључује Bluetooth у режиму рада у авиону. Искључите Bluetooth ако не желите да остане укључен." + "WiFi и Bluetooth остају укључени" + "Телефон памти да не треба да искључује WiFi и Bluetooth у режиму рада у авиону. Искључите WiFi и Bluetooth ако не желите да остану укључени." diff --git a/android/app/res/values-sv/strings.xml b/android/app/res/values-sv/strings.xml index dd29081413f..12678538125 100644 --- a/android/app/res/values-sv/strings.xml +++ b/android/app/res/values-sv/strings.xml @@ -23,6 +23,7 @@ "Bluetooth" "Okänd enhet" "Okänd" + "Inte angivet" "Flygplansläge" "Det går inte att använda Bluetooth i flygplansläge." @@ -109,10 +110,8 @@ "Alla objekt tas bort från listan." "Bluetooth-delning: skickade filer" "Bluetooth-delning: mottagna filer" - - - - + "{count,plural, =1{# misslyckades.}other{# misslyckades.}}" + "{count,plural, =1{# lyckades, %1$s}other{# lyckades, %1$s}}" "Rensa listan" "Öppna" "Ta bort från listan" @@ -130,4 +129,10 @@ "Bluetooth-ljud" "Det går inte att överföra filer som är större än 4 GB" "Anslut till Bluetooth" + "Håll Bluetooth aktiverat i flygplansläge" + "Om du håller wifi aktiverat kommer telefonen ihåg att hålla det aktiverat nästa gång du använder flygplansläge." + "Bluetooth förblir aktiverat" + "Telefonen kommer ihåg att hålla Bluetooth aktiverat i flygplansläge. Inaktivera Bluetooth om du inte vill att det ska hållas aktiverat." + "Wifi och Bluetooth ska vara aktiverade" + "Telefonen kommer ihåg att hålla wifi och Bluetooth aktiverade i flygplansläge. Du kan inaktivera wifi och Bluetooth om du inte vill hålla dem aktiverade." diff --git a/android/app/res/values-sw/strings.xml b/android/app/res/values-sw/strings.xml index 7fc3fc9d469..4ebf5cccfc2 100644 --- a/android/app/res/values-sw/strings.xml +++ b/android/app/res/values-sw/strings.xml @@ -23,6 +23,7 @@ "Bluetooth" "Kifaa kisichojulikana" "Haijulikani" + "Haijawekwa" "Hali ya ndegeni" "Huwezi kutumia Bluetooth kifaa kikiwa katika hali ya Ndegeni." @@ -37,7 +38,7 @@ "Sawa" "Muda ulikatika wakati wa kukubali faili inayoingia kutoka \"%1$s\"" "Faili Zinazoingia" - "%1$s ako tayari kutuma faili: %2$s" + "Faili kutoka %1$s iko tayari kutumwa: %2$s" "Kushiriki kwa bluetooth: Inapokea %1$s" "Kushiriki kwa bluetooth: Imepokea %1$s" "Kushiriki kwa Bluetooth: Faili %1$s haijapokewa" @@ -109,10 +110,8 @@ "Vipengee vyote vitafutwa kutoka kwenye orodha." "Kushiriki kwa bluetooth: Faili zilizotumwa" "Kushiriki kwa bluetooth: Faili zilizopokelewa" - - - - + "{count,plural, =1{# haijafanikiwa.}other{# hazijafanikiwa.}}" + "{count,plural, =1{# imefanikiwa, %1$s}other{# zimefanikiwa, %1$s}}" "Futa orodha" "Fungua" "Futa kutoka orodha" @@ -130,4 +129,10 @@ "Sauti ya Bluetooth" "Haiwezi kutuma faili zinazozidi GB 4" "Unganisha kwenye Bluetooth" + "Bluetooth itawashwa katika hali ya ndegeni" + "Usipozima Bluetooth, simu yako itakumbuka kuiwasha wakati mwingine unapokuwa katika hali ya ndegeni" + "Bluetooth itaendelea kuwaka" + "Simu yako itaendelea kuwasha Bluetooth katika hali ya ndegeni. Zima Bluetooth iwapo hutaki iendelee kuwaka." + "Wi-Fi na Bluetooth zitaendelea kuwaka" + "Simu yako itaendelea kuwasha Wi-Fi na Bluetooth ukiwa katika hali ya ndegeni. Zima Wi-Fi na Bluetooth ikiwa hutaki ziendelee kuwaka." diff --git a/android/app/res/values-ta/strings.xml b/android/app/res/values-ta/strings.xml index dd28c0f4ce1..ffd800cf343 100644 --- a/android/app/res/values-ta/strings.xml +++ b/android/app/res/values-ta/strings.xml @@ -23,6 +23,7 @@ "புளூடூத்" "அறியப்படாத சாதனம்" "அறியப்படாதது" + "வழங்கப்படவில்லை" "விமானப் பயன்முறை" "விமானப் பயன்முறையில் புளூடூத் ஐப் பயன்படுத்த முடியாது." @@ -109,10 +110,8 @@ "பட்டியலிலிருந்து அனைத்தும் அழிக்கப்படும்." "புளூடூத் பகிர்வு: அனுப்பியவை" "புளூடூத் பகிர்வு: பெற்ற ஃபைல்கள்" - - - - + "{count,plural, =1{# அனுப்பப்படவில்லை.}other{# அனுப்பப்படவில்லை.}}" + "{count,plural, =1{# அனுப்பப்பட்டது, %1$s}other{# அனுப்பப்பட்டன, %1$s}}" "பட்டியலை அழி" "திற" "பட்டியலிலிருந்து அழி" @@ -130,4 +129,10 @@ "புளூடூத் ஆடியோ" "4ஜி.பை.க்கு மேலிருக்கும் ஃபைல்களை இடமாற்ற முடியாது" "புளூடூத் உடன் இணை" + "விமானப் பயன்முறையில் புளூடூத்தை இயக்குதல்" + "புளூடூத்தை இயக்கத்தில் வைத்திருந்தால், அடுத்த முறை நீங்கள் விமானப் பயன்முறையைப் பயன்படுத்தும்போது உங்கள் மொபைல் புளூடூத்தை இயக்கத்தில் வைக்கும்" + "புளூடூத் இயக்கத்திலேயே இருக்கும்" + "விமானப் பயன்முறையில் புளூடூத்தை உங்கள் மொபைல் இயக்கத்திலேயே வைத்திருக்கும். புளூடூத்தை இயக்க விரும்பவில்லை என்றால் அதை முடக்கவும்." + "வைஃபையும் புளூடூத்தும் இயக்கத்திலேயே இருத்தல்" + "விமானப் பயன்முறையில் வைஃபையையும் புளூடூத்தையும் உங்கள் மொபைல் இயக்கத்திலேயே வைத்திருக்கும். வைஃபை மற்றும் புளூடூத்தை இயக்க விரும்பவில்லை என்றால் அவற்றை முடக்கவும்." diff --git a/android/app/res/values-te/strings.xml b/android/app/res/values-te/strings.xml index 57196ac0e29..fbe30065451 100644 --- a/android/app/res/values-te/strings.xml +++ b/android/app/res/values-te/strings.xml @@ -23,13 +23,14 @@ "బ్లూటూత్" "తెలియని పరికరం" "తెలియదు" - "ఎయిర్‌ప్లేన్ మోడ్" + "అందించబడలేదు" + "విమానం మోడ్" "మీరు ఎయిర్‌ప్లేన్ మోడ్‌లో బ్లూటూత్‌ను ఉపయోగించలేరు." "బ్లూటూత్ సేవలను ఉపయోగించడానికి, మీరు తప్పనిసరిగా ముందుగా బ్లూటూత్‌ను ప్రారంభించాలి." "ఇప్పుడే బ్లూటూత్‌ను ప్రారంభించాలా?" - "రద్దు చేయి" - "ప్రారంభించు" + "రద్దు చేయండి" + "ప్రారంభించండి" "ఫైల్ బదిలీ" "ఇన్‌కమింగ్ ఫైల్‌ను ఆమోదించాలా?" "తిరస్కరిస్తున్నాను" @@ -48,14 +49,14 @@ "ఫైల్ బదిలీ" "వీరి నుండి: \"%1$s\"" "ఫైల్: %1$s" - "ఫైల్ పరిమాణం: %1$s" + "ఫైల్ సైజ్‌: %1$s" "ఫైల్‌ను స్వీకరిస్తోంది…" "ఆపివేయి" "దాచు" "దీని నుండి" "ఫైల్ పేరు" - "పరిమాణం" + "సైజ్‌" "ఫైల్ స్వీకరించబడలేదు" "ఫైల్: %1$s" "కారణం: %1$s" @@ -69,15 +70,15 @@ "సరే" "ఫైల్ \"%1$s\"కి పంపబడలేదు." "ఫైల్: %1$s" - "మూసివేయి" + "మూసివేయండి" "సరే" "తెలియని ఫైల్" - "ఈ రకమైన ఫైల్‌ను నిర్వహించడానికి యాప్ ఏదీ లేదు. \n" + "ఈ రకమైన ఫైల్‌ను మేనేజ్ చేయడానికి యాప్ ఏదీ లేదు. \n" "ఫైల్ లేదు" "ఫైల్ ఉనికిలో లేదు. \n" "దయచేసి వేచి ఉండండి..." "బ్లూటూత్‌ను ప్రారంభిస్తోంది…" - "ఫైల్ స్వీకరించబడుతుంది. నోటిఫికేషన్‌ల ప్యానెల్‌లో ప్రోగ్రెస్‌ను తనిఖీ చేయండి." + "ఫైల్ స్వీకరించబడుతుంది. నోటిఫికేషన్‌ల ప్యానెల్‌లో ప్రోగ్రెస్‌ను చెక్ చేయండి." "ఫైల్ స్వీకరించబడలేదు." "\"%1$s\" పంపిన ఫైల్‌ను స్వీకరించడం ఆపివేయబడింది" "ఫైల్‌ను \"%1$s\"కి పంపుతోంది" @@ -93,8 +94,8 @@ "కంటెంట్‌కు మద్దతు లేదు." "లక్ష్య పరికరం బదిలీని నిషేధించింది." "వినియోగదారు బదిలీని రద్దు చేశారు." - "నిల్వ సమస్య." - "USB నిల్వ లేదు." + "స్టోరేజ్‌ సమస్య." + "USB స్టోరేజ్‌ లేదు." "SD కార్డు లేదు. బదిలీ చేయబడిన ఫైళ్లను సేవ్ చేయడానికి SD కార్డుని చొప్పించండి." "కనెక్షన్ విఫలమైంది." "రిక్వెస్ట్‌ సరిగ్గా నిర్వహించబడదు." @@ -109,17 +110,15 @@ "లిస్ట్‌ నుండి అన్ని అంశాలు క్లియర్ చేయబడతాయి." "బ్లూటూత్ షేర్: పంపిన ఫైళ్లు" "బ్లూటూత్ షేర్: స్వీకరించబడిన ఫైళ్లు" - - - - - "లిస్ట్‌ను క్లియర్ చేయి" + "{count,plural, =1{# విజయవంతం కాలేదు.}other{# విజయవంతం కాలేదు.}}" + "{count,plural, =1{# విజయవంతం అయింది, %1$s}other{# విజయవంతం అయింది, %1$s}}" + "లిస్ట్‌ను క్లియర్ చేయండి" "తెరువు" - "లిస్ట్‌ నుండి క్లియర్ చేయి" - "క్లియర్ చేయి" + "లిస్ట్‌ నుండి క్లియర్ చేయండి" + "క్లియర్ చేయండి" "ప్రస్తుతం ప్లే అవుతున్నవి" - "సేవ్ చేయి" - "రద్దు చేయి" + "సేవ్ చేయండి" + "రద్దు చేయండి" "మీరు బ్లూటూత్ ద్వారా షేర్ చేయాలనుకునే ఖాతాలను ఎంచుకోండి. మీరు ఇప్పటికీ కనెక్ట్ చేస్తున్నప్పుడు ఖాతాలకు అందించే ఏ యాక్సెస్‌నైనా ఆమోదించాల్సి ఉంటుంది." "మిగిలిన స్లాట్‌లు:" "యాప్‌ చిహ్నం" @@ -130,4 +129,10 @@ "బ్లూటూత్ ఆడియో" "4GB కన్నా పెద్ద ఫైళ్లు బదిలీ చేయబడవు" "బ్లూటూత్‌కు కనెక్ట్ చేయి" + "విమానం మోడ్‌లో బ్లూటూత్ ఆన్ చేయబడింది" + "మీరు బ్లూటూత్‌ను ఆన్‌లో ఉంచినట్లయితే, మీరు తదుపరిసారి విమానం మోడ్‌లో ఉన్నప్పుడు దాన్ని ఆన్‌లో ఉంచాలని మీ ఫోన్ గుర్తుంచుకుంటుంది" + "బ్లూటూత్ ఆన్‌లో ఉంటుంది" + "విమానం మోడ్‌లో బ్లూటూత్ ఆన్‌లో ఉంచాలని మీ ఫోన్ గుర్తుంచుకుంటుంది. బ్లూటూత్ ఆన్‌లో ఉండకూడదనుకుంటే దాన్ని ఆఫ్ చేయండి." + "Wi-Fi, బ్లూటూత్ ఆన్‌లో ఉంటాయి" + "మీ ఫోన్ విమానం మోడ్‌లో Wi‑Fiని, బ్లూటూత్‌ని ఆన్‌లో ఉంచాలని గుర్తుంచుకుంటుంది. Wi-Fi, బ్లూటూత్ ఆన్‌లో ఉండకూడదనుకుంటే వాటిని ఆఫ్ చేయండి." diff --git a/android/app/res/values-th/strings.xml b/android/app/res/values-th/strings.xml index e571562c0e1..91763b102a0 100644 --- a/android/app/res/values-th/strings.xml +++ b/android/app/res/values-th/strings.xml @@ -23,6 +23,7 @@ "บลูทูธ" "อุปกรณ์ที่ไม่รู้จัก" "ไม่รู้จัก" + "ไม่ได้ระบุ" "โหมดบนเครื่องบิน" "คุณไม่สามารถใช้บลูทูธในโหมดใช้งานบนเครื่องบินได้" @@ -109,10 +110,8 @@ "รายการทั้งหมดจะถูกล้างจากรายการ" "การแชร์ทางบลูทูธ: ส่งไฟล์แล้ว" "การแชร์ทางบลูทูธ: รับไฟล์แล้ว" - - - - + "{count,plural, =1{ไม่สำเร็จ # รายการ}other{ไม่สำเร็จ # รายการ}}" + "{count,plural, =1{สำเร็จ # รายการ, %1$s}other{สำเร็จ # รายการ, %1$s}}" "ล้างรายการ" "เปิด" "ล้างจากรายการ" @@ -130,4 +129,10 @@ "Bluetooth Audio" "โอนไฟล์ที่มีขนาดใหญ่กว่า 4 GB ไม่ได้" "เชื่อมต่อบลูทูธ" + "บลูทูธเปิดอยู่ในโหมดบนเครื่องบิน" + "หากเปิดบลูทูธไว้ โทรศัพท์จะจำว่าต้องเปิดบลูทูธในครั้งถัดไปที่คุณอยู่ในโหมดบนเครื่องบิน" + "บลูทูธเปิดอยู่" + "โทรศัพท์จำว่าจะต้องเปิดบลูทูธไว้ในโหมดบนเครื่องบิน ปิดบลูทูธหากคุณไม่ต้องการให้เปิดไว้" + "Wi-Fi และบลูทูธยังเปิดอยู่" + "โทรศัพท์จำว่าจะต้องเปิด Wi-Fi และบลูทูธไว้ในโหมดบนเครื่องบิน ปิด Wi-Fi และบลูทูธหากคุณไม่ต้องการให้เปิดไว้" diff --git a/android/app/res/values-tl/strings.xml b/android/app/res/values-tl/strings.xml index 86257d202f4..93c6a90be2f 100644 --- a/android/app/res/values-tl/strings.xml +++ b/android/app/res/values-tl/strings.xml @@ -23,6 +23,7 @@ "Bluetooth" "Hindi kilalang device" "Hindi alam" + "Hindi Ibinigay" "Airplane mode" "Hindi mo magagamit ang Bluetooth sa Airplane mode." @@ -41,7 +42,7 @@ "Pagbahagi sa Bluetooth: Tinatanggap ang %1$s" "Pagbahagi sa Bluetooth: Natanggap ang %1$s" "Pagbahagi sa Bluetooth: Hindi natanggap ang file na %1$s" - "Pagbahagi sa Bluetooth: Ipinapadala ang %1$s" + "Pagbabahagi sa Bluetooth: Ipinapadala ang %1$s" "Pagbahagi sa Bluetooth: Ipinadala ang %1$s" "100% kumpleto" "Pagbahagi sa Bluetooth: Hindi naipadala ang file na %1$s" @@ -108,11 +109,9 @@ "Walang laman ang history ng paglilipat." "Iki-clear ang lahat ng mga item mula sa listahan." "Bluetooth share: Mga naipadalang file" - "Bluetooth share: Mga natanggap na file" - - - - + "Pagbabahagi sa Bluetooth: Mga natanggap na file" + "{count,plural, =1{# ang hindi matagumpay.}one{# ang hindi matagumpay.}other{# ang hindi matagumpay.}}" + "{count,plural, =1{# ang matagumpay, %1$s}one{# ang matagumpay, %1$s}other{# ang matagumpay, %1$s}}" "I-clear ang listahan" "Buksan" "I-clear mula sa listahan" @@ -130,4 +129,10 @@ "Bluetooth Audio" "Hindi maililipat ang mga file na mas malaki sa 4GB" "Kumonekta sa Bluetooth" + "Naka-on ang Bluetooth sa airplane mode" + "Kung papanatilihin mong naka-on ang Bluetooth, tatandaan ng iyong telepono na panatilihin itong naka-on sa susunod na nasa airplane mode ka" + "Mananatiling naka-on ang Bluetooth" + "Tinatandaan ng iyong telepono na panatilihing naka-on ang Bluetooth habang nasa airplane mode. I-off ang Bluetooth kung ayaw mo itong manatiling naka-on." + "Mananatiling naka-on ang Wi-Fi at Bluetooth" + "Tinatandaan ng iyong telepono na panatilihing naka-on ang Wi-Fi at Bluetooth habang nasa airplane mode. I-off ang Wi-Fi at Bluetooth kung ayaw mong manatiling naka-on ang mga ito." diff --git a/android/app/res/values-tr/strings.xml b/android/app/res/values-tr/strings.xml index fd744100832..c1a650f337c 100644 --- a/android/app/res/values-tr/strings.xml +++ b/android/app/res/values-tr/strings.xml @@ -23,6 +23,7 @@ "Bluetooth" "Bilinmeyen cihaz" "Bilinmiyor" + "Belirtilmedi" "Uçak modu" "Uçak modunda Bluetooth\'u kullanamazsınız." @@ -109,10 +110,8 @@ "Tüm öğeler listeden temizlenecek." "Bluetooth paylaşımı: Gönderilen dosyalar" "Bluetooth paylaşımı: Dosyalar alındı" - - - - + "{count,plural, =1{# başarısız.}other{# başarısız.}}" + "{count,plural, =1{# başarılı, %1$s}other{# başarılı, %1$s}}" "Listeyi temizle" "Aç" "Listeden temizle" @@ -130,4 +129,10 @@ "Bluetooth Ses" "4 GB\'tan büyük dosyalar aktarılamaz" "Bluetooth\'a bağlan" + "Uçak modundayken Bluetooth açık" + "Kablosuz bağlantıyı açık tutarsanız telefonunuz, daha sonra tekrar uçak modunda olduğunuzda kablosuz bağlantıyı açık tutar" + "Bluetooth açık kalır" + "Telefonunuz, uçak modundayken Bluetooth\'u açık tutmayı hatırlar. Açık kalmasını istemiyorsanız Bluetooth\'u kapatın." + "Kablosuz bağlantı ve Bluetooth açık kalır" + "Telefonunuz, uçak modundayken kablosuz bağlantıyı ve Bluetooth\'u açık tutmayı hatırlar. Açık kalmasını istemiyorsanız kablosuz bağlantıyı ve Bluetooth\'u kapatın." diff --git a/android/app/res/values-uk/strings.xml b/android/app/res/values-uk/strings.xml index ba671525b27..348ae4c3adb 100644 --- a/android/app/res/values-uk/strings.xml +++ b/android/app/res/values-uk/strings.xml @@ -23,6 +23,7 @@ "Bluetooth" "Невідомий пристрій" "Невідомий" + "Не вказано" "Режим польоту" "Не можна викор. Bluetooth у режимі польоту." @@ -37,7 +38,7 @@ "OK" "Під час приймання вхідного файлу від \"%1$s\" виникла затримка" "Вхідний файл" - "%1$s може надіслати файл: %2$s" + "Пристрій %1$s готовий надіслати файл: %2$s" "Через Bluetooth: отримання %1$s" "Через Bluetooth: отримано %1$s" "Через Bluetooth: файл %1$s не отримано" @@ -109,10 +110,8 @@ "Зі списку буде видалено всі елементи." "Через Bluetooth: надісл. файли" "Через Bluetooth: отримані файли" - - - - + "{count,plural, =1{# не надіслано.}one{# не надіслано.}few{# не надіслано.}many{# не надіслано.}other{# не надіслано.}}" + "{count,plural, =1{# надіслано, %1$s}one{# надіслано, %1$s}few{# надіслано, %1$s}many{# надіслано, %1$s}other{# надіслано, %1$s}}" "Очистити список" "Відкрити" "Видалити зі списку" @@ -130,4 +129,10 @@ "Bluetooth Audio" "Не можна перенести файли, більші за 4 ГБ" "Підключитися до Bluetooth" + "Bluetooth увімкнено в режимі польоту" + "Якщо ви не вимкнете Bluetooth на телефоні, ця функція залишатиметься ввімкненою під час наступного використання режиму польоту" + "Bluetooth не буде вимкнено" + "У режимі польоту функція Bluetooth на телефоні залишатиметься ввімкненою. За бажання її можна вимкнути." + "Wi-Fi і Bluetooth залишаються ввімкненими" + "У режимі польоту функції Wi-Fi і Bluetooth на телефоні залишатимуться ввімкненими. За бажання їх можна вимкнути." diff --git a/android/app/res/values-ur/strings.xml b/android/app/res/values-ur/strings.xml index e8d26fffb97..c8d8480f46f 100644 --- a/android/app/res/values-ur/strings.xml +++ b/android/app/res/values-ur/strings.xml @@ -23,6 +23,7 @@ "بلوٹوتھ" "نامعلوم آلہ" "نامعلوم" + "فراہم نہیں کیا گیا" "ہوائی جہاز وضع" "آپ ہوائی جہاز وضع میں بلوٹوتھ استعمال نہیں کر سکتے ہیں۔" @@ -109,10 +110,8 @@ "سبھی آئٹمز فہرست سے صاف کر دیے جائیں گے۔" "بلوٹوتھ اشتراک: ارسال کردہ فائلیں" "بلوٹوتھ اشتراک: فائلیں موصول ہو گئیں" - - - - + "{count,plural, =1{# ناکام۔}other{# ناکام۔}}" + "{count,plural, =1{‏# کامیاب، ‎%1$s‎}other{‏# کامیاب، ‎%1$s‎}}" "فہرست صاف کریں" "کھولیں" "فہرست سے صاف کریں" @@ -130,4 +129,10 @@ "بلوٹوتھ آڈیو" "‏4GB سے بڑی فائلیں منتقل نہیں کی جا سکتیں" "بلوٹوتھ سے منسلک کریں" + "ہوائی جہاز وضع میں بلوٹوتھ آن ہے" + "اگر آپ بلوٹوتھ کو آن رکھتے ہیں تو آپ کا فون آپ کے اگلی مرتبہ ہوائی جہاز وضع میں ہونے پر اسے آن رکھنا یاد رکھے گا" + "بلوٹوتھ آن رہتا ہے" + "آپ کا فون ہوائی جہاز وضع میں بلوٹوتھ کو آن رکھنا یاد رکھتا ہے۔ اگر آپ نہیں چاہتے ہیں کہ بلوٹوتھ آن رہے تو اسے آف کریں۔" + "‏Wi-Fi اور بلوٹوتھ آن رہنے دیں" + "‏آپ کا فون ہوائی جہاز وضع میں Wi-Fi اور بلوٹوتھ کو آن رکھنا یاد رکھتا ہے۔ اگر آپ نہیں چاہتے ہیں کہ Wi-Fi اور بلوٹوتھ آن رہیں تو انہیں آف کریں۔" diff --git a/android/app/res/values-uz/strings.xml b/android/app/res/values-uz/strings.xml index e2b77cc4f97..f0f22bd7ac3 100644 --- a/android/app/res/values-uz/strings.xml +++ b/android/app/res/values-uz/strings.xml @@ -23,6 +23,7 @@ "Bluetooth" "Noma’lum qurilma" "Noma’lum" + "Kiritilmagan" "Parvoz rejimi" "Bluetooth’dan \"Parvoz rejimi\"da foydalana olmaysiz." @@ -109,10 +110,8 @@ "Barcha qaydlar ro‘yxatdan o‘chirib tashlanadi." "Bluetooth orqali yuborildi" "Bluetooth orqali olindi" - - - - + "{count,plural, =1{# ta bajarilmadi.}other{# ta bajarilmadi.}}" + "{count,plural, =1{# ta yuborildi, %1$s}other{# ta yuborildi, %1$s}}" "Ro‘yxatni tozalash" "Ochish" "Ro‘yxatdan o‘chirish" @@ -130,4 +129,10 @@ "Bluetooth orqali ovoz" "4 GBdan katta hajmli videolar o‘tkazilmaydi" "Bluetoothga ulanish" + "Bluetooth parvoz rejimida yoniq" + "Bluetooth yoniq qolsa, telefon keyingi safar parvoz rejimida ham uni yoniq qoldiradi." + "Bluetooth yoniq turadi" + "Telefoningiz parvoz rejimida Bluetooth yoqilganini eslab qoladi. Yoniq qolmasligi uchun Bluetooth aloqasini oʻchiring." + "Wi-Fi va Bluetooth yoniq qoladi" + "Telefoningiz parvoz rejimida Wi‑Fi va Bluetooth yoqilganini eslab qoladi. Yoniq qolmasligi uchun Wi-Fi va Bluetooth aloqasini oʻchiring." diff --git a/android/app/res/values-vi/strings.xml b/android/app/res/values-vi/strings.xml index 1816c9d631a..55ceb7c126a 100644 --- a/android/app/res/values-vi/strings.xml +++ b/android/app/res/values-vi/strings.xml @@ -23,6 +23,7 @@ "Bluetooth" "Thiết bị không xác định" "Không xác định" + "Chưa cung cấp" "Chế độ trên máy bay" "Bạn không thể sử dụng Bluetooth trong chế độ trên máy bay." @@ -108,11 +109,9 @@ "Nhật ký truyền hiện đang trống." "Tất cả các mục sẽ bị xóa khỏi danh sách." "Chia sẻ qua Bluetooth: Tệp đã gửi" - "Chia sẻ qua Bluetooth: Tệp đã nhận" - - - - + "Chia sẻ qua Bluetooth: Đã nhận tệp" + "{count,plural, =1{# không thành công.}other{# không thành công.}}" + "{count,plural, =1{# thành công, %1$s}other{# thành công, %1$s}}" "Xóa danh sách" "Mở" "Xóa khỏi danh sách" @@ -130,4 +129,10 @@ "Âm thanh Bluetooth" "Không thể chuyển những tệp lớn hơn 4 GB" "Kết nối với Bluetooth" + "Bluetooth đang bật ở chế độ trên máy bay" + "Nếu bạn không tắt Bluetooth, điện thoại sẽ luôn bật Bluetooth vào lần tiếp theo bạn dùng chế độ trên máy bay" + "Bluetooth luôn bật" + "Điện thoại của bạn sẽ luôn bật Bluetooth ở chế độ trên máy bay. Nếu không muốn như vậy thì bạn có thể tắt Bluetooth." + "Wi-Fi và Bluetooth vẫn đang bật" + "Điện thoại của bạn sẽ luôn bật Wi-Fi và Bluetooth ở chế độ trên máy bay. Tắt Wi-Fi và Bluetooth nếu bạn không muốn tiếp tục bật." diff --git a/android/app/res/values-zh-rCN/strings.xml b/android/app/res/values-zh-rCN/strings.xml index ec33eb459da..05bc8d23ad5 100644 --- a/android/app/res/values-zh-rCN/strings.xml +++ b/android/app/res/values-zh-rCN/strings.xml @@ -23,6 +23,7 @@ "蓝牙" "未知设备" "未知号码" + "未提供" "飞行模式" "飞行模式中不能使用蓝牙。" @@ -37,7 +38,7 @@ "确定" "接受来自“%1$s”的文件时发生超时" "有人发送文件给您" - "“%1$s”已做好发送以下文件的准备:%2$s" + "“%1$s”准备发送以下文件:%2$s" "蓝牙共享:正在接收“%1$s”" "蓝牙共享:已接收“%1$s”" "蓝牙共享:未收到文件“%1$s”" @@ -109,10 +110,8 @@ "所有内容都将从列表中清除。" "蓝牙共享:已发送文件" "蓝牙共享:已接收文件" - - - - + "{count,plural, =1{# 个文件传输失败。}other{# 个文件传输失败。}}" + "{count,plural, =1{# 个文件传输成功,%1$s}other{# 个文件传输成功,%1$s}}" "清除列表" "打开" "从列表中清除" @@ -130,4 +129,10 @@ "蓝牙音频" "无法传输 4GB 以上的文件" "连接到蓝牙" + "在飞行模式下蓝牙保持开启状态" + "如果您不关闭蓝牙,那么您下次进入飞行模式时手机将记住保持开启蓝牙" + "蓝牙保持开启状态" + "在飞行模式下手机将记住保持开启蓝牙。如果您不想保持开启和蓝牙,请关闭蓝牙。" + "WLAN 和蓝牙保持开启状态" + "在飞行模式下手机将记住保持开启 WLAN 和蓝牙。如果您不想保持开启 WLAN 和蓝牙,请关闭 WLAN 和蓝牙。" diff --git a/android/app/res/values-zh-rHK/strings.xml b/android/app/res/values-zh-rHK/strings.xml index b9b8c874662..4ae1ceedeaa 100644 --- a/android/app/res/values-zh-rHK/strings.xml +++ b/android/app/res/values-zh-rHK/strings.xml @@ -23,6 +23,7 @@ "藍牙" "不明裝置" "未知" + "未提供" "飛行模式" "裝置處於飛行模式時,無法使用藍牙功能。" @@ -109,10 +110,8 @@ "將會從清單清除所有項目。" "藍牙分享:傳送的檔案" "藍牙分享:接收的檔案" - - - - + "{count,plural, =1{# 個失敗。}other{# 個失敗。}}" + "{count,plural, =1{成功傳送 # 個檔案,%1$s}other{成功傳送 # 個檔案,%1$s}}" "清除清單" "開啟" "從清單清除" @@ -120,7 +119,7 @@ "歌曲識別" "儲存" "取消" - "選取您要透過藍牙分享的帳戶。連線時,您仍然必須接受所有帳戶存取要求。" + "選取你要透過藍牙分享的帳戶。連線時,你仍然必須接受所有帳戶存取要求。" "剩餘插槽數:" "應用程式圖示" "藍牙訊息分享設定" @@ -130,4 +129,10 @@ "藍牙音訊" "無法轉移 4 GB 以上的檔案" "連接藍牙" + "在飛航模式中保持藍牙開啟" + "如果你不關閉藍牙,下次手機進入飛行模式時,藍牙將保持開啟" + "保持藍牙連線" + "手機會記得在飛行模式下保持藍牙開啟。如果你不希望保持開啟,請關閉藍牙。" + "Wi-Fi 和藍牙保持開啟" + "手機會記得在飛行模式下保持 Wi-Fi 及藍牙開啟。如果你不希望保持開啟,請關閉 Wi-Fi 及藍牙。" diff --git a/android/app/res/values-zh-rTW/strings.xml b/android/app/res/values-zh-rTW/strings.xml index 38f15a3e4d6..9626544969d 100644 --- a/android/app/res/values-zh-rTW/strings.xml +++ b/android/app/res/values-zh-rTW/strings.xml @@ -23,6 +23,7 @@ "藍牙" "未知的裝置" "不明" + "未提供" "飛行模式" "手機處於飛行模式時,無法使用藍牙功能。" @@ -109,10 +110,8 @@ "所有項目都會從清單中清除。" "藍牙分享:傳送的檔案" "藍牙分享:接收的檔案" - - - - + "{count,plural, =1{# 個失敗。}other{# 個失敗。}}" + "{count,plural, =1{# 個檔案成功,%1$s}other{# 個檔案成功,%1$s}}" "清除清單" "開啟" "從清單清除" @@ -130,4 +129,10 @@ "藍牙音訊" "無法轉移大於 4GB 的檔案" "使用藍牙連線" + "在飛航模式下保持藍牙開啟狀態" + "如果不關閉藍牙,下次手機進入飛航模式時,藍牙將保持開啟" + "藍牙會保持開啟狀態" + "手機會記得在飛航模式下保持藍牙開啟。如果不要保持開啟,請關閉藍牙。" + "Wi-Fi 和藍牙會保持開啟狀態" + "手機會記得在飛航模式下保持 Wi-Fi 和藍牙開啟。如果不要保持開啟,請關閉 Wi-Fi 和藍牙。" diff --git a/android/app/res/values-zu/strings.xml b/android/app/res/values-zu/strings.xml index b060e0c0900..3d6d007846f 100644 --- a/android/app/res/values-zu/strings.xml +++ b/android/app/res/values-zu/strings.xml @@ -23,6 +23,7 @@ "Bluetooth" "Idivayisi engaziwa" "Akwaziwa" + "Akunikeziwe" "Imodi yendiza" "Awukwazi ukusebenzisa i-Bluetooth kwimodi yeNdiza." @@ -109,10 +110,8 @@ "Zonke izintwana zizosulwa ohlwini." "Abelana ne-Bluetooth. Amafayela athunyelwe" "Abelana ne-Bluetooth: Amafayela atholakele" - - - - + "{count,plural, =1{okungaphumelele #}one{okungaphumelele #}other{okungaphumelele #}}" + "{count,plural, =1{okuphumelele #, %1$s}one{okuphumelele #, %1$s}other{okuphumelele #, %1$s}}" "Sula uhlu" "Vula" "Sula ohlwini" @@ -130,4 +129,10 @@ "Umsindo we-Bluetooth" "Amafayela amakhulu kuno-4GB awakwazi ukudluliselwa" "Xhumeka ku-Bluetooth" + "I-Bluetooth ivuliwe kumodi yendiza" + "Uma ugcina i-Wi‑Fi ivuliwe, ifoni yakho izokhumbula ukuyigcina ivuliwe ngesikhathi esilandelayo uma ukumodi yendiza." + "I-Bluetooth ihlala ivuliwe" + "Ifoni yakho ikhumbula ukugcina i-Bluetooth ivuliwe kumodi yendiza. Vala i-Bluetooth uma ungafuni ukuthi ihlale ivuliwe." + "I-Wi-Fi ne-Bluetooth kuhlala kuvuliwe" + "Ifoni yakho ikhumbula ukugcina i-Wi-Fi ne-Bluetooth kuvuliwe kumodi yendiza. Vala i-Wi-Fi ne-Bluetooth uma ungafuni ukuthi ihlale ivuliwe." -- GitLab From a88631bd3213912c3453f6937ed6a34630e486cc Mon Sep 17 00:00:00 2001 From: Bill Yi Date: Sat, 22 Apr 2023 00:14:54 -0700 Subject: [PATCH 0026/2405] Import translations. DO NOT MERGE ANYWHERE Auto-generated-cl: translation import Change-Id: I861c9e04ec93e25781092b90f6f7ee3b2657385f --- android/app/res/values-eu/test_strings.xml | 2 +- android/app/res/values-or/test_strings.xml | 2 +- android/app/res/values-ro/test_strings.xml | 12 ++++++------ 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/android/app/res/values-eu/test_strings.xml b/android/app/res/values-eu/test_strings.xml index e6016491941..4c501ab19e1 100644 --- a/android/app/res/values-eu/test_strings.xml +++ b/android/app/res/values-eu/test_strings.xml @@ -1,7 +1,7 @@ - "Bluetooth-a" + "Bluetootha" "Sartu erregistroa" "Berretsi erregistroa" "ACK erregistroa" diff --git a/android/app/res/values-or/test_strings.xml b/android/app/res/values-or/test_strings.xml index fd2571f2c41..1849219b2ce 100644 --- a/android/app/res/values-or/test_strings.xml +++ b/android/app/res/values-or/test_strings.xml @@ -6,7 +6,7 @@ "ରେକର୍ଡ ସୁନିଶ୍ଚିତ କରନ୍ତୁ" "ରେକର୍ଡ ସ୍ୱୀକୃତ କରନ୍ତୁ" "ସମସ୍ତ ରେକର୍ଡ ଡିଲିଟ୍‌ କରନ୍ତୁ" - "ଠିକ୍‌ ଅଛି" + "ଠିକ ଅଛି" "ରେକର୍ଡ ଡିଲିଟ୍‌ କରନ୍ତୁ" "TCP ସର୍ଭର୍‌ ଆରମ୍ଭ କରନ୍ତୁ" "TCP ସର୍ଭର୍‌କୁ ସୂଚିତ କରନ୍ତୁ" diff --git a/android/app/res/values-ro/test_strings.xml b/android/app/res/values-ro/test_strings.xml index 84190c2ba9c..c2393c5fb0a 100644 --- a/android/app/res/values-ro/test_strings.xml +++ b/android/app/res/values-ro/test_strings.xml @@ -2,12 +2,12 @@ "Bluetooth" - "Inserați o înregistrare" - "Confirmați înregistrarea" + "Inserează o înregistrare" + "Confirmă înregistrarea" "Înregistrare Ack" - "Ștergeți toate înregistrările" + "Șterge toate înregistrările" "OK" - "Ștergeți înregistrarea" - "Porniți serverul TCP" - "Notificați serverul TCP" + "Șterge înregistrarea" + "Pornește serverul TCP" + "Notifică serverul TCP" -- GitLab From 4750a093e6d982817ffaa5730c8ef1527aad7d12 Mon Sep 17 00:00:00 2001 From: Abhishek Pandit-Subedi Date: Mon, 1 May 2023 11:23:45 -0700 Subject: [PATCH 0027/2405] floss: Fixup build issues Bug: 280317096 Tag: #floss Test: ./build.py Ignore-AOSP-First: Fixing error in stage-aosp-master Change-Id: I188fe340fc0da3084bc86ae2939a7a06d3b5bff9 --- system/btcore/BUILD.gn | 1 + system/btif/BUILD.gn | 1 - 2 files changed, 1 insertion(+), 1 deletion(-) diff --git a/system/btcore/BUILD.gn b/system/btcore/BUILD.gn index f483de0af92..a80741651b7 100644 --- a/system/btcore/BUILD.gn +++ b/system/btcore/BUILD.gn @@ -17,6 +17,7 @@ static_library("btcore") { sources = [ "src/device_class.cc", + "src/hal_util.cc", "src/module.cc", "src/osi_module.cc", "src/property.cc", diff --git a/system/btif/BUILD.gn b/system/btif/BUILD.gn index 1d6673bfa8e..7fb9cd9d59c 100644 --- a/system/btif/BUILD.gn +++ b/system/btif/BUILD.gn @@ -91,7 +91,6 @@ static_library("btif") { "src/btif_storage.cc", "src/btif_uid.cc", "src/btif_util.cc", - "src/profile_log_levels.cc", "src/stack_manager.cc", ] -- GitLab From 6412665b695044453562df8f94630634bc6e3ba0 Mon Sep 17 00:00:00 2001 From: Xuan Xing Date: Tue, 18 Apr 2023 21:31:09 +0000 Subject: [PATCH 0028/2405] Adding more bluetooth stack fuzzers. This change adds fuzzers for the following stack components: * SMP * GATT * BNEP * AVRC/AVCT * L2CAP Bug: 277109918 Ignore-AOSP-First: Internal fuzzers Test: Manually build and test Change-Id: Ie624b4cbc8ac960d908ab62663d5a5dd5d5a8b63 --- system/stack/Android.bp | 208 ++++++++++++++++++ system/stack/fuzzers/README.md | 95 +++++++++ system/stack/fuzzers/avrc_fuzzer.cc | 220 +++++++++++++++++++ system/stack/fuzzers/bnep_fuzzer.cc | 173 +++++++++++++++ system/stack/fuzzers/gatt_fuzzer.cc | 304 +++++++++++++++++++++++++++ system/stack/fuzzers/l2cap_fuzzer.cc | 253 ++++++++++++++++++++++ system/stack/fuzzers/smp_fuzzer.cc | 237 +++++++++++++++++++++ 7 files changed, 1490 insertions(+) create mode 100644 system/stack/fuzzers/README.md create mode 100644 system/stack/fuzzers/avrc_fuzzer.cc create mode 100644 system/stack/fuzzers/bnep_fuzzer.cc create mode 100644 system/stack/fuzzers/gatt_fuzzer.cc create mode 100644 system/stack/fuzzers/l2cap_fuzzer.cc create mode 100644 system/stack/fuzzers/smp_fuzzer.cc diff --git a/system/stack/Android.bp b/system/stack/Android.bp index fdd677cca4c..922a80b28b1 100644 --- a/system/stack/Android.bp +++ b/system/stack/Android.bp @@ -335,6 +335,9 @@ cc_defaults { "close_fd_mask=3", // This limits the maximum corpus size to 4KB "max_len=4096", + // TODO: b/280300628 for fixing memory leaks. Until it's fixed leak + // detection needs to be turned off to unblock fuzzing. + "detect_leaks=0", ], cc: [ "android-bluetooth-security@google.com", @@ -376,6 +379,211 @@ cc_fuzz { ], } +cc_fuzz { + name: "gatt-fuzzer", + defaults: [ + "btstack_fuzzer_default", + "fluoride_defaults_fuzzable", + ], + include_dirs: [ + "packages/modules/Bluetooth/system/stack/btm", + "external/flatbuffers/include", + "external/rust/crates/quiche/deps/boringssl/src/include", + ], + generated_headers: [ + "BluetoothGeneratedDumpsysDataSchema_h", + "BluetoothGeneratedPackets_h", + ], + srcs: crypto_toolbox_srcs + [ + "gatt/*.cc", + "eatt/*.cc", + ":TestCommonLogMsg", + ":TestCommonMockFunctions", + ":TestCommonStackConfig", + ":TestFakeOsi", + ":TestMockBtif", + ":TestMockDevice", + ":TestMockGdOsLoggingLogRedaction", + ":TestMockSrvcDis", + ":TestMockStackL2cap", + ":TestMockStackMetrics", + ":TestMockStackBtm", + ":TestMockStackAcl", + ":TestMockStackHcic", + ":TestMockMainShim", + ":TestMockStackSdp", + ":TestMockStackArbiter", + ":TestMockRustFfi", + "fuzzers/gatt_fuzzer.cc", + ], + static_libs: [ + "libgmock", + ], +} + +cc_fuzz { + name: "smp-fuzzer", + defaults: [ + "btstack_fuzzer_default", + "fluoride_defaults_fuzzable", + ], + include_dirs: [ + "packages/modules/Bluetooth/system/stack/btm", + "external/flatbuffers/include", + "external/rust/crates/quiche/deps/boringssl/src/include", + ], + generated_headers: [ + "BluetoothGeneratedDumpsysDataSchema_h", + "BluetoothGeneratedPackets_h", + ], + srcs: crypto_toolbox_srcs + [ + "smp/smp_*.cc", + ":TestCommonLogMsg", + ":TestCommonMockFunctions", + ":TestCommonStackConfig", + ":TestFakeOsi", + ":TestMockBtif", + ":TestMockDevice", + ":TestMockGdOsLoggingLogRedaction", + ":TestMockStackL2cap", + ":TestMockStackMetrics", + ":TestMockStackBtm", + ":TestMockStackAcl", + ":TestMockStackHcic", + ":TestMockMainShim", + "fuzzers/smp_fuzzer.cc", + ], + static_libs: [ + "libgmock", + ], +} + +cc_fuzz { + name: "bnep-fuzzer", + defaults: [ + "btstack_fuzzer_default", + "fluoride_defaults_fuzzable", + ], + include_dirs: [ + "packages/modules/Bluetooth/system/stack/btm", + "external/flatbuffers/include", + "external/rust/crates/quiche/deps/boringssl/src/include", + ], + generated_headers: [ + "BluetoothGeneratedDumpsysDataSchema_h", + "BluetoothGeneratedPackets_h", + ], + srcs: [ + "bnep/*.cc", + ":TestCommonLogMsg", + ":TestCommonMockFunctions", + ":TestCommonStackConfig", + ":TestFakeOsi", + ":TestMockBtif", + ":TestMockDevice", + ":TestMockGdOsLoggingLogRedaction", + ":TestMockStackL2cap", + ":TestMockStackMetrics", + ":TestMockStackBtm", + ":TestMockStackAcl", + ":TestMockStackHcic", + ":TestMockMainShim", + "fuzzers/bnep_fuzzer.cc", + ], + static_libs: [ + "libgmock", + ], +} + +cc_fuzz { + name: "avrc-fuzzer", + defaults: [ + "btstack_fuzzer_default", + "fluoride_defaults_fuzzable", + ], + include_dirs: [ + "packages/modules/Bluetooth/system/stack/btm", + "external/flatbuffers/include", + "external/rust/crates/quiche/deps/boringssl/src/include", + ], + generated_headers: [ + "BluetoothGeneratedDumpsysDataSchema_h", + "BluetoothGeneratedPackets_h", + ], + srcs: [ + "avrc/*.cc", + "avct/*.cc", + ":TestCommonLogMsg", + ":TestCommonMockFunctions", + ":TestCommonStackConfig", + ":TestFakeOsi", + ":TestMockBtif", + ":TestMockDevice", + ":TestMockGdOsLoggingLogRedaction", + ":TestMockStackL2cap", + ":TestMockStackMetrics", + ":TestMockStackBtm", + ":TestMockStackAcl", + ":TestMockStackHcic", + ":TestMockMainShim", + ":TestMockStackSdp", + "fuzzers/avrc_fuzzer.cc", + ], + static_libs: [ + "libgmock", + ], + target: { + android: { + static_libs: [ + "libcom.android.sysprop.bluetooth", + ], + }, + }, +} + +cc_fuzz { + name: "l2cap-fuzzer", + defaults: [ + "btstack_fuzzer_default", + "fluoride_defaults_fuzzable", + ], + include_dirs: [ + "packages/modules/Bluetooth/system/stack/btm", + "external/flatbuffers/include", + "external/rust/crates/quiche/deps/boringssl/src/include", + ], + generated_headers: [ + "BluetoothGeneratedDumpsysDataSchema_h", + "BluetoothGeneratedPackets_h", + ], + srcs: [ + "l2cap/*.cc", + ":TestCommonLogMsg", + ":TestCommonMockFunctions", + ":TestCommonStackConfig", + ":TestFakeOsi", + ":TestMockBtif", + ":TestMockDevice", + ":TestMockGdOsLoggingLogRedaction", + ":TestMockStackMetrics", + ":TestMockStackBtm", + ":TestMockStackAcl", + ":TestMockStackHcic", + ":TestMockMainShim", + "fuzzers/l2cap_fuzzer.cc", + ], + static_libs: [ + "libgmock", + ], + target: { + android: { + shared_libs: [ + "libPlatformProperties", + ], + }, + }, +} + // Bluetooth stack unit tests for target cc_test { name: "net_test_stack", diff --git a/system/stack/fuzzers/README.md b/system/stack/fuzzers/README.md new file mode 100644 index 00000000000..35a33835ef3 --- /dev/null +++ b/system/stack/fuzzers/README.md @@ -0,0 +1,95 @@ +# Bluetooth Stack Fuzzers + +## Overview +Bluetooth stack implements very complex wireless communication protocols and +scenarios. It's been a hotspot for security researchers and attackers. Fuzzing +has been used as a popular approach to look for security vulnerabilities in +Bluetooth stack. + +Due to the complex architecture of the Android Bluetooth stack, fuzzing the +entire stack with pure software is very difficult and impractical. Instead, +multiple fuzzers are created to target different areas of the BT stack. Fuzzers +in this directory focuses on the components under `system/stack`. + +## Attack surface selection +For security purpose, remote attack surfaces usually take higher priority since +they can cause much severe damage comparing to local attacks. This makes the +incoming BT message handlers our focus. The goal is to be able to pipe randomly +generated data packets to those message handlers to explore the code path each +component contains. This helps flushing out any memory/logic issues in the +remote message handling routine. + +Components requiring no authentication, or dealing with messages before +authentication have a higher fuzzing priority. This includes the SDP, GATT, SMP +and L2CAP components. A couple post authentication components such as BNEP, +AVRC, AVCT are also covered by different fuzzers. + +## Bluetooth stack overview +According to Bluetooth spec and the source code, most of the components we care +here work above the L2CAP layer. In general they work with the following +sequences: +1. At initialization, a component registers itself to L2CAP with a set of +callback functions, which, usually contains at least one function handling the +incoming Bluetooth packets. +2. Each component also exposes certain APIs to upper layers, which can be higher +level Bluetooth framework, or even applications. Bluetooth framework or +applications use these APIs to configure the stack, and issue requests. +3. Upper layer also registers callbacks into each component. When a component +receives a response, it parses and validates the response, extracts the payload +data, and passes data to upper layer using those callbacks. +4. Many Bluetooth components work in both server mode and client mode with +different sets of APIs and processing logics. +5. It's common for a Bluetooth stack component to use state machines. The state +transition happens when APIs are called, or incoming packets are handled. + +## Fuzzer design +The fuzzers are designed to simulate how a component is used in the real world, +but with a lot of simplifications. Here is how they work in general: +1. First a fuzzer should mock the L2CAP APIs to capture the registration call +from the target component. +2. At each fuzzing iteration, the fuzzer initializes the target component using +its initialization function. This will cause the component to register itself to +L2CAP. Because L2CAP APIs are mocked, the fuzzer will capture the registration +information, most importantly, the message handler callback function. +3. The fuzzer then calls necessary APIs and callbacks exposed to L2CAP to +further initialize the target component into either server mode or client mode. +4. Starting from here, the fuzzer splits the input data into multiple packets, +and feeds them to the target component using the previously captured message +handler callback. +5. It's common that a fuzzer also needs to call certain APIs to trigger state +transition of the target component. The fuzzer might use fixed data or data +derived from fuzzing input to make those API calls. +6. Once all the data is consumed, the target is cleaned up so next iteration can +start cleanly. It's important to cleanup all the data so there is no state +pollution between two iterations, otherwise it will be very difficult to +reproduce a crash. + +## Mocking dependencies +For maximium fuzzing efficiency, the fuzzers are created to include the target +component and minimium number of other Bluetooth components. This means any +dependencies from other Bluetooth components need to be mocked. The mocks are +implemented with a balance of reaching maximium target code coverage and +minimium development effort. Some of the mocks are simply not implemented. + +## Future improvement +These fuzzers are still far from perfect, with the following possible +improvements: +1. Code coverage + + It's very important to review the code coverage of each fuzzer. Any big + coverage gaps should be analyzed and improved. This can be done by adding + additional logic in the fuzzing loop, such as calling certain APIs, + providing upper layer callbacks, or changing the mock behaviors. + +2. Performance + + The fuzzers are designed to run as fast as possible. But there might still + be some room to improve the performance. Profiling can be done to figure + out the performance bottlenecks, which might be sleeps, tight for loops, or + computational heavy operations, such as crypto functions. + +3. Component coverage + + Currently only 3 fuzzers are created. More should be added so we can cover + most of the stack components. With the mocks and design patterns it + shouldn't be too difficult. diff --git a/system/stack/fuzzers/avrc_fuzzer.cc b/system/stack/fuzzers/avrc_fuzzer.cc new file mode 100644 index 00000000000..cb45f482603 --- /dev/null +++ b/system/stack/fuzzers/avrc_fuzzer.cc @@ -0,0 +1,220 @@ +/* + * Copyright 2022 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include + +#include +#include +#include +#include + +#include "osi/include/allocator.h" +#include "stack/include/avct_api.h" +#include "stack/include/avrc_api.h" +#include "test/fake/fake_osi.h" +#include "test/mock/mock_btif_config.h" +#include "test/mock/mock_stack_acl.h" +#include "test/mock/mock_stack_btm_dev.h" +#include "test/mock/mock_stack_l2cap_api.h" +#include "test/mock/mock_stack_l2cap_ble.h" +#include "types/bluetooth/uuid.h" + +using bluetooth::Uuid; + +// Verify the passed data is readable +static void ConsumeData(const uint8_t* data, size_t size) { + volatile uint8_t checksum = 0; + for (size_t i = 0; i < size; i++) { + checksum ^= data[i]; + } +} + +namespace { + +constexpr uint16_t kDummyCid = 0x1234; +constexpr uint8_t kDummyId = 0x77; +constexpr uint8_t kDummyRemoteAddr[] = {0x77, 0x88, 0x99, 0xAA, 0xBB, 0xCC}; + +// Set up default callback structure +static tL2CAP_APPL_INFO avct_appl, avct_br_appl; + +class FakeBtStack { + public: + FakeBtStack() { + test::mock::stack_l2cap_api::L2CA_DataWrite.body = [](uint16_t cid, + BT_HDR* hdr) { + CHECK(cid == kDummyCid); + ConsumeData((const uint8_t*)hdr, hdr->offset + hdr->len); + osi_free(hdr); + return L2CAP_DW_SUCCESS; + }; + test::mock::stack_l2cap_api::L2CA_DisconnectReq.body = [](uint16_t cid) { + CHECK(cid == kDummyCid); + return true; + }; + test::mock::stack_l2cap_api::L2CA_ConnectReq2.body = + [](uint16_t psm, const RawAddress& p_bd_addr, uint16_t sec_level) { + CHECK(p_bd_addr == kDummyRemoteAddr); + return kDummyCid; + }; + test::mock::stack_l2cap_api::L2CA_Register2.body = + [](uint16_t psm, const tL2CAP_APPL_INFO& p_cb_info, bool enable_snoop, + tL2CAP_ERTM_INFO* p_ertm_info, uint16_t my_mtu, + uint16_t required_remote_mtu, uint16_t sec_level) { + CHECK(psm == AVCT_PSM || psm == AVCT_BR_PSM); + if (psm == AVCT_PSM) { + avct_appl = p_cb_info; + } else if (psm == AVCT_BR_PSM) { + avct_br_appl = p_cb_info; + } + return psm; + }; + test::mock::stack_l2cap_api::L2CA_Deregister.body = [](uint16_t psm) {}; + } + + ~FakeBtStack() { + test::mock::stack_l2cap_api::L2CA_DataWrite = {}; + test::mock::stack_l2cap_api::L2CA_ConnectReq2 = {}; + test::mock::stack_l2cap_api::L2CA_DisconnectReq = {}; + test::mock::stack_l2cap_api::L2CA_Register2 = {}; + test::mock::stack_l2cap_api::L2CA_Deregister = {}; + } +}; + +class Fakes { + public: + test::fake::FakeOsi fake_osi; + FakeBtStack fake_stack; +}; + +} // namespace + +#ifdef OS_ANDROID +namespace android { +namespace sysprop { +namespace bluetooth { +namespace Avrcp { +std::optional absolute_volume() { return true; } +} // namespace Avrcp + +namespace Bta { +std::optional disable_delay() { return 200; } +} // namespace Bta + +namespace Pan { +std::optional nap() { return false; } +} // namespace Pan +} // namespace bluetooth +} // namespace sysprop +} // namespace android +#endif + +static void ctrl_cb(uint8_t handle, uint8_t event, uint16_t result, + const RawAddress* peer_addr) {} + +static void msg_cb(uint8_t handle, uint8_t label, uint8_t opcode, + tAVRC_MSG* p_msg) { + uint8_t scratch_buf[512]; + tAVRC_STS status; + + if (p_msg->hdr.ctype == AVCT_CMD) { + tAVRC_COMMAND cmd = {0}; + memset(scratch_buf, 0, sizeof(scratch_buf)); + status = AVRC_ParsCommand(p_msg, &cmd, scratch_buf, sizeof(scratch_buf)); + if (status == AVRC_STS_NO_ERROR) { + BT_HDR* p_pkt = (BT_HDR*)nullptr; + status = AVRC_BldCommand(&cmd, &p_pkt); + if (status == AVRC_STS_NO_ERROR && p_pkt) { + osi_free(p_pkt); + } + } + } else if (p_msg->hdr.ctype == AVCT_RSP) { + tAVRC_RESPONSE rsp = {0}; + memset(scratch_buf, 0, sizeof(scratch_buf)); + status = AVRC_ParsResponse(p_msg, &rsp, scratch_buf, sizeof(scratch_buf)); + if (status == AVRC_STS_NO_ERROR) { + BT_HDR* p_pkt = (BT_HDR*)nullptr; + status = AVRC_BldResponse(handle, &rsp, &p_pkt); + if (status == AVRC_STS_NO_ERROR && p_pkt) { + osi_free(p_pkt); + } + } + + uint16_t buf_len = sizeof(scratch_buf); + memset(scratch_buf, 0, sizeof(scratch_buf)); + status = AVRC_Ctrl_ParsResponse(p_msg, &rsp, scratch_buf, &buf_len); + if (status == AVRC_STS_NO_ERROR) { + BT_HDR* p_pkt = (BT_HDR*)nullptr; + status = AVRC_BldResponse(handle, &rsp, &p_pkt); + if (status == AVRC_STS_NO_ERROR && p_pkt) { + osi_free(p_pkt); + } + } + } +} + +static void Fuzz(const uint8_t* data, size_t size) { + FuzzedDataProvider fdp(data, size); + bool is_initiator = fdp.ConsumeBool(); + bool is_controller = fdp.ConsumeBool(); + bool is_br = fdp.ConsumeBool(); + + AVCT_Register(); + AVRC_Init(); + + tL2CAP_APPL_INFO* appl_info = is_br ? &avct_br_appl : &avct_appl; + + tAVRC_CONN_CB ccb = { + .ctrl_cback = base::Bind(ctrl_cb), + .msg_cback = base::Bind(msg_cb), + .conn = (uint8_t)(is_initiator ? AVCT_INT : AVCT_ACP), + .control = (uint8_t)(is_controller ? AVCT_CONTROL : AVCT_TARGET), + }; + + appl_info->pL2CA_ConnectInd_Cb(kDummyRemoteAddr, kDummyCid, 0, kDummyId); + + uint8_t handle; + if (AVCT_SUCCESS != AVRC_Open(&handle, &ccb, kDummyRemoteAddr)) { + return; + } + + tL2CAP_CFG_INFO cfg; + appl_info->pL2CA_ConfigCfm_Cb(kDummyCid, is_initiator, &cfg); + + // Feeding input packets + constexpr uint16_t kMaxPacketSize = 1024; + while (fdp.remaining_bytes() > 0) { + auto size = fdp.ConsumeIntegralInRange(0, kMaxPacketSize); + auto bytes = fdp.ConsumeBytes(size); + BT_HDR* hdr = (BT_HDR*)osi_calloc(sizeof(BT_HDR) + bytes.size()); + hdr->len = bytes.size(); + std::copy(bytes.cbegin(), bytes.cend(), hdr->data); + appl_info->pL2CA_DataInd_Cb(kDummyCid, hdr); + } + + AVRC_Close(handle); + + // Simulating disconnecting event + appl_info->pL2CA_DisconnectInd_Cb(kDummyCid, false); + + AVCT_Deregister(); +} + +extern "C" int LLVMFuzzerTestOneInput(const uint8_t* Data, size_t Size) { + auto fakes = std::make_unique(); + Fuzz(Data, Size); + return 0; +} diff --git a/system/stack/fuzzers/bnep_fuzzer.cc b/system/stack/fuzzers/bnep_fuzzer.cc new file mode 100644 index 00000000000..f4da8de8ece --- /dev/null +++ b/system/stack/fuzzers/bnep_fuzzer.cc @@ -0,0 +1,173 @@ +/* + * Copyright 2022 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include + +#include +#include +#include +#include + +#include "osi/include/allocator.h" +#include "stack/include/bnep_api.h" +#include "test/fake/fake_osi.h" +#include "test/mock/mock_btif_config.h" +#include "test/mock/mock_stack_acl.h" +#include "test/mock/mock_stack_btm_dev.h" +#include "test/mock/mock_stack_l2cap_api.h" +#include "test/mock/mock_stack_l2cap_ble.h" +#include "types/bluetooth/uuid.h" + +using bluetooth::Uuid; + +namespace { + +constexpr uint16_t kDummyCid = 0x1234; +constexpr uint8_t kDummyId = 0x77; +constexpr uint8_t kDummyRemoteAddr[] = {0x77, 0x88, 0x99, 0xAA, 0xBB, 0xCC}; +constexpr uint8_t kDummySrcUuid[] = {0x00, 0x11, 0x22, 0x33, 0x44, 0x55, + 0x66, 0x77, 0x88, 0x99, 0xaa, 0xbb, + 0xcc, 0xdd, 0xee, 0xff}; +constexpr uint8_t kDummyDstUuid[] = {0x00, 0x00, 0x00, 0x00, 0x22, 0x22, + 0x22, 0x22, 0x33, 0x33, 0x55, 0x55, + 0x55, 0x55, 0x55, 0x59}; + +// Set up default callback structure +static tL2CAP_APPL_INFO appl_info; + +class FakeBtStack { + public: + FakeBtStack() { + test::mock::stack_l2cap_api::L2CA_DataWrite.body = [](uint16_t cid, + BT_HDR* p_data) { + CHECK(cid == kDummyCid); + osi_free(p_data); + return L2CAP_DW_SUCCESS; + }; + test::mock::stack_l2cap_api::L2CA_DisconnectReq.body = [](uint16_t cid) { + CHECK(cid == kDummyCid); + return true; + }; + test::mock::stack_l2cap_api::L2CA_ConnectReq2.body = + [](uint16_t psm, const RawAddress& p_bd_addr, uint16_t sec_level) { + CHECK(p_bd_addr == kDummyRemoteAddr); + return kDummyCid; + }; + test::mock::stack_l2cap_api::L2CA_Register2.body = + [](uint16_t psm, const tL2CAP_APPL_INFO& p_cb_info, bool enable_snoop, + tL2CAP_ERTM_INFO* p_ertm_info, uint16_t my_mtu, + uint16_t required_remote_mtu, uint16_t sec_level) { + appl_info = p_cb_info; + return psm; + }; + test::mock::stack_l2cap_api::L2CA_Deregister.body = [](uint16_t psm) {}; + } + + ~FakeBtStack() { + test::mock::stack_l2cap_api::L2CA_DataWrite = {}; + test::mock::stack_l2cap_api::L2CA_ConnectReq2 = {}; + test::mock::stack_l2cap_api::L2CA_DisconnectReq = {}; + test::mock::stack_l2cap_api::L2CA_Register2 = {}; + test::mock::stack_l2cap_api::L2CA_Deregister = {}; + } +}; + +class Fakes { + public: + test::fake::FakeOsi fake_osi; + FakeBtStack fake_stack; +}; + +} // namespace + +// Verify the passed data is readable +static void ConsumeData(const uint8_t* data, size_t size) { + volatile uint8_t checksum = 0; + for (size_t i = 0; i < size; i++) { + checksum ^= data[i]; + } +} + +static void Fuzz(const uint8_t* data, size_t size) { + tBNEP_REGISTER reg = { + .p_conn_ind_cb = + [](uint16_t handle, const RawAddress& bd_addr, + const bluetooth::Uuid& remote_uuid, + const bluetooth::Uuid& local_uuid, + bool is_role_change) { BNEP_ConnectResp(handle, BNEP_SUCCESS); }, + .p_conn_state_cb = [](uint16_t handle, const RawAddress& rem_bda, + tBNEP_RESULT result, bool is_role_change) {}, + .p_data_ind_cb = [](uint16_t handle, const RawAddress& src, + const RawAddress& dst, uint16_t protocol, + uint8_t* p_data, uint16_t len, + bool fw_ext_present) { ConsumeData(p_data, len); }, + .p_tx_data_flow_cb = [](uint16_t handle, tBNEP_RESULT event) {}, + .p_filter_ind_cb = + [](uint16_t handle, bool indication, tBNEP_RESULT result, + uint16_t num_filters, + uint8_t* p_filters) { ConsumeData(p_filters, num_filters); }, + .p_mfilter_ind_cb = + [](uint16_t handle, bool indication, tBNEP_RESULT result, + uint16_t num_mfilters, + uint8_t* p_mfilters) { ConsumeData(p_mfilters, num_mfilters); }, + }; + + BNEP_Init(); + if (BNEP_SUCCESS != BNEP_Register(®)) { + return; + } + + FuzzedDataProvider fdp(data, size); + bool is_server = fdp.ConsumeBool(); + if (is_server) { + // Simulating an inbound connection event + appl_info.pL2CA_ConnectInd_Cb(kDummyRemoteAddr, kDummyCid, 0, kDummyId); + } else { + // Initiating an outbound connection + uint16_t handle; + BNEP_Connect(kDummyRemoteAddr, Uuid::From128BitBE(kDummySrcUuid), + Uuid::From128BitBE(kDummyDstUuid), &handle, 0); + + // Simulating outbound connection confirm event + appl_info.pL2CA_ConnectCfm_Cb(kDummyCid, L2CAP_CONN_OK); + } + + // Simulating configuration confirmation event + tL2CAP_CFG_INFO cfg = {}; + appl_info.pL2CA_ConfigCfm_Cb(kDummyCid, 0, &cfg); + + // Feeding input packets + constexpr uint16_t kMaxPacketSize = 1024; + while (fdp.remaining_bytes() > 0) { + auto size = fdp.ConsumeIntegralInRange(0, kMaxPacketSize); + auto bytes = fdp.ConsumeBytes(size); + BT_HDR* hdr = (BT_HDR*)osi_calloc(sizeof(BT_HDR) + bytes.size()); + hdr->len = bytes.size(); + std::copy(bytes.cbegin(), bytes.cend(), hdr->data); + appl_info.pL2CA_DataInd_Cb(kDummyCid, hdr); + } + + // Simulating disconnecting event + appl_info.pL2CA_DisconnectInd_Cb(kDummyCid, false); + + BNEP_Deregister(); +} + +extern "C" int LLVMFuzzerTestOneInput(const uint8_t* Data, size_t Size) { + auto fakes = std::make_unique(); + Fuzz(Data, Size); + return 0; +} diff --git a/system/stack/fuzzers/gatt_fuzzer.cc b/system/stack/fuzzers/gatt_fuzzer.cc new file mode 100644 index 00000000000..c9c05b80646 --- /dev/null +++ b/system/stack/fuzzers/gatt_fuzzer.cc @@ -0,0 +1,304 @@ +#include + +#include +#include +#include + +#include "osi/include/allocator.h" +#include "stack/include/bt_hdr.h" +#include "stack/include/gatt_api.h" +#include "stack/include/sdpdefs.h" +#include "test/fake/fake_osi.h" +#include "test/mock/mock_btif_config.h" +#include "test/mock/mock_stack_acl.h" +#include "test/mock/mock_stack_btm_dev.h" +#include "test/mock/mock_stack_l2cap_api.h" +#include "test/mock/mock_stack_l2cap_ble.h" + +using bluetooth::Uuid; +bt_status_t do_in_main_thread(base::Location const&, + base::OnceCallback) { + // this is not properly mocked, so we use abort to catch if this is used in + // any test cases + abort(); +} +bt_status_t do_in_main_thread_delayed(base::Location const&, + base::OnceCallback, + base::TimeDelta const&) { + // this is not properly mocked, so we use abort to catch if this is used in + // any test cases + abort(); +} + +namespace bluetooth { +namespace os { +bool GetSystemPropertyBool(const std::string& property, bool default_value) { + return default_value; +} +} // namespace os +} // namespace bluetooth + +constexpr uint8_t kDummyAddr[] = {0x11, 0x22, 0x33, 0x44, 0x55, 0x66}; +constexpr uint16_t kMaxPacketSize = 1024; +namespace { + +tL2CAP_FIXED_CHNL_REG fixed_chnl_reg; +tL2CAP_APPL_INFO appl_info; +tBTM_SEC_DEV_REC btm_sec_dev_rec; + +class FakeBtStack { + public: + FakeBtStack() { + test::mock::stack_btm_dev::btm_find_dev.body = [](const RawAddress&) { + return &btm_sec_dev_rec; + }; + + test::mock::stack_l2cap_ble::L2CA_GetBleConnRole.body = + [](const RawAddress&) { return HCI_ROLE_CENTRAL; }; + + test::mock::stack_l2cap_api::L2CA_SetIdleTimeoutByBdAddr.body = + [](const RawAddress&, uint16_t, uint8_t) { return true; }; + test::mock::stack_l2cap_api::L2CA_RemoveFixedChnl.body = + [](uint16_t lcid, const RawAddress&) { + CHECK(lcid == L2CAP_ATT_CID); + return true; + }; + test::mock::stack_l2cap_api::L2CA_ConnectFixedChnl.body = + [](uint16_t, const RawAddress&) { return true; }; + test::mock::stack_l2cap_api::L2CA_DataWrite.body = [](uint16_t lcid, + BT_HDR* hdr) { + osi_free(hdr); + return L2CAP_DW_SUCCESS; + }; + test::mock::stack_l2cap_api::L2CA_DisconnectReq.body = [](uint16_t) { + return true; + }; + test::mock::stack_l2cap_api::L2CA_SendFixedChnlData.body = + [](uint16_t cid, const RawAddress& addr, BT_HDR* hdr) { + osi_free(hdr); + return L2CAP_DW_SUCCESS; + }; + test::mock::stack_l2cap_api::L2CA_RegisterFixedChannel.body = + [](uint16_t fixed_cid, tL2CAP_FIXED_CHNL_REG* p_freg) { + fixed_chnl_reg = *p_freg; + return true; + }; + test::mock::stack_l2cap_api::L2CA_Register2.body = + [](uint16_t psm, const tL2CAP_APPL_INFO& p_cb_info, bool enable_snoop, + tL2CAP_ERTM_INFO* p_ertm_info, uint16_t my_mtu, + uint16_t required_remote_mtu, uint16_t sec_level) { + appl_info = p_cb_info; + return psm; + }; + test::mock::stack_l2cap_api::L2CA_RegisterLECoc.body = + [](uint16_t psm, const tL2CAP_APPL_INFO& p_fixed_chnl_reg, + uint16_t sec_level, tL2CAP_LE_CFG_INFO cfg) { return psm; }; + + test::mock::stack_l2cap_api::L2CA_SetIdleTimeoutByBdAddr.body = + [](const RawAddress&, uint16_t, uint8_t) { return true; }; + test::mock::stack_l2cap_api::L2CA_SetLeGattTimeout.body = + [](const RawAddress&, uint16_t) { return true; }; + } + + ~FakeBtStack() { + test::mock::stack_btm_dev::btm_find_dev = {}; + + test::mock::stack_l2cap_ble::L2CA_GetBleConnRole = {}; + + test::mock::stack_l2cap_api::L2CA_SetIdleTimeoutByBdAddr = {}; + test::mock::stack_l2cap_api::L2CA_RemoveFixedChnl = {}; + test::mock::stack_l2cap_api::L2CA_ConnectFixedChnl = {}; + test::mock::stack_l2cap_api::L2CA_DisconnectReq = {}; + test::mock::stack_l2cap_api::L2CA_SendFixedChnlData = {}; + test::mock::stack_l2cap_api::L2CA_RegisterFixedChannel = {}; + test::mock::stack_l2cap_api::L2CA_Register2 = {}; + test::mock::stack_l2cap_api::L2CA_RegisterLECoc = {}; + test::mock::stack_l2cap_api::L2CA_SetIdleTimeoutByBdAddr = {}; + test::mock::stack_l2cap_api::L2CA_SetLeGattTimeout = {}; + } +}; + +class Fakes { + public: + test::fake::FakeOsi fake_osi; + FakeBtStack fake_stack; +}; + +} // namespace + +static uint16_t s_ConnId; +static tGATT_IF s_AppIf; + +static void GattInit() { + s_ConnId = 0; + s_AppIf = 0; + + gatt_init(); + + /* Fill our internal UUID with a fixed pattern 0x82 */ + std::array tmp; + tmp.fill(0x82); + Uuid app_uuid = Uuid::From128BitBE(tmp); + + tGATT_CBACK gap_cback = { + .p_conn_cb = [](tGATT_IF, const RawAddress&, uint16_t conn_id, + bool connected, tGATT_DISCONN_REASON, + tBT_TRANSPORT) { s_ConnId = conn_id; }, + .p_cmpl_cb = [](uint16_t, tGATTC_OPTYPE, tGATT_STATUS, + tGATT_CL_COMPLETE*) {}, + .p_disc_res_cb = nullptr, + .p_disc_cmpl_cb = nullptr, + .p_req_cb = [](uint16_t conn_id, uint32_t trans_id, tGATTS_REQ_TYPE type, + tGATTS_DATA* p_data) {}, + .p_enc_cmpl_cb = nullptr, + .p_congestion_cb = nullptr, + .p_phy_update_cb = nullptr, + .p_conn_update_cb = nullptr, + .p_subrate_chg_cb = nullptr, + }; + + s_AppIf = GATT_Register(app_uuid, "Gap", &gap_cback, false); + GATT_StartIf(s_AppIf); +} + +static void ServerInit() { + GattInit(); + + tGATT_APPL_INFO appl_info = { + .p_nv_save_callback = [](bool, tGATTS_HNDL_RANGE*) {}, + .p_srv_chg_callback = [](tGATTS_SRV_CHG_CMD, tGATTS_SRV_CHG_REQ*, + tGATTS_SRV_CHG_RSP*) { return true; }, + }; + GATTS_NVRegister(&appl_info); + + Uuid svc_uuid = Uuid::From16Bit(UUID_SERVCLASS_GAP_SERVER); + Uuid name_uuid = Uuid::From16Bit(GATT_UUID_GAP_DEVICE_NAME); + Uuid icon_uuid = Uuid::From16Bit(GATT_UUID_GAP_ICON); + Uuid addr_res_uuid = Uuid::From16Bit(GATT_UUID_GAP_CENTRAL_ADDR_RESOL); + + btgatt_db_element_t service[] = { + { + .uuid = svc_uuid, + .type = BTGATT_DB_PRIMARY_SERVICE, + }, + {.uuid = name_uuid, + .type = BTGATT_DB_CHARACTERISTIC, + .properties = GATT_CHAR_PROP_BIT_READ, + .permissions = GATT_PERM_READ_IF_ENCRYPTED_OR_DISCOVERABLE}, + {.uuid = icon_uuid, + .type = BTGATT_DB_CHARACTERISTIC, + .properties = GATT_CHAR_PROP_BIT_READ, + .permissions = GATT_PERM_READ}, + {.uuid = addr_res_uuid, + .type = BTGATT_DB_CHARACTERISTIC, + .properties = GATT_CHAR_PROP_BIT_READ, + .permissions = GATT_PERM_READ}}; + + /* Add a GAP service */ + GATTS_AddService(s_AppIf, service, + sizeof(service) / sizeof(btgatt_db_element_t)); +} + +static void ServerCleanup() { + GATT_Deregister(s_AppIf); + gatt_free(); +} + +static void FuzzAsServer(const uint8_t* data, size_t size) { + ServerInit(); + fixed_chnl_reg.pL2CA_FixedConn_Cb(L2CAP_ATT_CID, kDummyAddr, true, 0, + BT_TRANSPORT_LE); + + FuzzedDataProvider fdp(data, size); + while (fdp.remaining_bytes() > 0) { + auto size = fdp.ConsumeIntegralInRange(0, kMaxPacketSize); + auto bytes = fdp.ConsumeBytes(size); + BT_HDR* hdr = (BT_HDR*)osi_calloc(sizeof(BT_HDR) + bytes.size()); + hdr->len = bytes.size(); + std::copy(bytes.cbegin(), bytes.cend(), hdr->data); + fixed_chnl_reg.pL2CA_FixedData_Cb(L2CAP_ATT_CID, kDummyAddr, hdr); + } + + ServerCleanup(); +} + +static void ClientInit() { + GattInit(); + GATT_Connect(s_AppIf, kDummyAddr, BTM_BLE_DIRECT_CONNECTION, BT_TRANSPORT_LE, + false); +} + +static void ClientCleanup() { + GATT_CancelConnect(s_AppIf, kDummyAddr, true); + GATT_Deregister(s_AppIf); + gatt_free(); +} + +static void FuzzAsClient(const uint8_t* data, size_t size) { + ClientInit(); + fixed_chnl_reg.pL2CA_FixedConn_Cb(L2CAP_ATT_CID, kDummyAddr, true, 0, + BT_TRANSPORT_LE); + + FuzzedDataProvider fdp(data, size); + while (fdp.remaining_bytes() > 0) { + auto op = fdp.ConsumeIntegral(); + switch (op) { + case GATTC_OPTYPE_CONFIG: { + auto mtu = fdp.ConsumeIntegral(); + GATTC_ConfigureMTU(s_ConnId, mtu); + break; + } + case GATTC_OPTYPE_DISCOVERY: { + auto type = (tGATT_DISC_TYPE)fdp.ConsumeIntegralInRange( + 0, GATT_DISC_MAX); + uint16_t start = fdp.ConsumeIntegral(); + uint16_t end = fdp.ConsumeIntegral(); + GATTC_Discover(s_ConnId, type, start, end); + break; + } + case GATTC_OPTYPE_READ: { + auto type = (tGATT_READ_TYPE)fdp.ConsumeIntegralInRange( + 0, GATT_READ_MAX); + tGATT_READ_PARAM param = {}; + fdp.ConsumeData(¶m, sizeof(param)); + GATTC_Read(s_ConnId, type, ¶m); + break; + } + case GATTC_OPTYPE_WRITE: { + auto type = (tGATT_WRITE_TYPE)fdp.ConsumeIntegralInRange( + 0, GATT_WRITE_PREPARE + 1); + tGATT_VALUE value = {}; + value.len = + fdp.ConsumeIntegralInRange(0, sizeof(value.value)); + value.len = fdp.ConsumeData(&value.value, value.len); + GATTC_Write(s_ConnId, type, &value); + break; + } + case GATTC_OPTYPE_EXE_WRITE: { + auto type = fdp.ConsumeBool(); + GATTC_ExecuteWrite(s_ConnId, type); + break; + } + default: + break; + } + auto size = fdp.ConsumeIntegralInRange(0, kMaxPacketSize); + auto bytes = fdp.ConsumeBytes(size); + BT_HDR* hdr = (BT_HDR*)osi_calloc(sizeof(BT_HDR) + bytes.size()); + hdr->len = bytes.size(); + std::copy(bytes.cbegin(), bytes.cend(), hdr->data); + fixed_chnl_reg.pL2CA_FixedData_Cb(L2CAP_ATT_CID, kDummyAddr, hdr); + } + + fixed_chnl_reg.pL2CA_FixedConn_Cb(L2CAP_ATT_CID, kDummyAddr, false, 0, + BT_TRANSPORT_LE); + ClientCleanup(); +} + +extern "C" int LLVMFuzzerTestOneInput(const uint8_t* Data, size_t Size) { + auto fakes = std::make_unique(); + + FuzzAsServer(Data, Size); + FuzzAsClient(Data, Size); + return 0; +} \ No newline at end of file diff --git a/system/stack/fuzzers/l2cap_fuzzer.cc b/system/stack/fuzzers/l2cap_fuzzer.cc new file mode 100644 index 00000000000..c7b2208c009 --- /dev/null +++ b/system/stack/fuzzers/l2cap_fuzzer.cc @@ -0,0 +1,253 @@ +/* + * Copyright 2022 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include + +#include +#include +#include +#include + +#include "btif/include/stack_manager.h" +#include "gd/hal/snoop_logger.h" +#include "osi/include/allocator.h" +#include "stack/btm/btm_int_types.h" +#include "stack/include/l2c_api.h" +#include "stack/include/l2cap_acl_interface.h" +#include "stack/include/l2cap_controller_interface.h" +#include "stack/include/l2cap_hci_link_interface.h" +#include "test/fake/fake_osi.h" +#include "test/mock/mock_device_controller.h" +#include "test/mock/mock_stack_acl.h" +#include "test/mock/mock_stack_btm_devctl.h" + +using bluetooth::Uuid; + +// Verify the passed data is readable +static void ConsumeData(const uint8_t* data, size_t size) { + volatile uint8_t checksum = 0; + for (size_t i = 0; i < size; i++) { + checksum ^= data[i]; + } +} + +tBTM_CB btm_cb; +uint8_t appl_trace_level; + +bt_status_t do_in_main_thread(base::Location const&, + base::OnceCallback) { + // this is not properly mocked, so we use abort to catch if this is used in + // any test cases + abort(); +} +bt_status_t do_in_main_thread_delayed(base::Location const&, + base::OnceCallback, + base::TimeDelta const&) { + // this is not properly mocked, so we use abort to catch if this is used in + // any test cases + abort(); +} + +namespace bluetooth { +namespace os { +uint32_t GetSystemPropertyUint32Base(const std::string& property, + uint32_t default_value, int base) { + return default_value; +} +} // namespace os + +namespace hal { +class SnoopLogger; + +const std::string SnoopLogger::kBtSnoopLogModeFiltered = "filtered"; + +std::string SnoopLogger::GetBtSnoopMode() { return "filtered"; } +void SnoopLogger::AcceptlistL2capChannel(uint16_t, uint16_t, uint16_t) {} +void SnoopLogger::AddA2dpMediaChannel(uint16_t, uint16_t, uint16_t) {} +void SnoopLogger::AddRfcommL2capChannel(uint16_t, uint16_t, uint16_t) {} +void SnoopLogger::ClearL2capAcceptlist(uint16_t, uint16_t, uint16_t) {} +void SnoopLogger::RemoveA2dpMediaChannel(uint16_t, uint16_t) {} +void SnoopLogger::SetL2capChannelClose(uint16_t, uint16_t, uint16_t) {} +void SnoopLogger::SetL2capChannelOpen(uint16_t, uint16_t, uint16_t, uint16_t, + bool) {} +} // namespace hal +} // namespace bluetooth + +namespace { + +class FakeBtStack { + public: + FakeBtStack() { + test::mock::stack_btm_devctl::BTM_IsDeviceUp.body = []() { return true; }; + test::mock::stack_acl::acl_create_le_connection.body = + [](const RawAddress& bd_addr) { return true; }; + test::mock::stack_acl::acl_create_classic_connection.body = + [](const RawAddress& bd_addr, bool there_are_high_priority_channels, + bool is_bonding) { return true; }; + + test::mock::stack_acl::acl_send_data_packet_br_edr.body = + [](const RawAddress& bd_addr, BT_HDR* hdr) { + ConsumeData((const uint8_t*)hdr, hdr->offset + hdr->len); + osi_free(hdr); + }; + test::mock::stack_acl::acl_send_data_packet_ble.body = + [](const RawAddress& bd_addr, BT_HDR* hdr) { + ConsumeData((const uint8_t*)hdr, hdr->offset + hdr->len); + osi_free(hdr); + }; + + GetInterfaceToProfiles()->profileSpecific_HACK->GetHearingAidDeviceCount = + []() { return 1; }; + + test::mock::device_controller::ble_supported = true; + test::mock::device_controller::acl_data_size_classic = 512; + test::mock::device_controller::acl_data_size_ble = 512; + test::mock::device_controller::iso_data_size = 512; + test::mock::device_controller::ble_suggested_default_data_length = 512; + } + + ~FakeBtStack() { + test::mock::stack_btm_devctl::BTM_IsDeviceUp = {}; + test::mock::stack_acl::acl_create_le_connection = {}; + test::mock::stack_acl::acl_create_classic_connection = {}; + test::mock::stack_acl::acl_send_data_packet_br_edr = {}; + test::mock::stack_acl::acl_send_data_packet_ble = {}; + } +}; + +class Fakes { + public: + test::fake::FakeOsi fake_osi; + FakeBtStack fake_stack; +}; + +} // namespace + +constexpr uint8_t kAttAddr[] = {0x11, 0x78, 0x78, 0x78, 0x78, 0x78}; +constexpr uint16_t kAttHndl = 0x0111; + +constexpr uint8_t kEattAddr[] = {0x22, 0x78, 0x78, 0x78, 0x78, 0x78}; + +constexpr uint8_t kSmpBrAddr[] = {0x33, 0x78, 0x78, 0x78, 0x78, 0x78}; +constexpr uint16_t kSmpBrHndl = 0x0222; + +constexpr uint16_t kNumClassicAclBuffer = 100; +constexpr uint16_t kNumLeAclBuffer = 100; + +void l2c_link_hci_conn_comp(tHCI_STATUS status, uint16_t handle, + const RawAddress& p_bda); + +static void Fuzz(const uint8_t* data, size_t size) { + memset(&btm_cb, 0, sizeof(btm_cb)); + + l2c_init(); + + l2c_link_init(kNumClassicAclBuffer); + l2c_link_processs_ble_num_bufs(kNumLeAclBuffer); + + tL2CAP_FIXED_CHNL_REG reg = { + .pL2CA_FixedConn_Cb = [](uint16_t, const RawAddress&, bool, uint16_t, + tBT_TRANSPORT) {}, + .pL2CA_FixedData_Cb = + [](uint16_t, const RawAddress&, BT_HDR* hdr) { + ConsumeData((const uint8_t*)hdr, hdr->offset + hdr->len); + }, + .pL2CA_FixedCong_Cb = [](const RawAddress&, bool) {}, + .default_idle_tout = 1000, + }; + + tL2CAP_APPL_INFO appl_info = { + .pL2CA_ConnectInd_Cb = [](const RawAddress&, uint16_t, uint16_t, + uint8_t) {}, + .pL2CA_ConnectCfm_Cb = [](uint16_t, uint16_t) {}, + .pL2CA_ConfigInd_Cb = [](uint16_t, tL2CAP_CFG_INFO*) {}, + .pL2CA_ConfigCfm_Cb = [](uint16_t, uint16_t, tL2CAP_CFG_INFO*) {}, + .pL2CA_DisconnectInd_Cb = [](uint16_t, bool) {}, + .pL2CA_DisconnectCfm_Cb = [](uint16_t, uint16_t) {}, + .pL2CA_DataInd_Cb = + [](uint16_t, BT_HDR* hdr) { + ConsumeData((const uint8_t*)hdr, hdr->offset + hdr->len); + }, + .pL2CA_CongestionStatus_Cb = [](uint16_t, bool) {}, + .pL2CA_TxComplete_Cb = [](uint16_t, uint16_t) {}, + .pL2CA_Error_Cb = [](uint16_t, uint16_t) {}, + .pL2CA_CreditBasedConnectInd_Cb = [](const RawAddress&, + std::vector&, uint16_t, + uint16_t, uint8_t) {}, + .pL2CA_CreditBasedConnectCfm_Cb = [](const RawAddress&, uint16_t, + uint16_t, uint16_t) {}, + .pL2CA_CreditBasedReconfigCompleted_Cb = [](const RawAddress&, uint16_t, + bool, tL2CAP_LE_CFG_INFO*) {}, + .pL2CA_CreditBasedCollisionInd_Cb = [](const RawAddress&) {}, + }; + CHECK(L2CA_Register2(BT_PSM_ATT, appl_info, false, nullptr, L2CAP_MTU_SIZE, 0, + BTM_SEC_NONE)); + CHECK(L2CA_RegisterLECoc(BT_PSM_EATT, appl_info, BTM_SEC_NONE, {})); + + CHECK(L2CA_RegisterFixedChannel(L2CAP_ATT_CID, ®)); + CHECK(L2CA_ConnectFixedChnl(L2CAP_ATT_CID, kAttAddr)); + CHECK(l2cble_conn_comp(kAttHndl, HCI_ROLE_CENTRAL, kAttAddr, BLE_ADDR_PUBLIC, + 100, 100, 100)); + + CHECK(L2CA_RegisterFixedChannel(L2CAP_SMP_BR_CID, ®)); + CHECK(L2CA_ConnectFixedChnl(L2CAP_SMP_BR_CID, kSmpBrAddr)); + l2c_link_hci_conn_comp(HCI_SUCCESS, kSmpBrHndl, kSmpBrAddr); + + auto att_cid = L2CA_ConnectReq(BT_PSM_ATT, kAttAddr); + CHECK(att_cid != 0); + + tL2CAP_LE_CFG_INFO cfg; + auto eatt_cid = L2CA_ConnectLECocReq(BT_PSM_EATT, kEattAddr, &cfg, 0); + CHECK(eatt_cid != 0); + + FuzzedDataProvider fdp(data, size); + + // Feeding input packets + constexpr uint16_t kMinPacketSize = 4 + L2CAP_PKT_OVERHEAD; + constexpr uint16_t kMaxPacketSize = 1024; + for (;;) { + auto size = + fdp.ConsumeIntegralInRange(kMinPacketSize, kMaxPacketSize); + auto bytes = fdp.ConsumeBytes(size); + if (bytes.size() < kMinPacketSize) { + break; + } + + BT_HDR* hdr = (BT_HDR*)osi_calloc(sizeof(BT_HDR) + bytes.size()); + hdr->len = bytes.size(); + std::copy(bytes.cbegin(), bytes.cend(), hdr->data); + l2c_rcv_acl_data(hdr); + } + + L2CA_DisconnectReq(att_cid); + L2CA_DisconnectLECocReq(eatt_cid); + + L2CA_RemoveFixedChnl(L2CAP_SMP_BR_CID, kSmpBrAddr); + l2c_link_hci_disc_comp(kSmpBrHndl, HCI_SUCCESS); + + L2CA_RemoveFixedChnl(L2CAP_ATT_CID, kAttAddr); + l2c_link_hci_disc_comp(kAttHndl, HCI_SUCCESS); + + l2cu_device_reset(); + l2c_free(); +} + +extern "C" int LLVMFuzzerTestOneInput(const uint8_t* Data, size_t Size) { + auto fakes = std::make_unique(); + Fuzz(Data, Size); + return 0; +} diff --git a/system/stack/fuzzers/smp_fuzzer.cc b/system/stack/fuzzers/smp_fuzzer.cc new file mode 100644 index 00000000000..ebb38d736c6 --- /dev/null +++ b/system/stack/fuzzers/smp_fuzzer.cc @@ -0,0 +1,237 @@ +/* + * Copyright 2022 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include + +#include +#include +#include +#include + +#include "osi/include/allocator.h" +#include "stack/btm/btm_int_types.h" +#include "stack/include/bt_hdr.h" +#include "stack/include/sdpdefs.h" +#include "stack/include/smp_api.h" +#include "stack/smp/p_256_ecc_pp.h" +#include "stack/smp/smp_int.h" +#include "test/fake/fake_osi.h" +#include "test/mock/mock_btif_config.h" +#include "test/mock/mock_stack_acl.h" +#include "test/mock/mock_stack_btm_dev.h" +#include "test/mock/mock_stack_l2cap_api.h" +#include "test/mock/mock_stack_l2cap_ble.h" +#include "types/bluetooth/uuid.h" + +namespace { + +#define SDP_DB_SIZE 0x10000 + +constexpr uint8_t kDummyAddr[] = {0x11, 0x22, 0x33, 0x44, 0x55, 0x66}; +constexpr uint8_t kDummyRemoteAddr[] = {0x77, 0x88, 0x99, 0xAA, 0xBB, 0xCC}; + +// Set up default callback structure +tL2CAP_FIXED_CHNL_REG fixed_chnl_reg = { + .pL2CA_FixedConn_Cb = [](uint16_t, const RawAddress&, bool, uint16_t, + tBT_TRANSPORT) {}, + .pL2CA_FixedData_Cb = [](uint16_t, const RawAddress&, BT_HDR*) {}, +}; + +tL2CAP_FIXED_CHNL_REG fixed_chnl_br_reg = { + .pL2CA_FixedConn_Cb = [](uint16_t, const RawAddress&, bool, uint16_t, + tBT_TRANSPORT) {}, + .pL2CA_FixedData_Cb = [](uint16_t, const RawAddress&, BT_HDR*) {}, +}; + +tBTM_SEC_DEV_REC dev_rec; +bool is_peripheral; + +class FakeBtStack { + public: + FakeBtStack() { + test::mock::stack_acl::BTM_ReadConnectionAddr.body = + [](const RawAddress& remote_bda, RawAddress& local_conn_addr, + tBLE_ADDR_TYPE* p_addr_type) { + local_conn_addr = kDummyAddr; + *p_addr_type = BLE_ADDR_PUBLIC; + }; + test::mock::stack_acl::BTM_ReadRemoteConnectionAddr.body = + [](const RawAddress& pseudo_addr, RawAddress& conn_addr, + tBLE_ADDR_TYPE* p_addr_type) { + conn_addr = kDummyRemoteAddr; + *p_addr_type = BLE_ADDR_PUBLIC; + return true; + }; + test::mock::stack_btm_dev::btm_find_dev.body = [](const RawAddress&) { + return &dev_rec; + }; + + test::mock::stack_l2cap_ble::L2CA_GetBleConnRole.body = + [](const RawAddress&) { + return is_peripheral ? HCI_ROLE_PERIPHERAL : HCI_ROLE_CENTRAL; + }; + + test::mock::stack_l2cap_api::L2CA_SetIdleTimeoutByBdAddr.body = + [](const RawAddress&, uint16_t, uint8_t) { return true; }; + test::mock::stack_l2cap_api::L2CA_RemoveFixedChnl.body = + [](uint16_t, const RawAddress&) { return true; }; + test::mock::stack_l2cap_api::L2CA_ConnectFixedChnl.body = + [](uint16_t, const RawAddress&) { return true; }; + test::mock::stack_l2cap_api::L2CA_SendFixedChnlData.body = + [](uint16_t cid, const RawAddress& addr, BT_HDR* hdr) { + osi_free(hdr); + return L2CAP_DW_SUCCESS; + }; + test::mock::stack_l2cap_api::L2CA_RegisterFixedChannel.body = + [](uint16_t fixed_cid, tL2CAP_FIXED_CHNL_REG* p_freg) { + if (fixed_cid == L2CAP_SMP_CID) { + fixed_chnl_reg = *p_freg; + } else if (fixed_cid == L2CAP_SMP_BR_CID) { + fixed_chnl_br_reg = *p_freg; + } else { + abort(); + } + return true; + }; + } + + ~FakeBtStack() { + test::mock::stack_acl::BTM_ReadConnectionAddr = {}; + test::mock::stack_acl::BTM_ReadRemoteConnectionAddr = {}; + + test::mock::stack_btm_dev::btm_find_dev = {}; + + test::mock::stack_l2cap_ble::L2CA_GetBleConnRole = {}; + + test::mock::stack_l2cap_api::L2CA_SetIdleTimeoutByBdAddr = {}; + test::mock::stack_l2cap_api::L2CA_RemoveFixedChnl = {}; + test::mock::stack_l2cap_api::L2CA_ConnectFixedChnl = {}; + test::mock::stack_l2cap_api::L2CA_SendFixedChnlData = {}; + test::mock::stack_l2cap_api::L2CA_RegisterFixedChannel = {}; + } +}; + +class Fakes { + public: + test::fake::FakeOsi fake_osi; + FakeBtStack fake_stack; +}; + +} // namespace + +// Mocking some ECC operations +bool ECC_ValidatePoint(Point const&) { return true; } +void ECC_PointMult_Bin_NAF(Point* q, Point* p, uint32_t* n) {} +void p_256_init_curve() {} +elliptic_curve_t curve_p256; + +tBTM_CB btm_cb; +uint8_t oob_data[] = {0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, + 0x99, 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 0x00}; +tSMP_IO_REQ io_req = {}; + +tBTM_STATUS smp_callback(tSMP_EVT event, const RawAddress& bd_addr, + const tSMP_EVT_DATA* p_data) { + switch (event) { + case SMP_IO_CAP_REQ_EVT: + case SMP_BR_KEYS_REQ_EVT: { + tSMP_IO_REQ* p_req = (tSMP_IO_REQ*)p_data; + memcpy(p_req, &io_req, sizeof(io_req)); + } break; + + case SMP_PASSKEY_REQ_EVT: { + SMP_PasskeyReply(kDummyAddr, SMP_SUCCESS, 1234); + } break; + + case SMP_NC_REQ_EVT: { + SMP_ConfirmReply(kDummyAddr, SMP_SUCCESS); + } break; + + case SMP_OOB_REQ_EVT: { + SMP_OobDataReply(kDummyAddr, SMP_SUCCESS, sizeof(oob_data), oob_data); + } break; + + case SMP_SC_OOB_REQ_EVT: { + tSMP_SC_OOB_DATA oob_data = {}; + SMP_SecureConnectionOobDataReply((uint8_t*)&oob_data); + } break; + case SMP_CONSENT_REQ_EVT: { + SMP_SecurityGrant(kDummyAddr, SMP_SUCCESS); + } break; + default: + break; + } + return BTM_SUCCESS; +} + +void Fuzz(const uint8_t* data, size_t size) { + FuzzedDataProvider fdp(data, size); + uint16_t cid; + tBT_TRANSPORT transport; + tL2CAP_FIXED_CHNL_REG* chnl_reg; + + btm_cb = tBTM_CB(); + + SMP_Init(); + SMP_Register(smp_callback); + SMP_SetTraceLevel(BT_TRACE_LEVEL_DEBUG); + SMP_ClearLocScOobData(); + + auto is_br = fdp.ConsumeBool(); + auto is_initiator = fdp.ConsumeBool(); + is_peripheral = fdp.ConsumeBool(); + fdp.ConsumeData(&io_req, sizeof(io_req)); + + if (is_br) { + cid = L2CAP_SMP_BR_CID; + chnl_reg = &fixed_chnl_br_reg; + transport = BT_TRANSPORT_BR_EDR; + if (is_initiator) SMP_BR_PairWith(kDummyAddr); + } else { + cid = L2CAP_SMP_CID; + chnl_reg = &fixed_chnl_reg; + transport = BT_TRANSPORT_LE; + if (is_initiator) SMP_Pair(kDummyAddr); + } + + // Simulating connection establaishing event + chnl_reg->pL2CA_FixedConn_Cb(cid, kDummyAddr, true, 0, transport); + + constexpr uint16_t kMaxPacketSize = 1024; + while (fdp.remaining_bytes() > 0) { + auto size = fdp.ConsumeIntegralInRange(0, kMaxPacketSize); + auto bytes = fdp.ConsumeBytes(size); + BT_HDR* hdr = (BT_HDR*)osi_calloc(sizeof(BT_HDR) + bytes.size()); + hdr->len = bytes.size(); + std::copy(bytes.cbegin(), bytes.cend(), hdr->data); + + // Simulating incoming data packet event + chnl_reg->pL2CA_FixedData_Cb(cid, kDummyAddr, hdr); + } + + // Simulating disconnecting event + chnl_reg->pL2CA_FixedConn_Cb(cid, kDummyAddr, false, 0, transport); + + // Final cleanups to avoid memory leak + alarm_free(smp_cb.smp_rsp_timer_ent); + alarm_free(smp_cb.delayed_auth_timer_ent); +} + +extern "C" int LLVMFuzzerTestOneInput(const uint8_t* Data, size_t Size) { + auto fakes = std::make_unique(); + Fuzz(Data, Size); + return 0; +} -- GitLab From 63d7236c7f0623259e5e77b4aa6d933fb0b9a545 Mon Sep 17 00:00:00 2001 From: Bill Yi Date: Tue, 2 May 2023 23:45:00 -0700 Subject: [PATCH 0029/2405] Import translations. DO NOT MERGE ANYWHERE Auto-generated-cl: translation import Change-Id: Ib750b1219d336f0c9aded352ee145a6bf7daa8e4 --- android/app/res/values-kn/strings_sap.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/android/app/res/values-kn/strings_sap.xml b/android/app/res/values-kn/strings_sap.xml index 6ab1489c235..d2c7002f9f0 100644 --- a/android/app/res/values-kn/strings_sap.xml +++ b/android/app/res/values-kn/strings_sap.xml @@ -1,8 +1,8 @@ - "ಬ್ಲೂಟೂತ್ ಸಿಮ್ ಪ್ರವೇಶ" - "ಬ್ಲೂಟೂತ್ ಸಿಮ್ ಪ್ರವೇಶ" + "ಬ್ಲೂಟೂತ್ ಸಿಮ್ ಆ್ಯಕ್ಸೆಸ್" + "ಬ್ಲೂಟೂತ್ ಸಿಮ್ ಆ್ಯಕ್ಸೆಸ್" "ಕಡಿತಗೊಳಿಸಲು ಕ್ಲೈಂಟ್ ಅನ್ನು ವಿನಂತಿಸುವುದೇ?" "ಕಡಿತಗೊಳಿಸಲು ಕ್ಲೈಂಟ್‌ಗೆ ನಿರೀಕ್ಷಿಸಲಾಗುತ್ತಿದೆ" "ಸಂಪರ್ಕ ಕಡಿತಗೊಳಿಸಿ" -- GitLab From 8810dfde2cbd831d8605e7320b2ff7214da8c8c4 Mon Sep 17 00:00:00 2001 From: Bill Yi Date: Tue, 2 May 2023 23:46:26 -0700 Subject: [PATCH 0030/2405] Import translations. DO NOT MERGE ANYWHERE Auto-generated-cl: translation import Change-Id: Ie6ee71c272992f3f5892531dad071bca5ac01218 --- android/app/res/values-te/strings.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/android/app/res/values-te/strings.xml b/android/app/res/values-te/strings.xml index fbe30065451..513e12b95e9 100644 --- a/android/app/res/values-te/strings.xml +++ b/android/app/res/values-te/strings.xml @@ -87,7 +87,7 @@ "ఫైల్‌ను సేవ్ చేయడానికి USB స్టోరేజ్‌లో సరిపడేంత స్పేస్ లేదు." "ఫైల్‌ను సేవ్ చేయడానికి SD కార్డ్‌లో సరిపడేంత స్పేస్ లేదు." "కావలసిన స్థలం: %1$s" - "చాలా ఎక్కువ రిక్వెస్ట్‌లు ప్రాసెస్ చేయబడుతున్నాయి. తర్వాత మళ్లీ ప్రయత్నించండి." + "చాలా ఎక్కువ రిక్వెస్ట్‌లు ప్రాసెస్ చేయబడుతున్నాయి. తర్వాత మళ్లీ ట్రై చేయండి." "ఫైల్ బదిలీ ఇంకా ప్రారంభించబడలేదు." "ఫైల్ బదిలీ కొనసాగుతోంది." "ఫైల్ బదిలీ విజయవంతంగా పూర్తయింది." -- GitLab From c02e35fe4ffc43009631592f26ad8ed830575508 Mon Sep 17 00:00:00 2001 From: Hui Peng Date: Fri, 28 Apr 2023 23:24:14 +0000 Subject: [PATCH 0031/2405] Fix a type confusion bug in bta_av_setconfig_rej tBTA_AV_CI_SETCONFIG is treated as tBTA_AV_STR_MSG in bta_av_setconfig_rej, resulting OOB access. Bug: 260230151 Test: manual Ignore-AOSP-First: security Tag: #security (cherry picked from https://googleplex-android-review.googlesource.com/q/commit:d5ec52732410406d4adf6bab85bb981f836b32dc) Merged-In: I78a1ee50dea0113381e51f8521711d758dc759cf Change-Id: I78a1ee50dea0113381e51f8521711d758dc759cf --- system/bta/av/bta_av_aact.cc | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/system/bta/av/bta_av_aact.cc b/system/bta/av/bta_av_aact.cc index 11dc3ed882d..1e7e6daca36 100644 --- a/system/bta/av/bta_av_aact.cc +++ b/system/bta/av/bta_av_aact.cc @@ -1785,9 +1785,7 @@ void bta_av_getcap_results(tBTA_AV_SCB* p_scb, tBTA_AV_DATA* p_data) { * ******************************************************************************/ void bta_av_setconfig_rej(tBTA_AV_SCB* p_scb, tBTA_AV_DATA* p_data) { - uint8_t avdt_handle = p_data->ci_setconfig.avdt_handle; - - bta_av_adjust_seps_idx(p_scb, avdt_handle); + bta_av_adjust_seps_idx(p_scb, p_scb->avdt_handle); LOG_INFO("%s: sep_idx=%d avdt_handle=%d bta_handle=0x%x", __func__, p_scb->sep_idx, p_scb->avdt_handle, p_scb->hndl); AVDT_ConfigRsp(p_scb->avdt_handle, p_scb->avdt_label, AVDT_ERR_UNSUP_CFG, 0); @@ -1795,7 +1793,7 @@ void bta_av_setconfig_rej(tBTA_AV_SCB* p_scb, tBTA_AV_DATA* p_data) { tBTA_AV bta_av_data = { .reject = { - .bd_addr = p_data->str_msg.bd_addr, + .bd_addr = p_scb->PeerAddress(), .hndl = p_scb->hndl, }, }; -- GitLab From d85588ff80baf0164301514f005c85a051311e0a Mon Sep 17 00:00:00 2001 From: Hui Peng Date: Fri, 5 May 2023 08:46:43 +0000 Subject: [PATCH 0032/2405] Fix 2 OOB bugs in LeAudioBroadcasterImpl::UpdateMetadata Bug: 275551881 Test: manual Ignore-AOSP-First: security Tag: #security Change-Id: I6172d11a9c745018ca40e2df8b0e70f4f9728fde --- system/bta/le_audio/broadcaster/broadcaster.cc | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/system/bta/le_audio/broadcaster/broadcaster.cc b/system/bta/le_audio/broadcaster/broadcaster.cc index 7a46fa5b01b..820003cdd32 100644 --- a/system/bta/le_audio/broadcaster/broadcaster.cc +++ b/system/bta/le_audio/broadcaster/broadcaster.cc @@ -302,6 +302,10 @@ class LeAudioBroadcasterImpl : public LeAudioBroadcaster, public BigCallbacks { le_audio::types::kLeAudioMetadataTypeStreamingAudioContext); if (stream_context_vec) { auto pp = stream_context_vec.value().data(); + if (stream_context_vec.value().size() < 2) { + LOG_ERROR("stream_context_vec.value() size < 2"); + return; + } UINT16_TO_STREAM(pp, context_type.value()); } } @@ -310,6 +314,10 @@ class LeAudioBroadcasterImpl : public LeAudioBroadcaster, public BigCallbacks { ltv.Find(le_audio::types::kLeAudioMetadataTypeStreamingAudioContext); if (stream_context_vec) { auto pp = stream_context_vec.value().data(); + if (stream_context_vec.value().size() < 2) { + LOG_ERROR("stream_context_vec.value() size < 2"); + return; + } STREAM_TO_UINT16(context_type.value_ref(), pp); } -- GitLab From 03f6330d9ff73a51aa2c01c30460ad36d420fc76 Mon Sep 17 00:00:00 2001 From: Hui Peng Date: Fri, 5 May 2023 08:46:43 +0000 Subject: [PATCH 0033/2405] Fix 2 OOB bugs in LeAudioBroadcasterImpl::UpdateMetadata Bug: 275551881 Test: manual Ignore-AOSP-First: security Tag: #security Merged-In: I6172d11a9c745018ca40e2df8b0e70f4f9728fde Change-Id: I6172d11a9c745018ca40e2df8b0e70f4f9728fde --- system/bta/le_audio/broadcaster/broadcaster.cc | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/system/bta/le_audio/broadcaster/broadcaster.cc b/system/bta/le_audio/broadcaster/broadcaster.cc index 7a46fa5b01b..820003cdd32 100644 --- a/system/bta/le_audio/broadcaster/broadcaster.cc +++ b/system/bta/le_audio/broadcaster/broadcaster.cc @@ -302,6 +302,10 @@ class LeAudioBroadcasterImpl : public LeAudioBroadcaster, public BigCallbacks { le_audio::types::kLeAudioMetadataTypeStreamingAudioContext); if (stream_context_vec) { auto pp = stream_context_vec.value().data(); + if (stream_context_vec.value().size() < 2) { + LOG_ERROR("stream_context_vec.value() size < 2"); + return; + } UINT16_TO_STREAM(pp, context_type.value()); } } @@ -310,6 +314,10 @@ class LeAudioBroadcasterImpl : public LeAudioBroadcaster, public BigCallbacks { ltv.Find(le_audio::types::kLeAudioMetadataTypeStreamingAudioContext); if (stream_context_vec) { auto pp = stream_context_vec.value().data(); + if (stream_context_vec.value().size() < 2) { + LOG_ERROR("stream_context_vec.value() size < 2"); + return; + } STREAM_TO_UINT16(context_type.value_ref(), pp); } -- GitLab From fc4deea428620bb9f1d4f46e1af37eacb300d7bc Mon Sep 17 00:00:00 2001 From: Rahul Arya Date: Mon, 8 May 2023 21:13:39 +0000 Subject: [PATCH 0034/2405] [GATT Server] Split up Arbiter logic and FFI The IsolationManager logic is separate from the FFI forwarding, so put it in a separate module. The idea is that the IsolationManager will ultimately live in the GATT server module directly, and peers will see either the global GATT db, or a server selected by the IsolationManager. FFI will always send connections straight to the GATT module, even if they are not isolated. Test: unit Bug: 274945531 Change-Id: I470d40e7a7c093ff55994aeb6a6935aa854c6970 --- system/rust/src/gatt/arbiter.rs | 378 +++--------------- system/rust/src/gatt/server.rs | 1 + .../rust/src/gatt/server/isolation_manager.rs | 242 +++++++++++ 3 files changed, 301 insertions(+), 320 deletions(-) create mode 100644 system/rust/src/gatt/server/isolation_manager.rs diff --git a/system/rust/src/gatt/arbiter.rs b/system/rust/src/gatt/arbiter.rs index 26a8d3319eb..d4a113f6b12 100644 --- a/system/rust/src/gatt/arbiter.rs +++ b/system/rust/src/gatt/arbiter.rs @@ -1,9 +1,9 @@ //! This module handles "arbitration" of ATT packets, to determine whether they -//! should be handled by the primary stack or by the "Private GATT" stack +//! should be handled by the primary stack or by the Rust stack -use std::{collections::HashMap, sync::Mutex}; +use std::sync::Mutex; -use log::{error, info, trace}; +use log::{error, trace}; use crate::{ do_in_rust_thread, @@ -12,25 +12,17 @@ use crate::{ use super::{ ffi::{InterceptAction, StoreCallbacksFromRust}, - ids::{AdvertiserId, ConnectionId, ServerId, TransportIndex}, + ids::{AdvertiserId, TransportIndex}, mtu::MtuEvent, opcode_types::{classify_opcode, OperationType}, + server::isolation_manager::IsolationManager, }; -static ARBITER: Mutex> = Mutex::new(None); - -/// This class is responsible for tracking which connections and advertising we -/// own, and using this information to decide what packets should be -/// intercepted, and which should be forwarded to the legacy stack. -#[derive(Default)] -pub struct Arbiter { - advertiser_to_server: HashMap, - transport_to_owned_connection: HashMap, -} +static ARBITER: Mutex> = Mutex::new(None); /// Initialize the Arbiter pub fn initialize_arbiter() { - *ARBITER.lock().unwrap() = Some(Arbiter::new()); + *ARBITER.lock().unwrap() = Some(IsolationManager::new()); StoreCallbacksFromRust( on_le_connect, @@ -44,108 +36,30 @@ pub fn initialize_arbiter() { /// Acquire the mutex holding the Arbiter and provide a mutable reference to the /// supplied closure -pub fn with_arbiter(f: impl FnOnce(&mut Arbiter) -> T) -> T { +pub fn with_arbiter(f: impl FnOnce(&mut IsolationManager) -> T) -> T { f(ARBITER.lock().unwrap().as_mut().unwrap()) } -impl Arbiter { - /// Constructor - pub fn new() -> Self { - Arbiter { - advertiser_to_server: HashMap::new(), - transport_to_owned_connection: HashMap::new(), - } - } - - /// Link a given GATT server to an LE advertising set, so incoming - /// connections to this advertiser will be visible only by the linked - /// server - pub fn associate_server_with_advertiser( - &mut self, - server_id: ServerId, - advertiser_id: AdvertiserId, - ) { - info!("associating server {server_id:?} with advertising set {advertiser_id:?}"); - let old = self.advertiser_to_server.insert(advertiser_id, server_id); - if let Some(old) = old { - error!("new server {server_id:?} associated with same advertiser {advertiser_id:?}, displacing old server {old:?}"); - } - } +/// Test to see if a buffer contains a valid ATT packet with an opcode we +/// are interested in intercepting (those intended for servers that are isolated) +fn try_parse_att_server_packet( + isolation_manager: &IsolationManager, + tcb_idx: TransportIndex, + packet: Box<[u8]>, +) -> Option { + isolation_manager.get_conn_id(tcb_idx)?; - /// Remove all linked advertising sets from the provided server - pub fn clear_server(&mut self, server_id: ServerId) { - info!("clearing advertisers associated with {server_id:?}"); - self.advertiser_to_server.retain(|_, server| *server != server_id); - } + let att = OwnedAttView::try_parse(packet).ok()?; - /// Clear the server associated with this advertiser, if one exists - pub fn clear_advertiser(&mut self, advertiser_id: AdvertiserId) { - info!("removing server (if any) associated with advertiser {advertiser_id:?}"); - self.advertiser_to_server.remove(&advertiser_id); + if att.view().get_opcode() == AttOpcode::EXCHANGE_MTU_REQUEST { + // special case: this server opcode is handled by legacy stack, and we snoop + // on its handling, since the MTU is shared between the client + server + return None; } - /// Check if this conn_id is currently owned by the Rust stack - pub fn is_connection_isolated(&self, conn_id: ConnectionId) -> bool { - self.transport_to_owned_connection.values().any(|owned_conn_id| *owned_conn_id == conn_id) - } - - /// Test to see if a buffer contains a valid ATT packet with an opcode we - /// are interested in intercepting (those intended for servers that are isolated) - pub fn try_parse_att_server_packet( - &self, - tcb_idx: TransportIndex, - packet: Box<[u8]>, - ) -> Option { - if !self.transport_to_owned_connection.contains_key(&tcb_idx) { - return None; - } - - let att = OwnedAttView::try_parse(packet).ok()?; - - if att.view().get_opcode() == AttOpcode::EXCHANGE_MTU_REQUEST { - // special case: this server opcode is handled by legacy stack, and we snoop - // on its handling, since the MTU is shared between the client + server - return None; - } - - match classify_opcode(att.view().get_opcode()) { - OperationType::Command | OperationType::Request | OperationType::Confirmation => { - Some(att) - } - _ => None, - } - } - - /// Check if an incoming connection should be intercepted and, if so, on - /// what conn_id - pub fn on_le_connect( - &mut self, - tcb_idx: TransportIndex, - advertiser: AdvertiserId, - ) -> Option { - info!( - "processing incoming connection on transport {tcb_idx:?} to advertiser {advertiser:?}" - ); - let server_id = *self.advertiser_to_server.get(&advertiser)?; - info!("connection is isolated to server {server_id:?}"); - - let conn_id = ConnectionId::new(tcb_idx, server_id); - let old = self.transport_to_owned_connection.insert(tcb_idx, conn_id); - if old.is_some() { - error!("new server {server_id:?} on transport {tcb_idx:?} displacing existing registered connection {conn_id:?}") - } - Some(conn_id) - } - - /// Handle a disconnection, if any, and return whether the disconnection was registered - pub fn on_le_disconnect(&mut self, tcb_idx: TransportIndex) -> bool { - info!("processing disconnection on transport {tcb_idx:?}"); - self.transport_to_owned_connection.remove(&tcb_idx).is_some() - } - - /// Look up the conn_id for a given tcb_idx, if present - pub fn get_conn_id(&self, tcb_idx: TransportIndex) -> Option { - self.transport_to_owned_connection.get(&tcb_idx).copied() + match classify_opcode(att.view().get_opcode()) { + OperationType::Command | OperationType::Request | OperationType::Confirmation => Some(att), + _ => None, } } @@ -175,7 +89,7 @@ fn on_le_disconnect(tcb_idx: u8) { fn intercept_packet(tcb_idx: u8, packet: Vec) -> InterceptAction { let tcb_idx = TransportIndex(tcb_idx); if let Some(att) = with_arbiter(|arbiter| { - arbiter.try_parse_att_server_packet(tcb_idx, packet.into_boxed_slice()) + try_parse_att_server_packet(arbiter, tcb_idx, packet.into_boxed_slice()) }) { do_in_rust_thread(move |modules| { trace!("pushing packet to GATT"); @@ -210,7 +124,7 @@ mod test { use super::*; use crate::{ - gatt::ids::AttHandle, + gatt::ids::{AttHandle, ServerId}, packets::{ AttBuilder, AttExchangeMtuRequestBuilder, AttOpcode, AttReadRequestBuilder, Serializable, @@ -218,260 +132,84 @@ mod test { }; const TCB_IDX: TransportIndex = TransportIndex(1); - const ANOTHER_TCB_IDX: TransportIndex = TransportIndex(2); const ADVERTISER_ID: AdvertiserId = AdvertiserId(3); const SERVER_ID: ServerId = ServerId(4); - const CONN_ID: ConnectionId = ConnectionId::new(TCB_IDX, SERVER_ID); - - const ANOTHER_ADVERTISER_ID: AdvertiserId = AdvertiserId(5); - - #[test] - fn test_non_isolated_connect() { - let mut arbiter = Arbiter::new(); - - let conn_id = arbiter.on_le_connect(TCB_IDX, ADVERTISER_ID); - - assert!(conn_id.is_none()) - } - - #[test] - fn test_isolated_connect() { - let mut arbiter = Arbiter::new(); - arbiter.associate_server_with_advertiser(SERVER_ID, ADVERTISER_ID); - - let conn_id = arbiter.on_le_connect(TCB_IDX, ADVERTISER_ID); - - assert_eq!(conn_id, Some(CONN_ID)); - } - - #[test] - fn test_non_isolated_connect_with_isolated_advertiser() { - let mut arbiter = Arbiter::new(); - arbiter.associate_server_with_advertiser(SERVER_ID, ADVERTISER_ID); - - let conn_id = arbiter.on_le_connect(TCB_IDX, ANOTHER_ADVERTISER_ID); - - assert!(conn_id.is_none()) - } - - #[test] - fn test_non_isolated_disconnect() { - let mut arbiter = Arbiter::new(); - arbiter.on_le_connect(TCB_IDX, ADVERTISER_ID); - - let ok = arbiter.on_le_disconnect(TCB_IDX); - - assert!(!ok) - } - - #[test] - fn test_isolated_disconnect() { - let mut arbiter = Arbiter::new(); - arbiter.associate_server_with_advertiser(SERVER_ID, ADVERTISER_ID); - arbiter.on_le_connect(TCB_IDX, ADVERTISER_ID); - - let ok = arbiter.on_le_disconnect(TCB_IDX); - - assert!(ok) - } - - #[test] - fn test_advertiser_id_reuse() { - let mut arbiter = Arbiter::new(); - // start an advertiser associated with the server, then kill the advertiser - arbiter.associate_server_with_advertiser(SERVER_ID, ADVERTISER_ID); - arbiter.clear_advertiser(ADVERTISER_ID); - - // a new advertiser appeared with the same ID and got a connection - let conn_id = arbiter.on_le_connect(TCB_IDX, ADVERTISER_ID); - - // but we should not be isolated since this is a new advertiser reusing the old - // ID - assert!(conn_id.is_none()) - } - - #[test] - fn test_server_closed() { - let mut arbiter = Arbiter::new(); - // start an advertiser associated with the server, then kill the server - arbiter.associate_server_with_advertiser(SERVER_ID, ADVERTISER_ID); - arbiter.clear_server(SERVER_ID); - - // then afterwards we get a connection to this advertiser - let conn_id = arbiter.on_le_connect(TCB_IDX, ADVERTISER_ID); - - // since the server is gone, we should not capture the connection - assert!(conn_id.is_none()) - } - - #[test] - fn test_connection_isolated() { - let mut arbiter = Arbiter::new(); - arbiter.associate_server_with_advertiser(SERVER_ID, ADVERTISER_ID); - let conn_id = arbiter.on_le_connect(TCB_IDX, ADVERTISER_ID).unwrap(); - - let is_isolated = arbiter.is_connection_isolated(conn_id); - - assert!(is_isolated) - } - - #[test] - fn test_connection_isolated_after_advertiser_stops() { - let mut arbiter = Arbiter::new(); - arbiter.associate_server_with_advertiser(SERVER_ID, ADVERTISER_ID); - let conn_id = arbiter.on_le_connect(TCB_IDX, ADVERTISER_ID).unwrap(); - arbiter.clear_advertiser(ADVERTISER_ID); - - let is_isolated = arbiter.is_connection_isolated(conn_id); - - assert!(is_isolated) - } - - #[test] - fn test_connection_isolated_after_server_stops() { - let mut arbiter = Arbiter::new(); - arbiter.associate_server_with_advertiser(SERVER_ID, ADVERTISER_ID); - let conn_id = arbiter.on_le_connect(TCB_IDX, ADVERTISER_ID).unwrap(); - arbiter.clear_server(SERVER_ID); - - let is_isolated = arbiter.is_connection_isolated(conn_id); - - assert!(is_isolated) + fn create_manager_with_isolated_connection( + tcb_idx: TransportIndex, + server_id: ServerId, + ) -> IsolationManager { + let mut isolation_manager = IsolationManager::new(); + isolation_manager.associate_server_with_advertiser(server_id, ADVERTISER_ID); + isolation_manager.on_le_connect(tcb_idx, ADVERTISER_ID); + isolation_manager } #[test] fn test_packet_capture_when_isolated() { - let mut arbiter = Arbiter::new(); - arbiter.associate_server_with_advertiser(SERVER_ID, ADVERTISER_ID); - arbiter.on_le_connect(TCB_IDX, ADVERTISER_ID); + let isolation_manager = create_manager_with_isolated_connection(TCB_IDX, SERVER_ID); let packet = AttBuilder { opcode: AttOpcode::READ_REQUEST, _child_: AttReadRequestBuilder { attribute_handle: AttHandle(1).into() }.into(), }; - let out = arbiter.try_parse_att_server_packet(TCB_IDX, packet.to_vec().unwrap().into()); + let out = try_parse_att_server_packet( + &isolation_manager, + TCB_IDX, + packet.to_vec().unwrap().into(), + ); assert!(out.is_some()); } #[test] fn test_packet_bypass_when_isolated() { - let mut arbiter = Arbiter::new(); - arbiter.associate_server_with_advertiser(SERVER_ID, ADVERTISER_ID); - arbiter.on_le_connect(TCB_IDX, ADVERTISER_ID); + let isolation_manager = create_manager_with_isolated_connection(TCB_IDX, SERVER_ID); let packet = AttBuilder { opcode: AttOpcode::ERROR_RESPONSE, _child_: AttReadRequestBuilder { attribute_handle: AttHandle(1).into() }.into(), }; - let out = arbiter.try_parse_att_server_packet(TCB_IDX, packet.to_vec().unwrap().into()); + let out = try_parse_att_server_packet( + &isolation_manager, + TCB_IDX, + packet.to_vec().unwrap().into(), + ); assert!(out.is_none()); } #[test] fn test_mtu_bypass() { - let mut arbiter = Arbiter::new(); - arbiter.associate_server_with_advertiser(SERVER_ID, ADVERTISER_ID); - arbiter.on_le_connect(TCB_IDX, ADVERTISER_ID); + let isolation_manager = create_manager_with_isolated_connection(TCB_IDX, SERVER_ID); let packet = AttBuilder { opcode: AttOpcode::EXCHANGE_MTU_REQUEST, _child_: AttExchangeMtuRequestBuilder { mtu: 64 }.into(), }; - let out = arbiter.try_parse_att_server_packet(TCB_IDX, packet.to_vec().unwrap().into()); + let out = try_parse_att_server_packet( + &isolation_manager, + TCB_IDX, + packet.to_vec().unwrap().into(), + ); assert!(out.is_none()); } #[test] fn test_packet_bypass_when_not_isolated() { - let mut arbiter = Arbiter::new(); - arbiter.associate_server_with_advertiser(SERVER_ID, ADVERTISER_ID); - arbiter.on_le_connect(TCB_IDX, ANOTHER_ADVERTISER_ID); - let packet = AttBuilder { - opcode: AttOpcode::READ_REQUEST, - _child_: AttReadRequestBuilder { attribute_handle: AttHandle(1).into() }.into(), - }; - - let out = arbiter.try_parse_att_server_packet(TCB_IDX, packet.to_vec().unwrap().into()); - - assert!(out.is_none()); - } - - #[test] - fn test_packet_bypass_when_different_connection() { - let mut arbiter = Arbiter::new(); - arbiter.associate_server_with_advertiser(SERVER_ID, ADVERTISER_ID); - arbiter.on_le_connect(TCB_IDX, ADVERTISER_ID); - arbiter.on_le_connect(ANOTHER_TCB_IDX, ANOTHER_ADVERTISER_ID); + let isolation_manager = IsolationManager::new(); let packet = AttBuilder { opcode: AttOpcode::READ_REQUEST, _child_: AttReadRequestBuilder { attribute_handle: AttHandle(1).into() }.into(), }; - let out = - arbiter.try_parse_att_server_packet(ANOTHER_TCB_IDX, packet.to_vec().unwrap().into()); + let out = try_parse_att_server_packet( + &isolation_manager, + TCB_IDX, + packet.to_vec().unwrap().into(), + ); assert!(out.is_none()); } - - #[test] - fn test_packet_capture_when_isolated_after_advertiser_closes() { - let mut arbiter = Arbiter::new(); - arbiter.associate_server_with_advertiser(SERVER_ID, ADVERTISER_ID); - arbiter.on_le_connect(TCB_IDX, ADVERTISER_ID); - let packet = AttBuilder { - opcode: AttOpcode::READ_REQUEST, - _child_: AttReadRequestBuilder { attribute_handle: AttHandle(1).into() }.into(), - }; - arbiter.clear_advertiser(ADVERTISER_ID); - - let out = arbiter.try_parse_att_server_packet(TCB_IDX, packet.to_vec().unwrap().into()); - - assert!(out.is_some()); - } - - #[test] - fn test_packet_capture_when_isolated_after_server_closes() { - let mut arbiter = Arbiter::new(); - arbiter.associate_server_with_advertiser(SERVER_ID, ADVERTISER_ID); - arbiter.on_le_connect(TCB_IDX, ADVERTISER_ID); - let packet = AttBuilder { - opcode: AttOpcode::READ_REQUEST, - _child_: AttReadRequestBuilder { attribute_handle: AttHandle(1).into() }.into(), - }; - arbiter.clear_server(SERVER_ID); - - let out = arbiter.try_parse_att_server_packet(TCB_IDX, packet.to_vec().unwrap().into()); - - assert!(out.is_some()); - } - - #[test] - fn test_not_isolated_after_disconnection() { - let mut arbiter = Arbiter::new(); - arbiter.associate_server_with_advertiser(SERVER_ID, ADVERTISER_ID); - arbiter.on_le_connect(TCB_IDX, ADVERTISER_ID); - - arbiter.on_le_disconnect(TCB_IDX); - let is_isolated = arbiter.is_connection_isolated(CONN_ID); - - assert!(!is_isolated); - } - - #[test] - fn test_tcb_idx_reuse_after_isolated() { - let mut arbiter = Arbiter::new(); - arbiter.associate_server_with_advertiser(SERVER_ID, ADVERTISER_ID); - arbiter.on_le_connect(TCB_IDX, ADVERTISER_ID); - arbiter.clear_advertiser(ADVERTISER_ID); - arbiter.on_le_disconnect(TCB_IDX); - - let conn_id = arbiter.on_le_connect(TCB_IDX, ADVERTISER_ID); - - assert!(conn_id.is_none()); - assert!(!arbiter.is_connection_isolated(CONN_ID)); - } } diff --git a/system/rust/src/gatt/server.rs b/system/rust/src/gatt/server.rs index 09fd87964b7..132779cf08c 100644 --- a/system/rust/src/gatt/server.rs +++ b/system/rust/src/gatt/server.rs @@ -10,6 +10,7 @@ pub mod services; mod transactions; mod command_handler; +pub mod isolation_manager; #[cfg(test)] mod test; diff --git a/system/rust/src/gatt/server/isolation_manager.rs b/system/rust/src/gatt/server/isolation_manager.rs new file mode 100644 index 00000000000..ea7fbc24c00 --- /dev/null +++ b/system/rust/src/gatt/server/isolation_manager.rs @@ -0,0 +1,242 @@ +//! This module determines which GATT server should be exposed to a given connection. + +use std::collections::HashMap; + +use log::{error, info}; + +use crate::gatt::ids::{AdvertiserId, ConnectionId, ServerId, TransportIndex}; + +/// This class is responsible for tracking which connections and advertising we +/// own, and using this information to decide what servers should be exposed to +/// a given connetion. +#[derive(Default)] +pub struct IsolationManager { + advertiser_to_server: HashMap, + transport_to_owned_connection: HashMap, +} + +impl IsolationManager { + /// Constructor + pub fn new() -> Self { + IsolationManager { + advertiser_to_server: HashMap::new(), + transport_to_owned_connection: HashMap::new(), + } + } + + /// Link a given GATT server to an LE advertising set, so incoming + /// connections to this advertiser will be visible only by the linked + /// server + pub fn associate_server_with_advertiser( + &mut self, + server_id: ServerId, + advertiser_id: AdvertiserId, + ) { + info!("associating server {server_id:?} with advertising set {advertiser_id:?}"); + let old = self.advertiser_to_server.insert(advertiser_id, server_id); + if let Some(old) = old { + error!("new server {server_id:?} associated with same advertiser {advertiser_id:?}, displacing old server {old:?}"); + } + } + + /// Remove all linked advertising sets from the provided server + pub fn clear_server(&mut self, server_id: ServerId) { + info!("clearing advertisers associated with {server_id:?}"); + self.advertiser_to_server.retain(|_, server| *server != server_id); + } + + /// Clear the server associated with this advertiser, if one exists + pub fn clear_advertiser(&mut self, advertiser_id: AdvertiserId) { + info!("removing server (if any) associated with advertiser {advertiser_id:?}"); + self.advertiser_to_server.remove(&advertiser_id); + } + + /// Check if this conn_id is currently owned by the Rust stack + pub fn is_connection_isolated(&self, conn_id: ConnectionId) -> bool { + self.transport_to_owned_connection.values().any(|owned_conn_id| *owned_conn_id == conn_id) + } + + /// Look up the conn_id for a given tcb_idx, if present + pub fn get_conn_id(&self, tcb_idx: TransportIndex) -> Option { + self.transport_to_owned_connection.get(&tcb_idx).copied() + } + + /// Handles an incoming connection, and reports if it should be isolated to a given connection ID + pub fn on_le_connect( + &mut self, + tcb_idx: TransportIndex, + advertiser: AdvertiserId, + ) -> Option { + info!( + "processing incoming connection on transport {tcb_idx:?} to advertiser {advertiser:?}" + ); + let server_id = *self.advertiser_to_server.get(&advertiser)?; + info!("connection is isolated to server {server_id:?}"); + + let conn_id = ConnectionId::new(tcb_idx, server_id); + let old = self.transport_to_owned_connection.insert(tcb_idx, conn_id); + if old.is_some() { + error!("new server {server_id:?} on transport {tcb_idx:?} displacing existing registered connection {conn_id:?}") + } + Some(conn_id) + } + + /// Handle a disconnection, if any, and return whether the disconnection was registered + pub fn on_le_disconnect(&mut self, tcb_idx: TransportIndex) -> bool { + info!("processing disconnection on transport {tcb_idx:?}"); + self.transport_to_owned_connection.remove(&tcb_idx).is_some() + } +} + +#[cfg(test)] +mod test { + use super::*; + + const TCB_IDX: TransportIndex = TransportIndex(1); + const ADVERTISER_ID: AdvertiserId = AdvertiserId(3); + const SERVER_ID: ServerId = ServerId(4); + + const CONN_ID: ConnectionId = ConnectionId::new(TCB_IDX, SERVER_ID); + + const ANOTHER_ADVERTISER_ID: AdvertiserId = AdvertiserId(5); + + #[test] + fn test_non_isolated_connect() { + let mut isolation_manager = IsolationManager::new(); + + let conn_id = isolation_manager.on_le_connect(TCB_IDX, ADVERTISER_ID); + + assert!(conn_id.is_none()) + } + + #[test] + fn test_isolated_connect() { + let mut isolation_manager = IsolationManager::new(); + isolation_manager.associate_server_with_advertiser(SERVER_ID, ADVERTISER_ID); + + let conn_id = isolation_manager.on_le_connect(TCB_IDX, ADVERTISER_ID); + + assert_eq!(conn_id, Some(CONN_ID)); + } + + #[test] + fn test_non_isolated_connect_with_isolated_advertiser() { + let mut isolation_manager = IsolationManager::new(); + isolation_manager.associate_server_with_advertiser(SERVER_ID, ADVERTISER_ID); + + let conn_id = isolation_manager.on_le_connect(TCB_IDX, ANOTHER_ADVERTISER_ID); + + assert!(conn_id.is_none()) + } + + #[test] + fn test_non_isolated_disconnect() { + let mut isolation_manager = IsolationManager::new(); + isolation_manager.on_le_connect(TCB_IDX, ADVERTISER_ID); + + let ok = isolation_manager.on_le_disconnect(TCB_IDX); + + assert!(!ok) + } + + #[test] + fn test_isolated_disconnect() { + let mut isolation_manager = IsolationManager::new(); + isolation_manager.associate_server_with_advertiser(SERVER_ID, ADVERTISER_ID); + isolation_manager.on_le_connect(TCB_IDX, ADVERTISER_ID); + + let ok = isolation_manager.on_le_disconnect(TCB_IDX); + + assert!(ok) + } + + #[test] + fn test_advertiser_id_reuse() { + let mut isolation_manager = IsolationManager::new(); + // start an advertiser associated with the server, then kill the advertiser + isolation_manager.associate_server_with_advertiser(SERVER_ID, ADVERTISER_ID); + isolation_manager.clear_advertiser(ADVERTISER_ID); + + // a new advertiser appeared with the same ID and got a connection + let conn_id = isolation_manager.on_le_connect(TCB_IDX, ADVERTISER_ID); + + // but we should not be isolated since this is a new advertiser reusing the old + // ID + assert!(conn_id.is_none()) + } + + #[test] + fn test_server_closed() { + let mut isolation_manager = IsolationManager::new(); + // start an advertiser associated with the server, then kill the server + isolation_manager.associate_server_with_advertiser(SERVER_ID, ADVERTISER_ID); + isolation_manager.clear_server(SERVER_ID); + + // then afterwards we get a connection to this advertiser + let conn_id = isolation_manager.on_le_connect(TCB_IDX, ADVERTISER_ID); + + // since the server is gone, we should not capture the connection + assert!(conn_id.is_none()) + } + + #[test] + fn test_connection_isolated() { + let mut isolation_manager = IsolationManager::new(); + isolation_manager.associate_server_with_advertiser(SERVER_ID, ADVERTISER_ID); + let conn_id = isolation_manager.on_le_connect(TCB_IDX, ADVERTISER_ID).unwrap(); + + let is_isolated = isolation_manager.is_connection_isolated(conn_id); + + assert!(is_isolated) + } + + #[test] + fn test_connection_isolated_after_advertiser_stops() { + let mut isolation_manager = IsolationManager::new(); + isolation_manager.associate_server_with_advertiser(SERVER_ID, ADVERTISER_ID); + let conn_id = isolation_manager.on_le_connect(TCB_IDX, ADVERTISER_ID).unwrap(); + isolation_manager.clear_advertiser(ADVERTISER_ID); + + let is_isolated = isolation_manager.is_connection_isolated(conn_id); + + assert!(is_isolated) + } + + #[test] + fn test_connection_isolated_after_server_stops() { + let mut isolation_manager = IsolationManager::new(); + isolation_manager.associate_server_with_advertiser(SERVER_ID, ADVERTISER_ID); + let conn_id = isolation_manager.on_le_connect(TCB_IDX, ADVERTISER_ID).unwrap(); + isolation_manager.clear_server(SERVER_ID); + + let is_isolated = isolation_manager.is_connection_isolated(conn_id); + + assert!(is_isolated) + } + + #[test] + fn test_not_isolated_after_disconnection() { + let mut isolation_manager = IsolationManager::new(); + isolation_manager.associate_server_with_advertiser(SERVER_ID, ADVERTISER_ID); + isolation_manager.on_le_connect(TCB_IDX, ADVERTISER_ID); + + isolation_manager.on_le_disconnect(TCB_IDX); + let is_isolated = isolation_manager.is_connection_isolated(CONN_ID); + + assert!(!is_isolated); + } + + #[test] + fn test_tcb_idx_reuse_after_isolated() { + let mut isolation_manager = IsolationManager::new(); + isolation_manager.associate_server_with_advertiser(SERVER_ID, ADVERTISER_ID); + isolation_manager.on_le_connect(TCB_IDX, ADVERTISER_ID); + isolation_manager.clear_advertiser(ADVERTISER_ID); + isolation_manager.on_le_disconnect(TCB_IDX); + + let conn_id = isolation_manager.on_le_connect(TCB_IDX, ADVERTISER_ID); + + assert!(conn_id.is_none()); + assert!(!isolation_manager.is_connection_isolated(CONN_ID)); + } +} -- GitLab From 34ecd8fefa0a1c02bc53ac326af5719ade54a762 Mon Sep 17 00:00:00 2001 From: Rahul Arya Date: Mon, 8 May 2023 21:44:54 +0000 Subject: [PATCH 0035/2405] [GATT Server] Simplify IsolationManager interface Some methods were redundant and existed only for FFI. Now that the module is decoupled from FFI, I'm pushing the complexity to the call-site and simplifying the core API. Test: unit + CTS multi-device Bug: 274945531 Change-Id: I1e5591b01a2edca37904baf7f7e186d7cc84ee38 --- system/rust/src/gatt/arbiter.rs | 12 ++- .../rust/src/gatt/server/isolation_manager.rs | 87 +++++++------------ 2 files changed, 40 insertions(+), 59 deletions(-) diff --git a/system/rust/src/gatt/arbiter.rs b/system/rust/src/gatt/arbiter.rs index d4a113f6b12..c28443ba68d 100644 --- a/system/rust/src/gatt/arbiter.rs +++ b/system/rust/src/gatt/arbiter.rs @@ -64,8 +64,11 @@ fn try_parse_att_server_packet( } fn on_le_connect(tcb_idx: u8, advertiser: u8) { + let tcb_idx = TransportIndex(tcb_idx); + let advertiser = AdvertiserId(advertiser); if let Some(conn_id) = with_arbiter(|arbiter| { - arbiter.on_le_connect(TransportIndex(tcb_idx), AdvertiserId(advertiser)) + arbiter.on_le_connect(tcb_idx, advertiser); + arbiter.get_conn_id(tcb_idx) }) { do_in_rust_thread(move |modules| { if let Err(err) = modules.gatt_module.on_le_connect(conn_id) { @@ -77,7 +80,12 @@ fn on_le_connect(tcb_idx: u8, advertiser: u8) { fn on_le_disconnect(tcb_idx: u8) { let tcb_idx = TransportIndex(tcb_idx); - if with_arbiter(|arbiter| arbiter.on_le_disconnect(tcb_idx)) { + let was_isolated = with_arbiter(|arbiter| { + let was_isolated = arbiter.get_conn_id(tcb_idx).is_some(); + arbiter.on_le_disconnect(tcb_idx); + was_isolated + }); + if was_isolated { do_in_rust_thread(move |modules| { if let Err(err) = modules.gatt_module.on_le_disconnect(tcb_idx) { error!("{err:?}") diff --git a/system/rust/src/gatt/server/isolation_manager.rs b/system/rust/src/gatt/server/isolation_manager.rs index ea7fbc24c00..31db3cbe235 100644 --- a/system/rust/src/gatt/server/isolation_manager.rs +++ b/system/rust/src/gatt/server/isolation_manager.rs @@ -61,30 +61,27 @@ impl IsolationManager { self.transport_to_owned_connection.get(&tcb_idx).copied() } - /// Handles an incoming connection, and reports if it should be isolated to a given connection ID - pub fn on_le_connect( - &mut self, - tcb_idx: TransportIndex, - advertiser: AdvertiserId, - ) -> Option { + /// Handles an incoming connection + pub fn on_le_connect(&mut self, tcb_idx: TransportIndex, advertiser: AdvertiserId) { info!( "processing incoming connection on transport {tcb_idx:?} to advertiser {advertiser:?}" ); - let server_id = *self.advertiser_to_server.get(&advertiser)?; - info!("connection is isolated to server {server_id:?}"); - - let conn_id = ConnectionId::new(tcb_idx, server_id); - let old = self.transport_to_owned_connection.insert(tcb_idx, conn_id); - if old.is_some() { - error!("new server {server_id:?} on transport {tcb_idx:?} displacing existing registered connection {conn_id:?}") + if let Some(server_id) = self.advertiser_to_server.get(&advertiser).copied() { + info!("connection is isolated to server {server_id:?}"); + let conn_id = ConnectionId::new(tcb_idx, server_id); + let old = self.transport_to_owned_connection.insert(tcb_idx, conn_id); + if old.is_some() { + error!("new server {server_id:?} on transport {tcb_idx:?} displacing existing registered connection {conn_id:?}") + } + } else { + info!("connection can access all servers"); } - Some(conn_id) } - /// Handle a disconnection, if any, and return whether the disconnection was registered - pub fn on_le_disconnect(&mut self, tcb_idx: TransportIndex) -> bool { + /// Handle a disconnection + pub fn on_le_disconnect(&mut self, tcb_idx: TransportIndex) { info!("processing disconnection on transport {tcb_idx:?}"); - self.transport_to_owned_connection.remove(&tcb_idx).is_some() + self.transport_to_owned_connection.remove(&tcb_idx); } } @@ -104,7 +101,8 @@ mod test { fn test_non_isolated_connect() { let mut isolation_manager = IsolationManager::new(); - let conn_id = isolation_manager.on_le_connect(TCB_IDX, ADVERTISER_ID); + isolation_manager.on_le_connect(TCB_IDX, ADVERTISER_ID); + let conn_id = isolation_manager.get_conn_id(TCB_IDX); assert!(conn_id.is_none()) } @@ -114,7 +112,8 @@ mod test { let mut isolation_manager = IsolationManager::new(); isolation_manager.associate_server_with_advertiser(SERVER_ID, ADVERTISER_ID); - let conn_id = isolation_manager.on_le_connect(TCB_IDX, ADVERTISER_ID); + isolation_manager.on_le_connect(TCB_IDX, ADVERTISER_ID); + let conn_id = isolation_manager.get_conn_id(TCB_IDX); assert_eq!(conn_id, Some(CONN_ID)); } @@ -124,32 +123,12 @@ mod test { let mut isolation_manager = IsolationManager::new(); isolation_manager.associate_server_with_advertiser(SERVER_ID, ADVERTISER_ID); - let conn_id = isolation_manager.on_le_connect(TCB_IDX, ANOTHER_ADVERTISER_ID); + isolation_manager.on_le_connect(TCB_IDX, ANOTHER_ADVERTISER_ID); + let conn_id = isolation_manager.get_conn_id(TCB_IDX); assert!(conn_id.is_none()) } - #[test] - fn test_non_isolated_disconnect() { - let mut isolation_manager = IsolationManager::new(); - isolation_manager.on_le_connect(TCB_IDX, ADVERTISER_ID); - - let ok = isolation_manager.on_le_disconnect(TCB_IDX); - - assert!(!ok) - } - - #[test] - fn test_isolated_disconnect() { - let mut isolation_manager = IsolationManager::new(); - isolation_manager.associate_server_with_advertiser(SERVER_ID, ADVERTISER_ID); - isolation_manager.on_le_connect(TCB_IDX, ADVERTISER_ID); - - let ok = isolation_manager.on_le_disconnect(TCB_IDX); - - assert!(ok) - } - #[test] fn test_advertiser_id_reuse() { let mut isolation_manager = IsolationManager::new(); @@ -158,7 +137,8 @@ mod test { isolation_manager.clear_advertiser(ADVERTISER_ID); // a new advertiser appeared with the same ID and got a connection - let conn_id = isolation_manager.on_le_connect(TCB_IDX, ADVERTISER_ID); + isolation_manager.on_le_connect(TCB_IDX, ADVERTISER_ID); + let conn_id = isolation_manager.get_conn_id(TCB_IDX); // but we should not be isolated since this is a new advertiser reusing the old // ID @@ -173,28 +153,19 @@ mod test { isolation_manager.clear_server(SERVER_ID); // then afterwards we get a connection to this advertiser - let conn_id = isolation_manager.on_le_connect(TCB_IDX, ADVERTISER_ID); + isolation_manager.on_le_connect(TCB_IDX, ADVERTISER_ID); + let conn_id = isolation_manager.get_conn_id(TCB_IDX); // since the server is gone, we should not capture the connection assert!(conn_id.is_none()) } - #[test] - fn test_connection_isolated() { - let mut isolation_manager = IsolationManager::new(); - isolation_manager.associate_server_with_advertiser(SERVER_ID, ADVERTISER_ID); - let conn_id = isolation_manager.on_le_connect(TCB_IDX, ADVERTISER_ID).unwrap(); - - let is_isolated = isolation_manager.is_connection_isolated(conn_id); - - assert!(is_isolated) - } - #[test] fn test_connection_isolated_after_advertiser_stops() { let mut isolation_manager = IsolationManager::new(); isolation_manager.associate_server_with_advertiser(SERVER_ID, ADVERTISER_ID); - let conn_id = isolation_manager.on_le_connect(TCB_IDX, ADVERTISER_ID).unwrap(); + isolation_manager.on_le_connect(TCB_IDX, ADVERTISER_ID); + let conn_id = isolation_manager.get_conn_id(TCB_IDX).unwrap(); isolation_manager.clear_advertiser(ADVERTISER_ID); let is_isolated = isolation_manager.is_connection_isolated(conn_id); @@ -206,7 +177,8 @@ mod test { fn test_connection_isolated_after_server_stops() { let mut isolation_manager = IsolationManager::new(); isolation_manager.associate_server_with_advertiser(SERVER_ID, ADVERTISER_ID); - let conn_id = isolation_manager.on_le_connect(TCB_IDX, ADVERTISER_ID).unwrap(); + isolation_manager.on_le_connect(TCB_IDX, ADVERTISER_ID); + let conn_id = isolation_manager.get_conn_id(TCB_IDX).unwrap(); isolation_manager.clear_server(SERVER_ID); let is_isolated = isolation_manager.is_connection_isolated(conn_id); @@ -234,7 +206,8 @@ mod test { isolation_manager.clear_advertiser(ADVERTISER_ID); isolation_manager.on_le_disconnect(TCB_IDX); - let conn_id = isolation_manager.on_le_connect(TCB_IDX, ADVERTISER_ID); + isolation_manager.on_le_connect(TCB_IDX, ADVERTISER_ID); + let conn_id = isolation_manager.get_conn_id(TCB_IDX); assert!(conn_id.is_none()); assert!(!isolation_manager.is_connection_isolated(CONN_ID)); -- GitLab From 927143d67e00ea91d80dc8e316c32f1e30a73e8a Mon Sep 17 00:00:00 2001 From: Abhishek Pandit-Subedi Date: Tue, 9 May 2023 11:58:16 -0700 Subject: [PATCH 0036/2405] net_test_stack_a2dp_codecs_native: Emit LOG_INFO Bug: 276385040 Test: atest net_test_stack_a2dp_codecs_native Tag: #bugfix Change-Id: Ia747543142e57701e0c18e8be8270df1f312cbd5 --- system/stack/test/a2dp/a2dp_aac_unittest.cc | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/system/stack/test/a2dp/a2dp_aac_unittest.cc b/system/stack/test/a2dp/a2dp_aac_unittest.cc index 47d8a10bfd9..54d89b46369 100644 --- a/system/stack/test/a2dp/a2dp_aac_unittest.cc +++ b/system/stack/test/a2dp/a2dp_aac_unittest.cc @@ -189,7 +189,7 @@ TEST_F(A2dpAacTest, a2dp_enqueue_cb_is_invoked) { return len; }; auto enqueue_cb = +[](BT_HDR* p_buf, size_t frames_n, uint32_t len) -> bool { - LOG_DEBUG("%s", kEnqueueCallbackIsInvoked); + LOG_INFO("%s", kEnqueueCallbackIsInvoked); osi_free(p_buf); return false; }; @@ -215,7 +215,7 @@ TEST_F(A2dpAacTest, decoded_data_cb_not_invoked_when_empty_packet) { TEST_F(A2dpAacTest, decoded_data_cb_invoked) { log_capture_ = std::make_unique(); auto data_cb = +[](uint8_t* p_buf, uint32_t len) { - LOG_DEBUG("%s", kDecodedDataCallbackIsInvoked); + LOG_INFO("%s", kDecodedDataCallbackIsInvoked); }; InitializeDecoder(data_cb); @@ -227,7 +227,7 @@ TEST_F(A2dpAacTest, decoded_data_cb_invoked) { }; auto enqueue_cb = +[](BT_HDR* p_buf, size_t frames_n, uint32_t len) -> bool { packet = p_buf; - LOG_DEBUG("%s", kEnqueueCallbackIsInvoked); + LOG_INFO("%s", kEnqueueCallbackIsInvoked); return false; }; InitializeEncoder(true, read_cb, enqueue_cb); -- GitLab From 063d296613af96ced38daeee407d8bb58b4180d3 Mon Sep 17 00:00:00 2001 From: Rahul Arya Date: Tue, 9 May 2023 21:21:14 +0000 Subject: [PATCH 0037/2405] Fix use-after-free in HID callback Caused crashlooping on MTE builds. Ignore-AOSP-First: security Test: manual Bug: 281346084 Change-Id: I94ecdfe3f091a2b2969471c316035e3cea64773c --- system/btif/src/btif_hh.cc | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/system/btif/src/btif_hh.cc b/system/btif/src/btif_hh.cc index 451cee10e54..4661708f971 100644 --- a/system/btif/src/btif_hh.cc +++ b/system/btif/src/btif_hh.cc @@ -671,11 +671,11 @@ bt_status_t btif_hh_connect(const RawAddress* bd_addr) { BTA_HhOpen(*bd_addr); do_in_jni_thread(base::Bind( - [](RawAddress* bd_addr) { - HAL_CBACK(bt_hh_callbacks, connection_state_cb, bd_addr, + [](RawAddress bd_addr) { + HAL_CBACK(bt_hh_callbacks, connection_state_cb, &bd_addr, BTHH_CONN_STATE_CONNECTING); }, - (RawAddress*)bd_addr)); + *bd_addr)); return BT_STATUS_SUCCESS; } -- GitLab From d449abc5a7d38583cb07d2bcbdafedb4885ae718 Mon Sep 17 00:00:00 2001 From: Bill Yi Date: Tue, 9 May 2023 18:46:32 -0700 Subject: [PATCH 0038/2405] Import translations. DO NOT MERGE ANYWHERE Auto-generated-cl: translation import Change-Id: If8042a61e151884af847f8221f8eea6feaed50c6 --- android/app/res/values-fi/strings.xml | 2 +- android/app/res/values-kn/strings.xml | 2 +- android/app/res/values-or/strings.xml | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/android/app/res/values-fi/strings.xml b/android/app/res/values-fi/strings.xml index dadce8f0870..7df0835d2ee 100644 --- a/android/app/res/values-fi/strings.xml +++ b/android/app/res/values-fi/strings.xml @@ -106,7 +106,7 @@ "%1$s lähetys valmis." "Saapuvat siirrot" "Lähtevät siirrot" - "Lähetyshistoria on tyhjä." + "Lataushistoria on tyhjä." "Koko luettelo tyhjennetään." "Bluetooth-jako: Lähetetyt tiedostot" "Bluetooth-jako: Vastaanotetut tiedostot" diff --git a/android/app/res/values-kn/strings.xml b/android/app/res/values-kn/strings.xml index 878f9135708..d7a5cbecc34 100644 --- a/android/app/res/values-kn/strings.xml +++ b/android/app/res/values-kn/strings.xml @@ -28,7 +28,7 @@ "ಏರ್‌ಪ್ಲೇನ್‌ ಮೋಡ್‌ನಲ್ಲಿ ನೀವು ಬ್ಲೂಟೂತ್‌‌ ಬಳಸಲು ಸಾಧ್ಯವಿಲ್ಲ." "ಬ್ಲೂಟೂತ್‌ ಸೇವೆಗಳನ್ನು ಬಳಸಲು, ಮೊದಲು ನೀವದನ್ನು ಆನ್‌ ಮಾಡಬೇಕು." - "ಇದೀಗ ಬ್ಲೂಟೂತ್‌ ಆನ್‌ ಮಾಡುವುದೇ?" + "ಇದೀಗ ಬ್ಲೂಟೂತ್‌ ಆನ್‌ ಮಾಡಬೇಕೆ?" "ರದ್ದುಮಾಡಿ" "ಆನ್‌ ಮಾಡಿ" "ಫೈಲ್ ವರ್ಗಾವಣೆ" diff --git a/android/app/res/values-or/strings.xml b/android/app/res/values-or/strings.xml index a9e5cdbf1ce..08e68d7097c 100644 --- a/android/app/res/values-or/strings.xml +++ b/android/app/res/values-or/strings.xml @@ -24,7 +24,7 @@ "ଅଜଣା ଡିଭାଇସ୍" "ଅଜଣା" "ପ୍ରଦାନ କରାଯାଇନାହିଁ" - "ଏରୋପ୍ଲେନ ମୋଡ" + "ଏୟାରପ୍ଲେନ ମୋଡ" "ଆପଣ, ଏୟାରପ୍ଲେନ୍‌ ମୋଡ୍‌ରେ ବ୍ଲୁଟୂଥ୍‍‌ ବ୍ୟବହାର କରିପାରିବେ ନାହିଁ।" "ବ୍ଲୁଟୂଥ୍‍‌ ସେବା ବ୍ୟବହାର କରିବା ପାଇଁ, ଆପଣଙ୍କୁ ପ୍ରଥମେ ବ୍ଲୁଟୂଥ୍‍‌ ଅନ୍‌ କରିବାକୁ ପଡ଼ିବ।" -- GitLab From 9066159c6aff46c222f996794686b5bec09d457f Mon Sep 17 00:00:00 2001 From: Rahul Arya Date: Wed, 10 May 2023 18:56:24 +0000 Subject: [PATCH 0039/2405] [GATT Server] Expose IsolationManager from GATT server module The IsolationManager is made a submodule of the GATT server, so we can query it to figure out what services are exposed to each connection. It is temporarily also available directly from FFI, solely for the purpose of arbitration. This will be removed once the Rust server is used for 100% of GATT server operations. Test: unit + CTS multi-device Bug: 274945531 Change-Id: Idc3cdd78ec2435a7a286413d7b1ebaae83a8f07a --- system/rust/Android.bp | 1 + system/rust/Cargo.toml | 1 + system/rust/src/gatt/arbiter.rs | 30 ++++----- system/rust/src/gatt/ffi.rs | 33 ++++++---- system/rust/src/gatt/server.rs | 54 ++++++++++++--- .../rust/src/gatt/server/isolation_manager.rs | 65 ++++++++++++------- system/rust/src/lib.rs | 6 +- system/rust/tests/gatt_server_test.rs | 56 ++++++++++++++-- 8 files changed, 171 insertions(+), 75 deletions(-) diff --git a/system/rust/Android.bp b/system/rust/Android.bp index 153d5e9490a..06a2885e113 100644 --- a/system/rust/Android.bp +++ b/system/rust/Android.bp @@ -39,6 +39,7 @@ rust_defaults { "libbt_common", "libcxx", "liblog_rust", + "libonce_cell", "libscopeguard", // needed to work around duplicate symbols diff --git a/system/rust/Cargo.toml b/system/rust/Cargo.toml index 3067f27d1e2..87429e132c4 100644 --- a/system/rust/Cargo.toml +++ b/system/rust/Cargo.toml @@ -34,6 +34,7 @@ async-trait = "*" tokio-test = "0.4.2" tokio = { version = "1.23.0", features = ["macros"] } scopeguard = "1.1.0" +once_cell = "1.17.1" [lib] crate-type = ["rlib"] diff --git a/system/rust/src/gatt/arbiter.rs b/system/rust/src/gatt/arbiter.rs index c28443ba68d..b6b25a10c6c 100644 --- a/system/rust/src/gatt/arbiter.rs +++ b/system/rust/src/gatt/arbiter.rs @@ -1,9 +1,10 @@ //! This module handles "arbitration" of ATT packets, to determine whether they //! should be handled by the primary stack or by the Rust stack -use std::sync::Mutex; +use std::sync::{Arc, Mutex}; use log::{error, trace}; +use once_cell::sync::OnceCell; use crate::{ do_in_rust_thread, @@ -18,11 +19,12 @@ use super::{ server::isolation_manager::IsolationManager, }; -static ARBITER: Mutex> = Mutex::new(None); +static ARBITER: OnceCell>> = OnceCell::new(); /// Initialize the Arbiter -pub fn initialize_arbiter() { - *ARBITER.lock().unwrap() = Some(IsolationManager::new()); +pub fn initialize_arbiter() -> Arc> { + let arbiter = Arc::new(Mutex::new(IsolationManager::new())); + ARBITER.set(arbiter.clone()).unwrap_or_else(|_| panic!("Rust stack should only start up once")); StoreCallbacksFromRust( on_le_connect, @@ -32,12 +34,14 @@ pub fn initialize_arbiter() { |tcb_idx, mtu| on_mtu_event(TransportIndex(tcb_idx), MtuEvent::IncomingResponse(mtu)), |tcb_idx, mtu| on_mtu_event(TransportIndex(tcb_idx), MtuEvent::IncomingRequest(mtu)), ); + + arbiter } /// Acquire the mutex holding the Arbiter and provide a mutable reference to the /// supplied closure pub fn with_arbiter(f: impl FnOnce(&mut IsolationManager) -> T) -> T { - f(ARBITER.lock().unwrap().as_mut().unwrap()) + f(ARBITER.get().unwrap().lock().as_mut().unwrap()) } /// Test to see if a buffer contains a valid ATT packet with an opcode we @@ -66,12 +70,10 @@ fn try_parse_att_server_packet( fn on_le_connect(tcb_idx: u8, advertiser: u8) { let tcb_idx = TransportIndex(tcb_idx); let advertiser = AdvertiserId(advertiser); - if let Some(conn_id) = with_arbiter(|arbiter| { - arbiter.on_le_connect(tcb_idx, advertiser); - arbiter.get_conn_id(tcb_idx) - }) { + let is_isolated = with_arbiter(|arbiter| arbiter.is_advertiser_isolated(advertiser)); + if is_isolated { do_in_rust_thread(move |modules| { - if let Err(err) = modules.gatt_module.on_le_connect(conn_id) { + if let Err(err) = modules.gatt_module.on_le_connect(tcb_idx, Some(advertiser)) { error!("{err:?}") } }) @@ -80,11 +82,7 @@ fn on_le_connect(tcb_idx: u8, advertiser: u8) { fn on_le_disconnect(tcb_idx: u8) { let tcb_idx = TransportIndex(tcb_idx); - let was_isolated = with_arbiter(|arbiter| { - let was_isolated = arbiter.get_conn_id(tcb_idx).is_some(); - arbiter.on_le_disconnect(tcb_idx); - was_isolated - }); + let was_isolated = with_arbiter(|arbiter| arbiter.get_conn_id(tcb_idx).is_some()); if was_isolated { do_in_rust_thread(move |modules| { if let Err(err) = modules.gatt_module.on_le_disconnect(tcb_idx) { @@ -149,7 +147,7 @@ mod test { ) -> IsolationManager { let mut isolation_manager = IsolationManager::new(); isolation_manager.associate_server_with_advertiser(server_id, ADVERTISER_ID); - isolation_manager.on_le_connect(tcb_idx, ADVERTISER_ID); + isolation_manager.on_le_connect(tcb_idx, Some(ADVERTISER_ID)); isolation_manager } diff --git a/system/rust/src/gatt/ffi.rs b/system/rust/src/gatt/ffi.rs index 8f86efe4ca1..57543bb4fcb 100644 --- a/system/rust/src/gatt/ffi.rs +++ b/system/rust/src/gatt/ffi.rs @@ -21,7 +21,7 @@ use crate::{ }; use super::{ - arbiter::{self, with_arbiter}, + arbiter::with_arbiter, callbacks::{GattWriteRequestType, GattWriteType, TransactionDecision}, channel::AttTransport, ids::{AdvertiserId, AttHandle, ConnectionId, ServerId, TransactionId, TransportIndex}, @@ -288,13 +288,13 @@ fn open_server(server_id: u8) { let server_id = ServerId(server_id); - if always_use_private_gatt_for_debugging_is_enabled() { - with_arbiter(|arbiter| { - arbiter.associate_server_with_advertiser(server_id, AdvertiserId(0)) - }); - } - do_in_rust_thread(move |modules| { + if always_use_private_gatt_for_debugging_is_enabled() { + modules + .gatt_module + .get_isolation_manager() + .associate_server_with_advertiser(server_id, AdvertiserId(0)) + } if let Err(err) = modules.gatt_module.open_gatt_server(server_id) { error!("{err:?}") } @@ -308,10 +308,6 @@ fn close_server(server_id: u8) { let server_id = ServerId(server_id); - if !always_use_private_gatt_for_debugging_is_enabled() { - with_arbiter(move |arbiter| arbiter.clear_server(server_id)); - } - do_in_rust_thread(move |modules| { if let Err(err) = modules.gatt_module.close_gatt_server(server_id) { error!("{err:?}") @@ -495,8 +491,13 @@ fn associate_server_with_advertiser(server_id: u8, advertiser_id: u8) { return; } - arbiter::with_arbiter(move |arbiter| { - arbiter.associate_server_with_advertiser(ServerId(server_id), AdvertiserId(advertiser_id)) + let server_id = ServerId(server_id); + let advertiser_id = AdvertiserId(advertiser_id); + do_in_rust_thread(move |modules| { + modules + .gatt_module + .get_isolation_manager() + .associate_server_with_advertiser(server_id, advertiser_id); }) } @@ -505,7 +506,11 @@ fn clear_advertiser(advertiser_id: u8) { return; } - arbiter::with_arbiter(move |arbiter| arbiter.clear_advertiser(AdvertiserId(advertiser_id))) + let advertiser_id = AdvertiserId(advertiser_id); + + do_in_rust_thread(move |modules| { + modules.gatt_module.get_isolation_manager().clear_advertiser(advertiser_id); + }) } #[cfg(test)] diff --git a/system/rust/src/gatt/server.rs b/system/rust/src/gatt/server.rs index 132779cf08c..d6869349c48 100644 --- a/system/rust/src/gatt/server.rs +++ b/system/rust/src/gatt/server.rs @@ -14,26 +14,32 @@ pub mod isolation_manager; #[cfg(test)] mod test; -use std::{collections::HashMap, rc::Rc}; +use std::{ + collections::HashMap, + rc::Rc, + sync::{Arc, Mutex, MutexGuard}, +}; use crate::{ core::shared_box::{SharedBox, WeakBox, WeakBoxRef}, - gatt::{ids::ConnectionId, server::gatt_database::GattDatabase}, + gatt::server::gatt_database::GattDatabase, }; use self::{ super::ids::ServerId, att_server_bearer::AttServerBearer, gatt_database::{AttDatabaseImpl, GattServiceWithHandle}, + isolation_manager::IsolationManager, services::register_builtin_services, }; use super::{ callbacks::RawGattDatastore, channel::AttTransport, - ids::{AttHandle, TransportIndex}, + ids::{AdvertiserId, AttHandle, TransportIndex}, }; use anyhow::{anyhow, bail, Result}; +use bt_common::init_flags::always_use_private_gatt_for_debugging_is_enabled; use log::info; pub use indication_handler::IndicationError; @@ -43,6 +49,10 @@ pub struct GattModule { connections: HashMap, databases: HashMap>, transport: Rc, + // NOTE: this is logically owned by the GattModule. We share it behind a Mutex just so we + // can use it as part of the Arbiter. Once the Arbiter is removed, this should be owned + // fully by the GattModule. + isolation_manager: Arc>, } struct GattConnection { @@ -52,13 +62,30 @@ struct GattConnection { impl GattModule { /// Constructor. - pub fn new(transport: Rc) -> Self { - Self { connections: HashMap::new(), databases: HashMap::new(), transport } + pub fn new( + transport: Rc, + isolation_manager: Arc>, + ) -> Self { + Self { + connections: HashMap::new(), + databases: HashMap::new(), + transport, + isolation_manager, + } } /// Handle LE link connect - pub fn on_le_connect(&mut self, conn_id: ConnectionId) -> Result<()> { - info!("connected on conn_id {conn_id:?}"); + pub fn on_le_connect( + &mut self, + tcb_idx: TransportIndex, + advertiser_id: Option, + ) -> Result<()> { + info!("connected on tcb_idx {tcb_idx:?}"); + self.isolation_manager.lock().unwrap().on_le_connect(tcb_idx, advertiser_id); + + let Some(conn_id) = self.isolation_manager.lock().unwrap().get_conn_id(tcb_idx) else { + bail!("non-isolated servers are not yet supported (b/274945531)") + }; let database = self.databases.get(&conn_id.get_server_id()); let Some(database) = database else { bail!( @@ -67,9 +94,6 @@ impl GattModule { ); }; - // TODO(aryarahul): do not pass in conn_id at all, derive it using the IsolationManager instead - let tcb_idx = conn_id.get_tcb_idx(); - let transport = self.transport.clone(); let bearer = SharedBox::new(AttServerBearer::new( database.get_att_database(tcb_idx), @@ -83,6 +107,7 @@ impl GattModule { /// Handle an LE link disconnect pub fn on_le_disconnect(&mut self, tcb_idx: TransportIndex) -> Result<()> { info!("disconnected conn_id {tcb_idx:?}"); + self.isolation_manager.lock().unwrap().on_le_disconnect(tcb_idx); let connection = self.connections.remove(&tcb_idx); let Some(connection) = connection else { bail!("got disconnection from {tcb_idx:?} but bearer does not exist"); @@ -135,6 +160,10 @@ impl GattModule { bail!("GATT server {server_id:?} did not exist") }; + if !always_use_private_gatt_for_debugging_is_enabled() { + self.isolation_manager.lock().unwrap().clear_server(server_id); + } + Ok(()) } @@ -145,4 +174,9 @@ impl GattModule { ) -> Option>> { self.connections.get(&tcb_idx).map(|x| x.bearer.as_ref()) } + + /// Get the IsolationManager to manage associations between servers + advertisers + pub fn get_isolation_manager(&mut self) -> MutexGuard<'_, IsolationManager> { + self.isolation_manager.lock().unwrap() + } } diff --git a/system/rust/src/gatt/server/isolation_manager.rs b/system/rust/src/gatt/server/isolation_manager.rs index 31db3cbe235..2d0cfa6dde8 100644 --- a/system/rust/src/gatt/server/isolation_manager.rs +++ b/system/rust/src/gatt/server/isolation_manager.rs @@ -39,12 +39,6 @@ impl IsolationManager { } } - /// Remove all linked advertising sets from the provided server - pub fn clear_server(&mut self, server_id: ServerId) { - info!("clearing advertisers associated with {server_id:?}"); - self.advertiser_to_server.retain(|_, server| *server != server_id); - } - /// Clear the server associated with this advertiser, if one exists pub fn clear_advertiser(&mut self, advertiser_id: AdvertiserId) { info!("removing server (if any) associated with advertiser {advertiser_id:?}"); @@ -56,29 +50,50 @@ impl IsolationManager { self.transport_to_owned_connection.values().any(|owned_conn_id| *owned_conn_id == conn_id) } + /// Check if this advertiser is tied to a private server + pub fn is_advertiser_isolated(&self, advertiser_id: AdvertiserId) -> bool { + self.advertiser_to_server.contains_key(&advertiser_id) + } + /// Look up the conn_id for a given tcb_idx, if present pub fn get_conn_id(&self, tcb_idx: TransportIndex) -> Option { self.transport_to_owned_connection.get(&tcb_idx).copied() } + /// Remove all linked advertising sets from the provided server + /// + /// This is invoked by the GATT server module, not separately from the upper layer. + pub fn clear_server(&mut self, server_id: ServerId) { + info!("clearing advertisers associated with {server_id:?}"); + self.advertiser_to_server.retain(|_, server| *server != server_id); + } + /// Handles an incoming connection - pub fn on_le_connect(&mut self, tcb_idx: TransportIndex, advertiser: AdvertiserId) { + /// + /// This event should be supplied from the enclosing module, not directly from the upper layer. + pub fn on_le_connect(&mut self, tcb_idx: TransportIndex, advertiser: Option) { info!( "processing incoming connection on transport {tcb_idx:?} to advertiser {advertiser:?}" ); - if let Some(server_id) = self.advertiser_to_server.get(&advertiser).copied() { - info!("connection is isolated to server {server_id:?}"); - let conn_id = ConnectionId::new(tcb_idx, server_id); - let old = self.transport_to_owned_connection.insert(tcb_idx, conn_id); - if old.is_some() { - error!("new server {server_id:?} on transport {tcb_idx:?} displacing existing registered connection {conn_id:?}") - } - } else { + let Some(advertiser) = advertiser else { + info!("processing outgoing connection, granting access to all servers"); + return; + }; + let Some(server_id) = self.advertiser_to_server.get(&advertiser).copied() else { info!("connection can access all servers"); + return; + }; + info!("connection is isolated to server {server_id:?}"); + let conn_id = ConnectionId::new(tcb_idx, server_id); + let old = self.transport_to_owned_connection.insert(tcb_idx, conn_id); + if old.is_some() { + error!("new server {server_id:?} on transport {tcb_idx:?} displacing existing registered connection {conn_id:?}") } } /// Handle a disconnection + /// + /// This event should be supplied from the enclosing module, not directly from the upper layer. pub fn on_le_disconnect(&mut self, tcb_idx: TransportIndex) { info!("processing disconnection on transport {tcb_idx:?}"); self.transport_to_owned_connection.remove(&tcb_idx); @@ -101,7 +116,7 @@ mod test { fn test_non_isolated_connect() { let mut isolation_manager = IsolationManager::new(); - isolation_manager.on_le_connect(TCB_IDX, ADVERTISER_ID); + isolation_manager.on_le_connect(TCB_IDX, Some(ADVERTISER_ID)); let conn_id = isolation_manager.get_conn_id(TCB_IDX); assert!(conn_id.is_none()) @@ -112,7 +127,7 @@ mod test { let mut isolation_manager = IsolationManager::new(); isolation_manager.associate_server_with_advertiser(SERVER_ID, ADVERTISER_ID); - isolation_manager.on_le_connect(TCB_IDX, ADVERTISER_ID); + isolation_manager.on_le_connect(TCB_IDX, Some(ADVERTISER_ID)); let conn_id = isolation_manager.get_conn_id(TCB_IDX); assert_eq!(conn_id, Some(CONN_ID)); @@ -123,7 +138,7 @@ mod test { let mut isolation_manager = IsolationManager::new(); isolation_manager.associate_server_with_advertiser(SERVER_ID, ADVERTISER_ID); - isolation_manager.on_le_connect(TCB_IDX, ANOTHER_ADVERTISER_ID); + isolation_manager.on_le_connect(TCB_IDX, Some(ANOTHER_ADVERTISER_ID)); let conn_id = isolation_manager.get_conn_id(TCB_IDX); assert!(conn_id.is_none()) @@ -137,7 +152,7 @@ mod test { isolation_manager.clear_advertiser(ADVERTISER_ID); // a new advertiser appeared with the same ID and got a connection - isolation_manager.on_le_connect(TCB_IDX, ADVERTISER_ID); + isolation_manager.on_le_connect(TCB_IDX, Some(ADVERTISER_ID)); let conn_id = isolation_manager.get_conn_id(TCB_IDX); // but we should not be isolated since this is a new advertiser reusing the old @@ -153,7 +168,7 @@ mod test { isolation_manager.clear_server(SERVER_ID); // then afterwards we get a connection to this advertiser - isolation_manager.on_le_connect(TCB_IDX, ADVERTISER_ID); + isolation_manager.on_le_connect(TCB_IDX, Some(ADVERTISER_ID)); let conn_id = isolation_manager.get_conn_id(TCB_IDX); // since the server is gone, we should not capture the connection @@ -164,7 +179,7 @@ mod test { fn test_connection_isolated_after_advertiser_stops() { let mut isolation_manager = IsolationManager::new(); isolation_manager.associate_server_with_advertiser(SERVER_ID, ADVERTISER_ID); - isolation_manager.on_le_connect(TCB_IDX, ADVERTISER_ID); + isolation_manager.on_le_connect(TCB_IDX, Some(ADVERTISER_ID)); let conn_id = isolation_manager.get_conn_id(TCB_IDX).unwrap(); isolation_manager.clear_advertiser(ADVERTISER_ID); @@ -177,7 +192,7 @@ mod test { fn test_connection_isolated_after_server_stops() { let mut isolation_manager = IsolationManager::new(); isolation_manager.associate_server_with_advertiser(SERVER_ID, ADVERTISER_ID); - isolation_manager.on_le_connect(TCB_IDX, ADVERTISER_ID); + isolation_manager.on_le_connect(TCB_IDX, Some(ADVERTISER_ID)); let conn_id = isolation_manager.get_conn_id(TCB_IDX).unwrap(); isolation_manager.clear_server(SERVER_ID); @@ -190,7 +205,7 @@ mod test { fn test_not_isolated_after_disconnection() { let mut isolation_manager = IsolationManager::new(); isolation_manager.associate_server_with_advertiser(SERVER_ID, ADVERTISER_ID); - isolation_manager.on_le_connect(TCB_IDX, ADVERTISER_ID); + isolation_manager.on_le_connect(TCB_IDX, Some(ADVERTISER_ID)); isolation_manager.on_le_disconnect(TCB_IDX); let is_isolated = isolation_manager.is_connection_isolated(CONN_ID); @@ -202,11 +217,11 @@ mod test { fn test_tcb_idx_reuse_after_isolated() { let mut isolation_manager = IsolationManager::new(); isolation_manager.associate_server_with_advertiser(SERVER_ID, ADVERTISER_ID); - isolation_manager.on_le_connect(TCB_IDX, ADVERTISER_ID); + isolation_manager.on_le_connect(TCB_IDX, Some(ADVERTISER_ID)); isolation_manager.clear_advertiser(ADVERTISER_ID); isolation_manager.on_le_disconnect(TCB_IDX); - isolation_manager.on_le_connect(TCB_IDX, ADVERTISER_ID); + isolation_manager.on_le_connect(TCB_IDX, Some(ADVERTISER_ID)); let conn_id = isolation_manager.get_conn_id(TCB_IDX); assert!(conn_id.is_none()); diff --git a/system/rust/src/lib.rs b/system/rust/src/lib.rs index d944e0214e3..7e628608a54 100644 --- a/system/rust/src/lib.rs +++ b/system/rust/src/lib.rs @@ -86,15 +86,15 @@ impl GlobalModuleRegistry { assert!(prev_registry.is_none()); // First, setup FFI and C++ modules - gatt::arbiter::initialize_arbiter(); + let arbiter = gatt::arbiter::initialize_arbiter(); connection::register_callbacks(); // Now enter the runtime - local.block_on(&rt, async { + local.block_on(&rt, async move { // Then follow the pure-Rust modules let gatt_incoming_callbacks = Rc::new(gatt::callbacks::CallbackTransactionManager::new(gatt_callbacks.clone())); - let gatt_module = &mut gatt::server::GattModule::new(att_transport.clone()); + let gatt_module = &mut gatt::server::GattModule::new(att_transport.clone(), arbiter); let connection_manager = connection::ConnectionManager::new(le_acl_manager); diff --git a/system/rust/tests/gatt_server_test.rs b/system/rust/tests/gatt_server_test.rs index 8ec91f74e49..7ee6fd74022 100644 --- a/system/rust/tests/gatt_server_test.rs +++ b/system/rust/tests/gatt_server_test.rs @@ -1,11 +1,14 @@ -use std::rc::Rc; +use std::{ + rc::Rc, + sync::{Arc, Mutex}, +}; use bluetooth_core::{ core::uuid::Uuid, gatt::{ self, ffi::AttributeBackingType, - ids::{AttHandle, ConnectionId, ServerId, TransportIndex}, + ids::{AdvertiserId, AttHandle, ServerId, TransportIndex}, mocks::{ mock_datastore::{MockDatastore, MockDatastoreEvents}, mock_transport::MockAttTransport, @@ -15,6 +18,7 @@ use bluetooth_core::{ AttPermissions, GattCharacteristicWithHandle, GattDescriptorWithHandle, GattServiceWithHandle, CHARACTERISTIC_UUID, PRIMARY_SERVICE_DECLARATION_UUID, }, + isolation_manager::IsolationManager, services::{ gap::DEVICE_NAME_UUID, gatt::{ @@ -48,11 +52,11 @@ mod utils; const TCB_IDX: TransportIndex = TransportIndex(1); const SERVER_ID: ServerId = ServerId(2); -const CONN_ID: ConnectionId = ConnectionId::new(TCB_IDX, SERVER_ID); +const ADVERTISER_ID: AdvertiserId = AdvertiserId(3); const ANOTHER_TCB_IDX: TransportIndex = TransportIndex(2); const ANOTHER_SERVER_ID: ServerId = ServerId(3); -const ANOTHER_CONN_ID: ConnectionId = ConnectionId::new(ANOTHER_TCB_IDX, ANOTHER_SERVER_ID); +const ANOTHER_ADVERTISER_ID: AdvertiserId = AdvertiserId(4); const SERVICE_HANDLE: AttHandle = AttHandle(6); const CHARACTERISTIC_HANDLE: AttHandle = AttHandle(8); @@ -68,7 +72,8 @@ const ANOTHER_DATA: [u8; 4] = [5, 6, 7, 8]; fn start_gatt_module() -> (gatt::server::GattModule, UnboundedReceiver<(TransportIndex, AttBuilder)>) { let (transport, transport_rx) = MockAttTransport::new(); - let gatt = GattModule::new(Rc::new(transport)); + let arbiter = IsolationManager::new(); + let gatt = GattModule::new(Rc::new(transport), Arc::new(Mutex::new(arbiter))); (gatt, transport_rx) } @@ -99,7 +104,8 @@ fn create_server_and_open_connection( datastore, ) .unwrap(); - gatt.on_le_connect(CONN_ID).unwrap(); + gatt.get_isolation_manager().associate_server_with_advertiser(SERVER_ID, ADVERTISER_ID); + gatt.on_le_connect(TCB_IDX, Some(ADVERTISER_ID)).unwrap(); data_rx } @@ -400,7 +406,9 @@ fn test_multiple_servers() { datastore, ) .unwrap(); - gatt.on_le_connect(ANOTHER_CONN_ID).unwrap(); + gatt.get_isolation_manager() + .associate_server_with_advertiser(ANOTHER_SERVER_ID, ANOTHER_ADVERTISER_ID); + gatt.on_le_connect(ANOTHER_TCB_IDX, Some(ANOTHER_ADVERTISER_ID)).unwrap(); // act: read from both connections gatt.get_bearer(TCB_IDX).unwrap().handle_packet( @@ -613,3 +621,37 @@ fn test_service_change_indication() { ); }); } + +#[test] +fn test_closing_gatt_server_unisolates_advertiser() { + start_test(async move { + // arrange + let (mut gatt, _) = start_gatt_module(); + gatt.open_gatt_server(SERVER_ID).unwrap(); + gatt.get_isolation_manager().associate_server_with_advertiser(SERVER_ID, ADVERTISER_ID); + + // act + gatt.close_gatt_server(SERVER_ID).unwrap(); + + // assert + let is_advertiser_isolated = + gatt.get_isolation_manager().is_advertiser_isolated(ADVERTISER_ID); + assert!(!is_advertiser_isolated); + }); +} + +#[test] +fn test_disconnection_unisolates_connection() { + start_test(async move { + // arrange + let (mut gatt, _) = start_gatt_module(); + create_server_and_open_connection(&mut gatt); + + // act + gatt.on_le_disconnect(TCB_IDX).unwrap(); + + // assert + let is_connection_isolated = gatt.get_isolation_manager().get_conn_id(TCB_IDX).is_some(); + assert!(!is_connection_isolated); + }); +} -- GitLab From df312c3e82cda24cb37358c2cbb1aecdb5aae93a Mon Sep 17 00:00:00 2001 From: Rahul Arya Date: Wed, 10 May 2023 18:55:16 +0000 Subject: [PATCH 0040/2405] [GATT Server] Simplify API of IsolationManager Test: unit Bug: 274945531 Change-Id: I956e035b9646dac149357f74e3d4a3d0236a9b0e --- system/rust/src/gatt/arbiter.rs | 6 +- system/rust/src/gatt/ffi.rs | 2 +- system/rust/src/gatt/server.rs | 9 +-- .../rust/src/gatt/server/isolation_manager.rs | 61 +++++++++---------- system/rust/tests/gatt_server_test.rs | 2 +- 5 files changed, 36 insertions(+), 44 deletions(-) diff --git a/system/rust/src/gatt/arbiter.rs b/system/rust/src/gatt/arbiter.rs index b6b25a10c6c..156d0c90859 100644 --- a/system/rust/src/gatt/arbiter.rs +++ b/system/rust/src/gatt/arbiter.rs @@ -51,7 +51,7 @@ fn try_parse_att_server_packet( tcb_idx: TransportIndex, packet: Box<[u8]>, ) -> Option { - isolation_manager.get_conn_id(tcb_idx)?; + isolation_manager.get_server_id(tcb_idx)?; let att = OwnedAttView::try_parse(packet).ok()?; @@ -82,7 +82,7 @@ fn on_le_connect(tcb_idx: u8, advertiser: u8) { fn on_le_disconnect(tcb_idx: u8) { let tcb_idx = TransportIndex(tcb_idx); - let was_isolated = with_arbiter(|arbiter| arbiter.get_conn_id(tcb_idx).is_some()); + let was_isolated = with_arbiter(|arbiter| arbiter.is_connection_isolated(tcb_idx)); if was_isolated { do_in_rust_thread(move |modules| { if let Err(err) = modules.gatt_module.on_le_disconnect(tcb_idx) { @@ -112,7 +112,7 @@ fn intercept_packet(tcb_idx: u8, packet: Vec) -> InterceptAction { } fn on_mtu_event(tcb_idx: TransportIndex, event: MtuEvent) { - if with_arbiter(|arbiter| arbiter.get_conn_id(tcb_idx)).is_some() { + if with_arbiter(|arbiter| arbiter.is_connection_isolated(tcb_idx)) { do_in_rust_thread(move |modules| { let Some(bearer) = modules.gatt_module.get_bearer(tcb_idx) else { error!("Bearer for {tcb_idx:?} not found"); diff --git a/system/rust/src/gatt/ffi.rs b/system/rust/src/gatt/ffi.rs index 57543bb4fcb..4f06f0b60b2 100644 --- a/system/rust/src/gatt/ffi.rs +++ b/system/rust/src/gatt/ffi.rs @@ -431,7 +431,7 @@ fn is_connection_isolated(conn_id: u16) -> bool { return false; } - with_arbiter(|arbiter| arbiter.is_connection_isolated(ConnectionId(conn_id))) + with_arbiter(|arbiter| arbiter.is_connection_isolated(ConnectionId(conn_id).get_tcb_idx())) } fn send_response(_server_id: u8, conn_id: u16, trans_id: u32, status: u8, value: &[u8]) { diff --git a/system/rust/src/gatt/server.rs b/system/rust/src/gatt/server.rs index d6869349c48..ee35a7ce30f 100644 --- a/system/rust/src/gatt/server.rs +++ b/system/rust/src/gatt/server.rs @@ -83,15 +83,12 @@ impl GattModule { info!("connected on tcb_idx {tcb_idx:?}"); self.isolation_manager.lock().unwrap().on_le_connect(tcb_idx, advertiser_id); - let Some(conn_id) = self.isolation_manager.lock().unwrap().get_conn_id(tcb_idx) else { + let Some(server_id) = self.isolation_manager.lock().unwrap().get_server_id(tcb_idx) else { bail!("non-isolated servers are not yet supported (b/274945531)") }; - let database = self.databases.get(&conn_id.get_server_id()); + let database = self.databases.get(&server_id); let Some(database) = database else { - bail!( - "got connection to conn_id {conn_id:?} (server_id {:?}) but this server does not exist!", - conn_id.get_server_id(), - ); + bail!("got connection to {server_id:?} but this server does not exist!"); }; let transport = self.transport.clone(); diff --git a/system/rust/src/gatt/server/isolation_manager.rs b/system/rust/src/gatt/server/isolation_manager.rs index 2d0cfa6dde8..b7f32a7b79b 100644 --- a/system/rust/src/gatt/server/isolation_manager.rs +++ b/system/rust/src/gatt/server/isolation_manager.rs @@ -4,7 +4,7 @@ use std::collections::HashMap; use log::{error, info}; -use crate::gatt::ids::{AdvertiserId, ConnectionId, ServerId, TransportIndex}; +use crate::gatt::ids::{AdvertiserId, ServerId, TransportIndex}; /// This class is responsible for tracking which connections and advertising we /// own, and using this information to decide what servers should be exposed to @@ -12,7 +12,7 @@ use crate::gatt::ids::{AdvertiserId, ConnectionId, ServerId, TransportIndex}; #[derive(Default)] pub struct IsolationManager { advertiser_to_server: HashMap, - transport_to_owned_connection: HashMap, + transport_to_server: HashMap, } impl IsolationManager { @@ -20,7 +20,7 @@ impl IsolationManager { pub fn new() -> Self { IsolationManager { advertiser_to_server: HashMap::new(), - transport_to_owned_connection: HashMap::new(), + transport_to_server: HashMap::new(), } } @@ -45,9 +45,9 @@ impl IsolationManager { self.advertiser_to_server.remove(&advertiser_id); } - /// Check if this conn_id is currently owned by the Rust stack - pub fn is_connection_isolated(&self, conn_id: ConnectionId) -> bool { - self.transport_to_owned_connection.values().any(|owned_conn_id| *owned_conn_id == conn_id) + /// Check if this transport is currently owned by the Rust stack + pub fn is_connection_isolated(&self, tcb_idx: TransportIndex) -> bool { + self.transport_to_server.contains_key(&tcb_idx) } /// Check if this advertiser is tied to a private server @@ -55,9 +55,9 @@ impl IsolationManager { self.advertiser_to_server.contains_key(&advertiser_id) } - /// Look up the conn_id for a given tcb_idx, if present - pub fn get_conn_id(&self, tcb_idx: TransportIndex) -> Option { - self.transport_to_owned_connection.get(&tcb_idx).copied() + /// Look up the server_id tied to a given tcb_idx, if one exists + pub fn get_server_id(&self, tcb_idx: TransportIndex) -> Option { + self.transport_to_server.get(&tcb_idx).copied() } /// Remove all linked advertising sets from the provided server @@ -84,10 +84,9 @@ impl IsolationManager { return; }; info!("connection is isolated to server {server_id:?}"); - let conn_id = ConnectionId::new(tcb_idx, server_id); - let old = self.transport_to_owned_connection.insert(tcb_idx, conn_id); + let old = self.transport_to_server.insert(tcb_idx, server_id); if old.is_some() { - error!("new server {server_id:?} on transport {tcb_idx:?} displacing existing registered connection {conn_id:?}") + error!("new server {server_id:?} on transport {tcb_idx:?} displacing existing server {server_id:?}") } } @@ -96,7 +95,7 @@ impl IsolationManager { /// This event should be supplied from the enclosing module, not directly from the upper layer. pub fn on_le_disconnect(&mut self, tcb_idx: TransportIndex) { info!("processing disconnection on transport {tcb_idx:?}"); - self.transport_to_owned_connection.remove(&tcb_idx); + self.transport_to_server.remove(&tcb_idx); } } @@ -108,8 +107,6 @@ mod test { const ADVERTISER_ID: AdvertiserId = AdvertiserId(3); const SERVER_ID: ServerId = ServerId(4); - const CONN_ID: ConnectionId = ConnectionId::new(TCB_IDX, SERVER_ID); - const ANOTHER_ADVERTISER_ID: AdvertiserId = AdvertiserId(5); #[test] @@ -117,9 +114,9 @@ mod test { let mut isolation_manager = IsolationManager::new(); isolation_manager.on_le_connect(TCB_IDX, Some(ADVERTISER_ID)); - let conn_id = isolation_manager.get_conn_id(TCB_IDX); + let server_id = isolation_manager.get_server_id(TCB_IDX); - assert!(conn_id.is_none()) + assert!(server_id.is_none()) } #[test] @@ -128,9 +125,9 @@ mod test { isolation_manager.associate_server_with_advertiser(SERVER_ID, ADVERTISER_ID); isolation_manager.on_le_connect(TCB_IDX, Some(ADVERTISER_ID)); - let conn_id = isolation_manager.get_conn_id(TCB_IDX); + let server_id = isolation_manager.get_server_id(TCB_IDX); - assert_eq!(conn_id, Some(CONN_ID)); + assert_eq!(server_id, Some(SERVER_ID)); } #[test] @@ -139,9 +136,9 @@ mod test { isolation_manager.associate_server_with_advertiser(SERVER_ID, ADVERTISER_ID); isolation_manager.on_le_connect(TCB_IDX, Some(ANOTHER_ADVERTISER_ID)); - let conn_id = isolation_manager.get_conn_id(TCB_IDX); + let server_id = isolation_manager.get_server_id(TCB_IDX); - assert!(conn_id.is_none()) + assert!(server_id.is_none()) } #[test] @@ -153,11 +150,11 @@ mod test { // a new advertiser appeared with the same ID and got a connection isolation_manager.on_le_connect(TCB_IDX, Some(ADVERTISER_ID)); - let conn_id = isolation_manager.get_conn_id(TCB_IDX); + let server_id = isolation_manager.get_server_id(TCB_IDX); // but we should not be isolated since this is a new advertiser reusing the old // ID - assert!(conn_id.is_none()) + assert!(server_id.is_none()) } #[test] @@ -169,10 +166,10 @@ mod test { // then afterwards we get a connection to this advertiser isolation_manager.on_le_connect(TCB_IDX, Some(ADVERTISER_ID)); - let conn_id = isolation_manager.get_conn_id(TCB_IDX); + let server_id = isolation_manager.get_server_id(TCB_IDX); // since the server is gone, we should not capture the connection - assert!(conn_id.is_none()) + assert!(server_id.is_none()) } #[test] @@ -180,10 +177,9 @@ mod test { let mut isolation_manager = IsolationManager::new(); isolation_manager.associate_server_with_advertiser(SERVER_ID, ADVERTISER_ID); isolation_manager.on_le_connect(TCB_IDX, Some(ADVERTISER_ID)); - let conn_id = isolation_manager.get_conn_id(TCB_IDX).unwrap(); isolation_manager.clear_advertiser(ADVERTISER_ID); - let is_isolated = isolation_manager.is_connection_isolated(conn_id); + let is_isolated = isolation_manager.is_connection_isolated(TCB_IDX); assert!(is_isolated) } @@ -193,10 +189,9 @@ mod test { let mut isolation_manager = IsolationManager::new(); isolation_manager.associate_server_with_advertiser(SERVER_ID, ADVERTISER_ID); isolation_manager.on_le_connect(TCB_IDX, Some(ADVERTISER_ID)); - let conn_id = isolation_manager.get_conn_id(TCB_IDX).unwrap(); isolation_manager.clear_server(SERVER_ID); - let is_isolated = isolation_manager.is_connection_isolated(conn_id); + let is_isolated = isolation_manager.is_connection_isolated(TCB_IDX); assert!(is_isolated) } @@ -208,7 +203,7 @@ mod test { isolation_manager.on_le_connect(TCB_IDX, Some(ADVERTISER_ID)); isolation_manager.on_le_disconnect(TCB_IDX); - let is_isolated = isolation_manager.is_connection_isolated(CONN_ID); + let is_isolated = isolation_manager.is_connection_isolated(TCB_IDX); assert!(!is_isolated); } @@ -222,9 +217,9 @@ mod test { isolation_manager.on_le_disconnect(TCB_IDX); isolation_manager.on_le_connect(TCB_IDX, Some(ADVERTISER_ID)); - let conn_id = isolation_manager.get_conn_id(TCB_IDX); + let server_id = isolation_manager.get_server_id(TCB_IDX); - assert!(conn_id.is_none()); - assert!(!isolation_manager.is_connection_isolated(CONN_ID)); + assert!(server_id.is_none()); + assert!(!isolation_manager.is_connection_isolated(TCB_IDX)); } } diff --git a/system/rust/tests/gatt_server_test.rs b/system/rust/tests/gatt_server_test.rs index 7ee6fd74022..20532ab8352 100644 --- a/system/rust/tests/gatt_server_test.rs +++ b/system/rust/tests/gatt_server_test.rs @@ -651,7 +651,7 @@ fn test_disconnection_unisolates_connection() { gatt.on_le_disconnect(TCB_IDX).unwrap(); // assert - let is_connection_isolated = gatt.get_isolation_manager().get_conn_id(TCB_IDX).is_some(); + let is_connection_isolated = gatt.get_isolation_manager().is_connection_isolated(TCB_IDX); assert!(!is_connection_isolated); }); } -- GitLab From d1fd446b335f28c7026ada138d962bbcb0c82d3f Mon Sep 17 00:00:00 2001 From: Hsin-chen Chuang Date: Thu, 11 May 2023 10:50:51 +0800 Subject: [PATCH 0041/2405] btif_sock: Fix the wrong log info Bug: 281925900 Test: CQ Change-Id: I29de0b04c0cd24d5a2a69f26366e80aa8e0f3e59 --- system/btif/src/btif_sock.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/system/btif/src/btif_sock.cc b/system/btif/src/btif_sock.cc index 4b3ca300655..794cf05ed28 100644 --- a/system/btif/src/btif_sock.cc +++ b/system/btif/src/btif_sock.cc @@ -157,7 +157,7 @@ void btif_sock_cleanup(void) { } void btif_sock_connection_logger(int state, int role, const RawAddress& addr) { - LOG_INFO("address=%s, role=%d, state=%d", ADDRESS_TO_LOGGABLE_CSTR(addr), + LOG_INFO("address=%s, state=%d, role=%d", ADDRESS_TO_LOGGABLE_CSTR(addr), state, role); uint8_t index = logger_index++ % SOCK_LOGGER_SIZE_MAX; -- GitLab From c4b6d03982a04e9b42c02273b4b07a647884d3ba Mon Sep 17 00:00:00 2001 From: Daihee Kang Date: Thu, 11 May 2023 03:41:27 +0000 Subject: [PATCH 0042/2405] Fix for infinite loop in free_gatt_resources Change-Id: Idecd58c6b8e2ad17e074cef82f04255910fc3c10 --- system/stack/eatt/eatt_impl.h | 1 + 1 file changed, 1 insertion(+) diff --git a/system/stack/eatt/eatt_impl.h b/system/stack/eatt/eatt_impl.h index a613a410ae9..a7835c98c97 100644 --- a/system/stack/eatt/eatt_impl.h +++ b/system/stack/eatt/eatt_impl.h @@ -708,6 +708,7 @@ struct eatt_impl { fixed_queue_free(channel->server_outstanding_cmd_.multi_rsp_q, NULL); channel->server_outstanding_cmd_.multi_rsp_q = NULL; + iter++; } } -- GitLab From 11a7eeb07d2914b31aba90feabd7ea3abf2929c2 Mon Sep 17 00:00:00 2001 From: Henri Chataing Date: Mon, 8 May 2023 09:19:14 -0700 Subject: [PATCH 0043/2405] pdl: Implement custom fields for rust generator Add support for custom types of constant size. In this case the generator produces a type alias. Test: cargo test Bug: 279494407 Change-Id: Ic1289083dbe2e3aaf3edea595fd6fc36a999c103 --- tools/pdl/Android.bp | 4 + tools/pdl/src/backends/rust.rs | 91 ++++++++ tools/pdl/src/backends/rust/parser.rs | 43 ++-- tools/pdl/src/backends/rust/serializer.rs | 21 +- tools/pdl/src/backends/rust/types.rs | 1 + .../custom_field_declaration_big_endian.rs | 93 +++++++++ .../custom_field_declaration_little_endian.rs | 93 +++++++++ .../packet_decl_custom_field_big_endian.rs | 194 ++++++++++++++++++ .../packet_decl_custom_field_little_endian.rs | 194 ++++++++++++++++++ 9 files changed, 717 insertions(+), 17 deletions(-) create mode 100644 tools/pdl/tests/generated/custom_field_declaration_big_endian.rs create mode 100644 tools/pdl/tests/generated/custom_field_declaration_little_endian.rs create mode 100644 tools/pdl/tests/generated/packet_decl_custom_field_big_endian.rs create mode 100644 tools/pdl/tests/generated/packet_decl_custom_field_little_endian.rs diff --git a/tools/pdl/Android.bp b/tools/pdl/Android.bp index 3deba58a145..d9d98560b87 100644 --- a/tools/pdl/Android.bp +++ b/tools/pdl/Android.bp @@ -41,6 +41,8 @@ rust_binary_host { filegroup { name: "pdl_generated_files", srcs: [ + "tests/generated/custom_field_declaration_big_endian.rs", + "tests/generated/custom_field_declaration_little_endian.rs", "tests/generated/enum_declaration_big_endian.rs", "tests/generated/enum_declaration_little_endian.rs", "tests/generated/packet_decl_8bit_enum_array_big_endian.rs", @@ -79,6 +81,8 @@ filegroup { "tests/generated/packet_decl_child_packets_little_endian.rs", "tests/generated/packet_decl_complex_scalars_big_endian.rs", "tests/generated/packet_decl_complex_scalars_little_endian.rs", + "tests/generated/packet_decl_custom_field_big_endian.rs", + "tests/generated/packet_decl_custom_field_little_endian.rs", "tests/generated/packet_decl_empty_big_endian.rs", "tests/generated/packet_decl_empty_little_endian.rs", "tests/generated/packet_decl_fixed_enum_field_big_endian.rs", diff --git a/tools/pdl/src/backends/rust.rs b/tools/pdl/src/backends/rust.rs index e14efbd7d3c..d034d4ba875 100644 --- a/tools/pdl/src/backends/rust.rs +++ b/tools/pdl/src/backends/rust.rs @@ -899,6 +899,67 @@ fn generate_enum_decl( } } +/// Generate the declaration for a custom field of static size. +/// +/// * `id` - Enum identifier. +/// * `width` - Width of the backing type of the enum, in bits. +fn generate_custom_field_decl(id: &str, width: usize) -> proc_macro2::TokenStream { + let id = format_ident!("{}", id); + let backing_type = types::Integer::new(width); + let backing_type_str = proc_macro2::Literal::string(&format!("u{}", backing_type.width)); + let max_value = mask_bits(width, "usize"); + let common = quote! { + impl From<&#id> for #backing_type { + fn from(value: &#id) -> #backing_type { + value.0 + } + } + + impl From<#id> for #backing_type { + fn from(value: #id) -> #backing_type { + value.0 + } + } + }; + + if backing_type.width == width { + quote! { + #[derive(Debug, Clone, Copy, Hash, Eq, PartialEq)] + #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] + #[cfg_attr(feature = "serde", serde(from = #backing_type_str, into = #backing_type_str))] + pub struct #id(#backing_type); + + #common + + impl From<#backing_type> for #id { + fn from(value: #backing_type) -> Self { + #id(value) + } + } + } + } else { + quote! { + #[derive(Debug, Clone, Copy, Hash, Eq, PartialEq)] + #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] + #[cfg_attr(feature = "serde", serde(try_from = #backing_type_str, into = #backing_type_str))] + pub struct #id(#backing_type); + + #common + + impl TryFrom<#backing_type> for #id { + type Error = #backing_type; + fn try_from(value: #backing_type) -> std::result::Result { + if value > #max_value { + Err(value) + } else { + Ok(#id(value)) + } + } + } + } + } +} + fn generate_decl( scope: &lint::Scope<'_>, file: &analyzer_ast::File, @@ -919,6 +980,9 @@ fn generate_decl( ast::DeclDesc::Enum { id, tags, width } => { generate_enum_decl(id, tags, *width, false).to_string() } + ast::DeclDesc::CustomField { id, width: Some(width), .. } => { + generate_custom_field_decl(id, *width).to_string() + } _ => todo!("unsupported Decl::{:?}", decl), } } @@ -1104,6 +1168,20 @@ mod tests { "# ); + test_pdl!( + custom_field_declaration, + r#" + // Still unsupported. + // custom_field Dynamic "dynamic" + + // Should generate a type with From implementation. + custom_field ExactSize : 32 "exact_size" + + // Should generate a type with TryFrom implementation. + custom_field TruncatedSize : 24 "truncated_size" + "# + ); + test_pdl!( packet_decl_simple_scalars, r#" @@ -1260,6 +1338,19 @@ mod tests { " ); + test_pdl!( + packet_decl_custom_field, + r#" + custom_field Bar1 : 24 "exact" + custom_field Bar2 : 32 "truncated" + + packet Foo { + a: Bar1, + b: Bar2, + } + "# + ); + test_pdl!( packet_decl_fixed_scalar_field, " diff --git a/tools/pdl/src/backends/rust/parser.rs b/tools/pdl/src/backends/rust/parser.rs index 71984f877bb..b1fa7167109 100644 --- a/tools/pdl/src/backends/rust/parser.rs +++ b/tools/pdl/src/backends/rust/parser.rs @@ -459,27 +459,40 @@ impl<'a> FieldParser<'a> { let id = format_ident!("{id}"); let type_id = format_ident!("{type_id}"); - match self.scope.get_decl_width(decl, true) { - None => self.code.push(quote! { + self.code.push(match self.scope.get_decl_width(decl, true) { + None => quote! { let #id = #type_id::parse_inner(&mut #span)?; - }), + }, Some(width) => { assert_eq!(width % 8, 0, "Typedef field type size is not a multiple of 8"); - let width = syn::Index::from(width / 8); - self.code.push(if let ast::DeclDesc::Checksum { .. } = &decl.desc { - // TODO: handle checksum fields. - quote! { - #span.get_mut().advance(#width); + match &decl.desc { + ast::DeclDesc::Checksum { .. } => todo!(), + ast::DeclDesc::CustomField { .. } if [8, 16, 32, 64].contains(&width) => { + let get_uint = types::get_uint(self.endianness, width, span); + quote! { + let #id = #get_uint.into(); + } } - } else { - quote! { - let (head, tail) = #span.get().split_at(#width); - #span.replace(tail); - let #id = #type_id::parse(head)?; + ast::DeclDesc::CustomField { .. } => { + let get_uint = types::get_uint(self.endianness, width, span); + quote! { + let #id = (#get_uint) + .try_into() + .unwrap(); // Value is masked and conversion must succeed. + } } - }); + ast::DeclDesc::Struct { .. } => { + let width = syn::Index::from(width / 8); + quote! { + let (head, tail) = #span.get().split_at(#width); + #span.replace(tail); + let #id = #type_id::parse(head)?; + } + } + _ => unreachable!(), + } } - } + }); } /// Parse body and payload fields. diff --git a/tools/pdl/src/backends/rust/serializer.rs b/tools/pdl/src/backends/rust/serializer.rs index 7ef3bf29351..1cb7ecbca83 100644 --- a/tools/pdl/src/backends/rust/serializer.rs +++ b/tools/pdl/src/backends/rust/serializer.rs @@ -302,8 +302,25 @@ impl<'a> FieldSerializer<'a> { let id = format_ident!("{id}"); let span = format_ident!("{}", self.span); - self.code.push(quote! { - self.#id.write_to(#span); + + self.code.push(match &decl.desc { + ast::DeclDesc::Checksum { .. } => todo!(), + ast::DeclDesc::CustomField { width: Some(width), .. } => { + let backing_type = types::Integer::new(*width); + let put_uint = types::put_uint( + self.endianness, + "e! { #backing_type::from(self.#id) }, + *width, + self.span, + ); + quote! { + #put_uint; + } + } + ast::DeclDesc::Struct { .. } => quote! { + self.#id.write_to(#span); + }, + _ => unreachable!(), }); } diff --git a/tools/pdl/src/backends/rust/types.rs b/tools/pdl/src/backends/rust/types.rs index bd73c0d6c3f..e8f14aa3de2 100644 --- a/tools/pdl/src/backends/rust/types.rs +++ b/tools/pdl/src/backends/rust/types.rs @@ -90,6 +90,7 @@ pub fn rust_borrow( ast::FieldDesc::Typedef { type_id, .. } => match &scope.typedef[type_id].desc { ast::DeclDesc::Enum { .. } => quote!(), ast::DeclDesc::Struct { .. } => quote!(&), + ast::DeclDesc::CustomField { .. } => quote!(&), desc => unreachable!("unexpected declaration: {desc:?}"), }, ast::FieldDesc::Array { .. } => quote!(&), diff --git a/tools/pdl/tests/generated/custom_field_declaration_big_endian.rs b/tools/pdl/tests/generated/custom_field_declaration_big_endian.rs new file mode 100644 index 00000000000..3576f1f1ea5 --- /dev/null +++ b/tools/pdl/tests/generated/custom_field_declaration_big_endian.rs @@ -0,0 +1,93 @@ +// @generated rust packets from test + +use bytes::{Buf, BufMut, Bytes, BytesMut}; +use std::cell::Cell; +use std::convert::{TryFrom, TryInto}; +use std::fmt; +use std::sync::Arc; +use thiserror::Error; + +type Result = std::result::Result; + +#[doc = r" Private prevents users from creating arbitrary scalar values"] +#[doc = r" in situations where the value needs to be validated."] +#[doc = r" Users can freely deref the value, but only the backend"] +#[doc = r" may create it."] +#[derive(Debug, Clone, Copy, Hash, PartialEq, Eq, PartialOrd, Ord)] +pub struct Private(T); +impl std::ops::Deref for Private { + type Target = T; + fn deref(&self) -> &Self::Target { + &self.0 + } +} + +#[derive(Debug, Error)] +pub enum Error { + #[error("Packet parsing failed")] + InvalidPacketError, + #[error("{field} was {value:x}, which is not known")] + ConstraintOutOfBounds { field: String, value: u64 }, + #[error("Got {actual:x}, expected {expected:x}")] + InvalidFixedValue { expected: u64, actual: u64 }, + #[error("when parsing {obj} needed length of {wanted} but got {got}")] + InvalidLengthError { obj: String, wanted: usize, got: usize }, + #[error("array size ({array} bytes) is not a multiple of the element size ({element} bytes)")] + InvalidArraySize { array: usize, element: usize }, + #[error("Due to size restrictions a struct could not be parsed.")] + ImpossibleStructError, + #[error("when parsing field {obj}.{field}, {value} is not a valid {type_} value")] + InvalidEnumValueError { obj: String, field: String, value: u64, type_: String }, + #[error("expected child {expected}, got {actual}")] + InvalidChildError { expected: &'static str, actual: String }, +} + +pub trait Packet { + fn to_bytes(self) -> Bytes; + fn to_vec(self) -> Vec; +} + +#[derive(Debug, Clone, Copy, Hash, Eq, PartialEq)] +#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] +#[cfg_attr(feature = "serde", serde(from = "u32", into = "u32"))] +pub struct ExactSize(u32); +impl From<&ExactSize> for u32 { + fn from(value: &ExactSize) -> u32 { + value.0 + } +} +impl From for u32 { + fn from(value: ExactSize) -> u32 { + value.0 + } +} +impl From for ExactSize { + fn from(value: u32) -> Self { + ExactSize(value) + } +} + +#[derive(Debug, Clone, Copy, Hash, Eq, PartialEq)] +#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] +#[cfg_attr(feature = "serde", serde(try_from = "u32", into = "u32"))] +pub struct TruncatedSize(u32); +impl From<&TruncatedSize> for u32 { + fn from(value: &TruncatedSize) -> u32 { + value.0 + } +} +impl From for u32 { + fn from(value: TruncatedSize) -> u32 { + value.0 + } +} +impl TryFrom for TruncatedSize { + type Error = u32; + fn try_from(value: u32) -> std::result::Result { + if value > 0xff_ffff { + Err(value) + } else { + Ok(TruncatedSize(value)) + } + } +} diff --git a/tools/pdl/tests/generated/custom_field_declaration_little_endian.rs b/tools/pdl/tests/generated/custom_field_declaration_little_endian.rs new file mode 100644 index 00000000000..3576f1f1ea5 --- /dev/null +++ b/tools/pdl/tests/generated/custom_field_declaration_little_endian.rs @@ -0,0 +1,93 @@ +// @generated rust packets from test + +use bytes::{Buf, BufMut, Bytes, BytesMut}; +use std::cell::Cell; +use std::convert::{TryFrom, TryInto}; +use std::fmt; +use std::sync::Arc; +use thiserror::Error; + +type Result = std::result::Result; + +#[doc = r" Private prevents users from creating arbitrary scalar values"] +#[doc = r" in situations where the value needs to be validated."] +#[doc = r" Users can freely deref the value, but only the backend"] +#[doc = r" may create it."] +#[derive(Debug, Clone, Copy, Hash, PartialEq, Eq, PartialOrd, Ord)] +pub struct Private(T); +impl std::ops::Deref for Private { + type Target = T; + fn deref(&self) -> &Self::Target { + &self.0 + } +} + +#[derive(Debug, Error)] +pub enum Error { + #[error("Packet parsing failed")] + InvalidPacketError, + #[error("{field} was {value:x}, which is not known")] + ConstraintOutOfBounds { field: String, value: u64 }, + #[error("Got {actual:x}, expected {expected:x}")] + InvalidFixedValue { expected: u64, actual: u64 }, + #[error("when parsing {obj} needed length of {wanted} but got {got}")] + InvalidLengthError { obj: String, wanted: usize, got: usize }, + #[error("array size ({array} bytes) is not a multiple of the element size ({element} bytes)")] + InvalidArraySize { array: usize, element: usize }, + #[error("Due to size restrictions a struct could not be parsed.")] + ImpossibleStructError, + #[error("when parsing field {obj}.{field}, {value} is not a valid {type_} value")] + InvalidEnumValueError { obj: String, field: String, value: u64, type_: String }, + #[error("expected child {expected}, got {actual}")] + InvalidChildError { expected: &'static str, actual: String }, +} + +pub trait Packet { + fn to_bytes(self) -> Bytes; + fn to_vec(self) -> Vec; +} + +#[derive(Debug, Clone, Copy, Hash, Eq, PartialEq)] +#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] +#[cfg_attr(feature = "serde", serde(from = "u32", into = "u32"))] +pub struct ExactSize(u32); +impl From<&ExactSize> for u32 { + fn from(value: &ExactSize) -> u32 { + value.0 + } +} +impl From for u32 { + fn from(value: ExactSize) -> u32 { + value.0 + } +} +impl From for ExactSize { + fn from(value: u32) -> Self { + ExactSize(value) + } +} + +#[derive(Debug, Clone, Copy, Hash, Eq, PartialEq)] +#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] +#[cfg_attr(feature = "serde", serde(try_from = "u32", into = "u32"))] +pub struct TruncatedSize(u32); +impl From<&TruncatedSize> for u32 { + fn from(value: &TruncatedSize) -> u32 { + value.0 + } +} +impl From for u32 { + fn from(value: TruncatedSize) -> u32 { + value.0 + } +} +impl TryFrom for TruncatedSize { + type Error = u32; + fn try_from(value: u32) -> std::result::Result { + if value > 0xff_ffff { + Err(value) + } else { + Ok(TruncatedSize(value)) + } + } +} diff --git a/tools/pdl/tests/generated/packet_decl_custom_field_big_endian.rs b/tools/pdl/tests/generated/packet_decl_custom_field_big_endian.rs new file mode 100644 index 00000000000..cfe327f6b74 --- /dev/null +++ b/tools/pdl/tests/generated/packet_decl_custom_field_big_endian.rs @@ -0,0 +1,194 @@ +// @generated rust packets from test + +use bytes::{Buf, BufMut, Bytes, BytesMut}; +use std::cell::Cell; +use std::convert::{TryFrom, TryInto}; +use std::fmt; +use std::sync::Arc; +use thiserror::Error; + +type Result = std::result::Result; + +#[doc = r" Private prevents users from creating arbitrary scalar values"] +#[doc = r" in situations where the value needs to be validated."] +#[doc = r" Users can freely deref the value, but only the backend"] +#[doc = r" may create it."] +#[derive(Debug, Clone, Copy, Hash, PartialEq, Eq, PartialOrd, Ord)] +pub struct Private(T); +impl std::ops::Deref for Private { + type Target = T; + fn deref(&self) -> &Self::Target { + &self.0 + } +} + +#[derive(Debug, Error)] +pub enum Error { + #[error("Packet parsing failed")] + InvalidPacketError, + #[error("{field} was {value:x}, which is not known")] + ConstraintOutOfBounds { field: String, value: u64 }, + #[error("Got {actual:x}, expected {expected:x}")] + InvalidFixedValue { expected: u64, actual: u64 }, + #[error("when parsing {obj} needed length of {wanted} but got {got}")] + InvalidLengthError { obj: String, wanted: usize, got: usize }, + #[error("array size ({array} bytes) is not a multiple of the element size ({element} bytes)")] + InvalidArraySize { array: usize, element: usize }, + #[error("Due to size restrictions a struct could not be parsed.")] + ImpossibleStructError, + #[error("when parsing field {obj}.{field}, {value} is not a valid {type_} value")] + InvalidEnumValueError { obj: String, field: String, value: u64, type_: String }, + #[error("expected child {expected}, got {actual}")] + InvalidChildError { expected: &'static str, actual: String }, +} + +pub trait Packet { + fn to_bytes(self) -> Bytes; + fn to_vec(self) -> Vec; +} + +#[derive(Debug, Clone, Copy, Hash, Eq, PartialEq)] +#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] +#[cfg_attr(feature = "serde", serde(try_from = "u32", into = "u32"))] +pub struct Bar1(u32); +impl From<&Bar1> for u32 { + fn from(value: &Bar1) -> u32 { + value.0 + } +} +impl From for u32 { + fn from(value: Bar1) -> u32 { + value.0 + } +} +impl TryFrom for Bar1 { + type Error = u32; + fn try_from(value: u32) -> std::result::Result { + if value > 0xff_ffff { + Err(value) + } else { + Ok(Bar1(value)) + } + } +} + +#[derive(Debug, Clone, Copy, Hash, Eq, PartialEq)] +#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] +#[cfg_attr(feature = "serde", serde(from = "u32", into = "u32"))] +pub struct Bar2(u32); +impl From<&Bar2> for u32 { + fn from(value: &Bar2) -> u32 { + value.0 + } +} +impl From for u32 { + fn from(value: Bar2) -> u32 { + value.0 + } +} +impl From for Bar2 { + fn from(value: u32) -> Self { + Bar2(value) + } +} + +#[derive(Debug, Clone, PartialEq, Eq)] +#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] +pub struct FooData { + a: Bar1, + b: Bar2, +} +#[derive(Debug, Clone, PartialEq, Eq)] +#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] +pub struct Foo { + #[cfg_attr(feature = "serde", serde(flatten))] + foo: Arc, +} +#[derive(Debug)] +#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] +pub struct FooBuilder { + pub a: Bar1, + pub b: Bar2, +} +impl FooData { + fn conforms(bytes: &[u8]) -> bool { + bytes.len() >= 7 + } + fn parse(bytes: &[u8]) -> Result { + let mut cell = Cell::new(bytes); + let packet = Self::parse_inner(&mut cell)?; + Ok(packet) + } + fn parse_inner(mut bytes: &mut Cell<&[u8]>) -> Result { + let a = (bytes.get_mut().get_uint(3) as u32).try_into().unwrap(); + let b = bytes.get_mut().get_u32().into(); + Ok(Self { a, b }) + } + fn write_to(&self, buffer: &mut BytesMut) { + buffer.put_uint(u32::from(self.a) as u64, 3); + buffer.put_u32(u32::from(self.b)); + } + fn get_total_size(&self) -> usize { + self.get_size() + } + fn get_size(&self) -> usize { + 7 + } +} +impl Packet for Foo { + fn to_bytes(self) -> Bytes { + let mut buffer = BytesMut::with_capacity(self.foo.get_size()); + self.foo.write_to(&mut buffer); + buffer.freeze() + } + fn to_vec(self) -> Vec { + self.to_bytes().to_vec() + } +} +impl From for Bytes { + fn from(packet: Foo) -> Self { + packet.to_bytes() + } +} +impl From for Vec { + fn from(packet: Foo) -> Self { + packet.to_vec() + } +} +impl Foo { + pub fn parse(bytes: &[u8]) -> Result { + let mut cell = Cell::new(bytes); + let packet = Self::parse_inner(&mut cell)?; + Ok(packet) + } + fn parse_inner(mut bytes: &mut Cell<&[u8]>) -> Result { + let data = FooData::parse_inner(&mut bytes)?; + Self::new(Arc::new(data)) + } + fn new(foo: Arc) -> Result { + Ok(Self { foo }) + } + pub fn get_a(&self) -> &Bar1 { + &self.foo.as_ref().a + } + pub fn get_b(&self) -> &Bar2 { + &self.foo.as_ref().b + } + fn write_to(&self, buffer: &mut BytesMut) { + self.foo.write_to(buffer) + } + pub fn get_size(&self) -> usize { + self.foo.get_size() + } +} +impl FooBuilder { + pub fn build(self) -> Foo { + let foo = Arc::new(FooData { a: self.a, b: self.b }); + Foo::new(foo).unwrap() + } +} +impl From for Foo { + fn from(builder: FooBuilder) -> Foo { + builder.build().into() + } +} diff --git a/tools/pdl/tests/generated/packet_decl_custom_field_little_endian.rs b/tools/pdl/tests/generated/packet_decl_custom_field_little_endian.rs new file mode 100644 index 00000000000..4a12f13ed4f --- /dev/null +++ b/tools/pdl/tests/generated/packet_decl_custom_field_little_endian.rs @@ -0,0 +1,194 @@ +// @generated rust packets from test + +use bytes::{Buf, BufMut, Bytes, BytesMut}; +use std::cell::Cell; +use std::convert::{TryFrom, TryInto}; +use std::fmt; +use std::sync::Arc; +use thiserror::Error; + +type Result = std::result::Result; + +#[doc = r" Private prevents users from creating arbitrary scalar values"] +#[doc = r" in situations where the value needs to be validated."] +#[doc = r" Users can freely deref the value, but only the backend"] +#[doc = r" may create it."] +#[derive(Debug, Clone, Copy, Hash, PartialEq, Eq, PartialOrd, Ord)] +pub struct Private(T); +impl std::ops::Deref for Private { + type Target = T; + fn deref(&self) -> &Self::Target { + &self.0 + } +} + +#[derive(Debug, Error)] +pub enum Error { + #[error("Packet parsing failed")] + InvalidPacketError, + #[error("{field} was {value:x}, which is not known")] + ConstraintOutOfBounds { field: String, value: u64 }, + #[error("Got {actual:x}, expected {expected:x}")] + InvalidFixedValue { expected: u64, actual: u64 }, + #[error("when parsing {obj} needed length of {wanted} but got {got}")] + InvalidLengthError { obj: String, wanted: usize, got: usize }, + #[error("array size ({array} bytes) is not a multiple of the element size ({element} bytes)")] + InvalidArraySize { array: usize, element: usize }, + #[error("Due to size restrictions a struct could not be parsed.")] + ImpossibleStructError, + #[error("when parsing field {obj}.{field}, {value} is not a valid {type_} value")] + InvalidEnumValueError { obj: String, field: String, value: u64, type_: String }, + #[error("expected child {expected}, got {actual}")] + InvalidChildError { expected: &'static str, actual: String }, +} + +pub trait Packet { + fn to_bytes(self) -> Bytes; + fn to_vec(self) -> Vec; +} + +#[derive(Debug, Clone, Copy, Hash, Eq, PartialEq)] +#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] +#[cfg_attr(feature = "serde", serde(try_from = "u32", into = "u32"))] +pub struct Bar1(u32); +impl From<&Bar1> for u32 { + fn from(value: &Bar1) -> u32 { + value.0 + } +} +impl From for u32 { + fn from(value: Bar1) -> u32 { + value.0 + } +} +impl TryFrom for Bar1 { + type Error = u32; + fn try_from(value: u32) -> std::result::Result { + if value > 0xff_ffff { + Err(value) + } else { + Ok(Bar1(value)) + } + } +} + +#[derive(Debug, Clone, Copy, Hash, Eq, PartialEq)] +#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] +#[cfg_attr(feature = "serde", serde(from = "u32", into = "u32"))] +pub struct Bar2(u32); +impl From<&Bar2> for u32 { + fn from(value: &Bar2) -> u32 { + value.0 + } +} +impl From for u32 { + fn from(value: Bar2) -> u32 { + value.0 + } +} +impl From for Bar2 { + fn from(value: u32) -> Self { + Bar2(value) + } +} + +#[derive(Debug, Clone, PartialEq, Eq)] +#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] +pub struct FooData { + a: Bar1, + b: Bar2, +} +#[derive(Debug, Clone, PartialEq, Eq)] +#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] +pub struct Foo { + #[cfg_attr(feature = "serde", serde(flatten))] + foo: Arc, +} +#[derive(Debug)] +#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] +pub struct FooBuilder { + pub a: Bar1, + pub b: Bar2, +} +impl FooData { + fn conforms(bytes: &[u8]) -> bool { + bytes.len() >= 7 + } + fn parse(bytes: &[u8]) -> Result { + let mut cell = Cell::new(bytes); + let packet = Self::parse_inner(&mut cell)?; + Ok(packet) + } + fn parse_inner(mut bytes: &mut Cell<&[u8]>) -> Result { + let a = (bytes.get_mut().get_uint_le(3) as u32).try_into().unwrap(); + let b = bytes.get_mut().get_u32_le().into(); + Ok(Self { a, b }) + } + fn write_to(&self, buffer: &mut BytesMut) { + buffer.put_uint_le(u32::from(self.a) as u64, 3); + buffer.put_u32_le(u32::from(self.b)); + } + fn get_total_size(&self) -> usize { + self.get_size() + } + fn get_size(&self) -> usize { + 7 + } +} +impl Packet for Foo { + fn to_bytes(self) -> Bytes { + let mut buffer = BytesMut::with_capacity(self.foo.get_size()); + self.foo.write_to(&mut buffer); + buffer.freeze() + } + fn to_vec(self) -> Vec { + self.to_bytes().to_vec() + } +} +impl From for Bytes { + fn from(packet: Foo) -> Self { + packet.to_bytes() + } +} +impl From for Vec { + fn from(packet: Foo) -> Self { + packet.to_vec() + } +} +impl Foo { + pub fn parse(bytes: &[u8]) -> Result { + let mut cell = Cell::new(bytes); + let packet = Self::parse_inner(&mut cell)?; + Ok(packet) + } + fn parse_inner(mut bytes: &mut Cell<&[u8]>) -> Result { + let data = FooData::parse_inner(&mut bytes)?; + Self::new(Arc::new(data)) + } + fn new(foo: Arc) -> Result { + Ok(Self { foo }) + } + pub fn get_a(&self) -> &Bar1 { + &self.foo.as_ref().a + } + pub fn get_b(&self) -> &Bar2 { + &self.foo.as_ref().b + } + fn write_to(&self, buffer: &mut BytesMut) { + self.foo.write_to(buffer) + } + pub fn get_size(&self) -> usize { + self.foo.get_size() + } +} +impl FooBuilder { + pub fn build(self) -> Foo { + let foo = Arc::new(FooData { a: self.a, b: self.b }); + Foo::new(foo).unwrap() + } +} +impl From for Foo { + fn from(builder: FooBuilder) -> Foo { + builder.build().into() + } +} -- GitLab From 2323071db3688295f4ed2d4ee801b1276312bdc3 Mon Sep 17 00:00:00 2001 From: William Escande Date: Thu, 11 May 2023 12:38:37 -0700 Subject: [PATCH 0044/2405] Log bluetooth state change in metrics Bug: 278198192 Test: Unknown Change-Id: I2fb2c6945e979e24eaae0d040d3f9ed530a2d64c --- .../server/bluetooth/BluetoothManagerService.java | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/service/src/com/android/server/bluetooth/BluetoothManagerService.java b/service/src/com/android/server/bluetooth/BluetoothManagerService.java index daa483314dc..e573733c7e6 100644 --- a/service/src/com/android/server/bluetooth/BluetoothManagerService.java +++ b/service/src/com/android/server/bluetooth/BluetoothManagerService.java @@ -90,6 +90,7 @@ import android.util.Log; import android.util.Pair; import android.util.proto.ProtoOutputStream; +import com.android.bluetooth.BluetoothStatsLog; import com.android.internal.annotations.GuardedBy; import com.android.internal.annotations.VisibleForTesting; import com.android.modules.utils.SynchronousResultReceiver; @@ -3094,6 +3095,19 @@ public class BluetoothManagerService extends IBluetoothManager.Stub { } mActiveLogs.add( new ActiveLog(reason, packageName, enable, System.currentTimeMillis())); + + int state = + enable + ? BluetoothStatsLog.BLUETOOTH_ENABLED_STATE_CHANGED__STATE__ENABLED + : BluetoothStatsLog.BLUETOOTH_ENABLED_STATE_CHANGED__STATE__DISABLED; + + BluetoothStatsLog.write_non_chained( + BluetoothStatsLog.BLUETOOTH_ENABLED_STATE_CHANGED, + Binder.getCallingUid(), + null, + state, + reason, + packageName); } } -- GitLab From 9255938279aa0acf88a962641b6ad97e50f3f360 Mon Sep 17 00:00:00 2001 From: Calvin On Date: Mon, 3 Apr 2023 17:55:40 -0700 Subject: [PATCH 0045/2405] Fix bit inversion in RFCOMM event handler. The bit-flip seems to have broken the authentication sequence for incoming RFCOMM connections. Bug: 268273571 Test: Manual (see comment#1 in bug) Ignore-AOSP-First: This branch is unreachable from AOSP. Pending-CP-To-Master: ag/22446590 (cherry picked from https://googleplex-android-review.googlesource.com/q/commit:23e155d25cf425a319fff2049a3e932fd266cc98) Merged-In: I52b4c2f8d595e3d7be3fb18818f8b7f93271fb32 Change-Id: I52b4c2f8d595e3d7be3fb18818f8b7f93271fb32 --- system/stack/rfcomm/rfc_port_fsm.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/system/stack/rfcomm/rfc_port_fsm.cc b/system/stack/rfcomm/rfc_port_fsm.cc index 4919ba9eabc..22baea89fcb 100644 --- a/system/stack/rfcomm/rfc_port_fsm.cc +++ b/system/stack/rfcomm/rfc_port_fsm.cc @@ -150,7 +150,7 @@ void rfc_port_sm_state_closed(tPORT* p_port, tRFC_PORT_EVENT event, /* Open will be continued after security checks are passed */ p_port->rfc.state = RFC_STATE_TERM_WAIT_SEC_CHECK; - btm_sec_mx_access_request(p_port->rfc.p_mcb->bd_addr, true, + btm_sec_mx_access_request(p_port->rfc.p_mcb->bd_addr, false, p_port->sec_mask, &rfc_sec_check_complete, p_port); return; -- GitLab From dcbfc6b8cbfd1d09facc11044bddbdfad28b0c8c Mon Sep 17 00:00:00 2001 From: Myles Watson Date: Fri, 12 May 2023 10:39:05 -0700 Subject: [PATCH 0046/2405] SecurityTest: Remove FakeStorageModule Bug: 260006855 Test: atest bluetooth_unit_test_gd Change-Id: Ifb73badc5dd10ff6416c0ecc8d7d6d0fd1701b98 --- .../record/security_record_storage_test.cc | 17 +++++--- system/gd/security/test/fake_storage_module.h | 42 ------------------- 2 files changed, 11 insertions(+), 48 deletions(-) delete mode 100644 system/gd/security/test/fake_storage_module.h diff --git a/system/gd/security/record/security_record_storage_test.cc b/system/gd/security/record/security_record_storage_test.cc index bd1b748dcc7..5b2d6fdf81b 100644 --- a/system/gd/security/record/security_record_storage_test.cc +++ b/system/gd/security/record/security_record_storage_test.cc @@ -18,21 +18,26 @@ #include -#include "security/test/fake_storage_module.h" +#include "storage/storage_module.h" namespace bluetooth { namespace security { namespace record { namespace { +static const std::chrono::milliseconds kTestConfigSaveDelay = std::chrono::milliseconds(100); + +using storage::StorageModule; + class DISABLED_SecurityRecordStorageTest : public ::testing::Test { protected: void SetUp() override { - // Make Fake storage module - storage_module_ = new FakeStorageModule(); + // Make storage module + storage_module_ = + new StorageModule("/tmp/temp_config.txt", kTestConfigSaveDelay, 100, false, false); // Inject - fake_registry_.InjectTestModule(&storage::StorageModule::Factory, storage_module_); + fake_registry_.InjectTestModule(&StorageModule::Factory, storage_module_); // Make storage record_storage_ = new record::SecurityRecordStorage(storage_module_, handler_); @@ -45,13 +50,13 @@ class DISABLED_SecurityRecordStorageTest : public ::testing::Test { } void synchronize() { - fake_registry_.SynchronizeModuleHandler(&FakeStorageModule::Factory, std::chrono::milliseconds(20)); + fake_registry_.SynchronizeModuleHandler(&StorageModule::Factory, std::chrono::milliseconds(20)); } TestModuleRegistry fake_registry_; os::Thread& thread_ = fake_registry_.GetTestThread(); os::Handler* handler_ = nullptr; - FakeStorageModule* storage_module_; + StorageModule* storage_module_; record::SecurityRecordStorage* record_storage_; }; diff --git a/system/gd/security/test/fake_storage_module.h b/system/gd/security/test/fake_storage_module.h deleted file mode 100644 index cf66a4bec78..00000000000 --- a/system/gd/security/test/fake_storage_module.h +++ /dev/null @@ -1,42 +0,0 @@ -/* - * - * Copyright 2019 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at: - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - */ - -#include "storage/storage_module.h" - -#include - -namespace bluetooth { -namespace security { - -static const std::chrono::milliseconds kTestConfigSaveDelay = std::chrono::milliseconds(100); - -class FakeStorageModule : public storage::StorageModule { - public: - FakeStorageModule() : storage::StorageModule("/tmp/temp_config.txt", kTestConfigSaveDelay, 100, false, false) {} - - storage::ConfigCache* GetConfigCachePublic() { - return StorageModule::GetConfigCache(); - } - - void SaveImmediatelyPublic() { - StorageModule::SaveImmediately(); - } -}; - -} // namespace security -} // namespace bluetooth -- GitLab From 0a70ea9dadbcdffdc3ba665c808ca174e83ff967 Mon Sep 17 00:00:00 2001 From: Ravi Jain Date: Mon, 15 May 2023 06:49:00 +0000 Subject: [PATCH 0047/2405] Revert "rust: Make AttPermissions compatible with libbitflags 2.2.1" Revert submission 23170841-cherrypicker-L56400000960600321:N14500001367781407 Reason for revert: DroidMonitor: Potential culprit for Bug b/282265637 - verifying through ABTD before revert submission. This is part of the standard investigation process, and does not mean your CL will be reverted. Reverted changes: /q/submissionid:23170841-cherrypicker-L56400000960600321:N14500001367781407 Change-Id: Icbd2de5059d5ac3627b7483cc7970d942ccf3d6b --- system/rust/src/gatt/server/att_database.rs | 1 - 1 file changed, 1 deletion(-) diff --git a/system/rust/src/gatt/server/att_database.rs b/system/rust/src/gatt/server/att_database.rs index 2235fd81f59..db2d7318826 100644 --- a/system/rust/src/gatt/server/att_database.rs +++ b/system/rust/src/gatt/server/att_database.rs @@ -34,7 +34,6 @@ bitflags! { /// /// These values are from Core Spec 5.3 Vol 3G 3.3.1.1 Characteristic Properties, /// and also match what Android uses in JNI. - #[derive(Copy, Clone, Debug, PartialEq, Eq)] pub struct AttPermissions : u8 { /// Attribute can be read using READ_REQ const READABLE = 0x02; -- GitLab From ba4211ba2e708a8362b5552de763a1cbd4f910a1 Mon Sep 17 00:00:00 2001 From: Ravi Jain Date: Mon, 15 May 2023 06:49:00 +0000 Subject: [PATCH 0048/2405] Revert "[automerge] rust: Make AttPermissions compatible with li..." Revert submission 23170841-cherrypicker-L56400000960600321:N14500001367781407 Reason for revert: DroidMonitor: Potential culprit for Bug b/282265637 - verifying through ABTD before revert submission. This is part of the standard investigation process, and does not mean your CL will be reverted. Reverted changes: /q/submissionid:23170841-cherrypicker-L56400000960600321:N14500001367781407 Change-Id: Ib35ccf2a8c27a638150d6df52824b76619b7972d --- system/rust/src/gatt/server/att_database.rs | 1 - 1 file changed, 1 deletion(-) diff --git a/system/rust/src/gatt/server/att_database.rs b/system/rust/src/gatt/server/att_database.rs index 2235fd81f59..db2d7318826 100644 --- a/system/rust/src/gatt/server/att_database.rs +++ b/system/rust/src/gatt/server/att_database.rs @@ -34,7 +34,6 @@ bitflags! { /// /// These values are from Core Spec 5.3 Vol 3G 3.3.1.1 Characteristic Properties, /// and also match what Android uses in JNI. - #[derive(Copy, Clone, Debug, PartialEq, Eq)] pub struct AttPermissions : u8 { /// Attribute can be read using READ_REQ const READABLE = 0x02; -- GitLab From 5fd37a23a2281a8d65b327aa8bb8011478c120aa Mon Sep 17 00:00:00 2001 From: David Duarte Date: Mon, 15 May 2023 11:31:05 +0000 Subject: [PATCH 0049/2405] Revert "Remove unused dut_mode from bluetooth interface" This reverts commit 0fd84ef210ae59e959948eccba35fd18386ebb94. Reason for revert: b/269397845 Bug: 269397845 Test: mma Change-Id: I0bc217670292449e0eab113688a4555833ca4271 --- ...oid_bluetooth_btservice_AdapterService.cpp | 5 ++ system/bta/dm/bta_dm_api.cc | 6 ++ system/bta/include/bta_api.h | 12 ++++ system/btif/include/btif_api.h | 21 ++++++ system/btif/src/bluetooth.cc | 28 ++++++++ system/btif/src/btif_core.cc | 70 ++++++++++++++++++- system/btif/test/btif_core_test.cc | 2 + system/btif/test/btif_hh_test.cc | 1 + system/gd/rust/topshim/src/btif.rs | 2 + system/include/hardware/bluetooth.h | 15 ++++ system/main/shim/btm_api.h | 17 +++++ system/stack/btm/btm_devctl.cc | 44 ++++++++++++ system/stack/hcic/hcicmds.cc | 54 ++++++++++++++ system/stack/include/btm_api.h | 17 +++++ system/stack/include/hcimsgs.h | 7 ++ system/test/headless/headless.cc | 7 ++ system/test/mock/mock_bta_dm_api.cc | 5 ++ system/test/mock/mock_bta_dm_api.h | 9 +++ system/test/mock/mock_btif_bluetooth.cc | 10 +++ system/test/mock/mock_btif_bluetooth.h | 19 +++++ system/test/mock/mock_btif_core.cc | 8 +++ system/test/mock/mock_stack_btm_devctl.cc | 4 ++ system/test/mock/mock_stack_hcic_hcicmds.cc | 12 ++++ system/test/mock/mock_stack_hcic_hcicmds.h | 24 +++++++ 24 files changed, 398 insertions(+), 1 deletion(-) diff --git a/android/app/jni/com_android_bluetooth_btservice_AdapterService.cpp b/android/app/jni/com_android_bluetooth_btservice_AdapterService.cpp index 7648871be13..32ca755e908 100644 --- a/android/app/jni/com_android_bluetooth_btservice_AdapterService.cpp +++ b/android/app/jni/com_android_bluetooth_btservice_AdapterService.cpp @@ -685,6 +685,10 @@ static void callback_thread_event(bt_cb_thread_evt event) { } } +static void dut_mode_recv_callback(uint16_t opcode, uint8_t* buf, uint8_t len) { + +} + static void energy_info_recv_callback(bt_activity_energy_info* p_energy_info, bt_uid_traffic_t* uid_data) { CallbackEnv sCallbackEnv(__func__); @@ -728,6 +732,7 @@ static bt_callbacks_t sBluetoothCallbacks = {sizeof(sBluetoothCallbacks), le_address_associate_callback, acl_state_changed_callback, callback_thread_event, + dut_mode_recv_callback, energy_info_recv_callback, link_quality_report_callback, generate_local_oob_data_callback, diff --git a/system/bta/dm/bta_dm_api.cc b/system/bta/dm/bta_dm_api.cc index 325d82ef75b..e31d66737f9 100644 --- a/system/bta/dm/bta_dm_api.cc +++ b/system/bta/dm/bta_dm_api.cc @@ -55,6 +55,12 @@ void BTA_dm_init() { BTM_SetConsolidationCallback(bta_dm_consolidate); } +/** Enables bluetooth device under test mode */ +void BTA_EnableTestMode(void) { + do_in_main_thread(FROM_HERE, + base::Bind(base::IgnoreResult(BTM_EnableTestMode))); +} + /** This function sets the Bluetooth name of local device */ void BTA_DmSetDeviceName(const char* p_name) { std::vector name(BD_NAME_LEN + 1); diff --git a/system/bta/include/bta_api.h b/system/bta/include/bta_api.h index 97a57487316..5b7d14069ea 100644 --- a/system/bta/include/bta_api.h +++ b/system/bta/include/bta_api.h @@ -741,6 +741,18 @@ enum { void BTA_dm_init(); +/******************************************************************************* + * + * Function BTA_EnableTestMode + * + * Description Enables bluetooth device under test mode + * + * + * Returns tBTA_STATUS + * + ******************************************************************************/ +extern void BTA_EnableTestMode(void); + /******************************************************************************* * * Function BTA_DmSetDeviceName diff --git a/system/btif/include/btif_api.h b/system/btif/include/btif_api.h index 55b9da1ac65..6a44658b41d 100644 --- a/system/btif/include/btif_api.h +++ b/system/btif/include/btif_api.h @@ -329,6 +329,27 @@ bt_status_t btif_dm_get_adapter_property(bt_property_t* prop); ******************************************************************************/ void btif_dm_get_remote_services(const RawAddress remote_addr, int transport); +/******************************************************************************* + * + * Function btif_dut_mode_configure + * + * Description Configure Test Mode - 'enable' to 1 puts the device in test + * mode and 0 exits test mode + * + ******************************************************************************/ +void btif_dut_mode_configure(uint8_t enable); + +bool btif_is_dut_mode(); + +/******************************************************************************* + * + * Function btif_dut_mode_send + * + * Description Sends a HCI Vendor specific command to the controller + * + ******************************************************************************/ +void btif_dut_mode_send(uint16_t opcode, uint8_t* buf, uint8_t len); + /******************************************************************************* * * Function btif_dm_read_energy_info diff --git a/system/btif/src/bluetooth.cc b/system/btif/src/bluetooth.cc index 9d0ef836c23..24c45b3b7fb 100644 --- a/system/btif/src/bluetooth.cc +++ b/system/btif/src/bluetooth.cc @@ -917,6 +917,32 @@ static const void* get_profile_interface(const char* profile_id) { return NULL; } +int dut_mode_configure(uint8_t enable) { + if (!interface_ready()) return BT_STATUS_NOT_READY; + if (!stack_manager_get_interface()->get_stack_is_running()) + return BT_STATUS_NOT_READY; + + do_in_main_thread(FROM_HERE, base::BindOnce(btif_dut_mode_configure, enable)); + return BT_STATUS_SUCCESS; +} + +int dut_mode_send(uint16_t opcode, uint8_t* buf, uint8_t len) { + if (!interface_ready()) return BT_STATUS_NOT_READY; + if (!btif_is_dut_mode()) return BT_STATUS_FAIL; + + uint8_t* copy = (uint8_t*)osi_calloc(len); + memcpy(copy, buf, len); + + do_in_main_thread(FROM_HERE, + base::BindOnce( + [](uint16_t opcode, uint8_t* buf, uint8_t len) { + btif_dut_mode_send(opcode, buf, len); + osi_free(buf); + }, + opcode, copy, len)); + return BT_STATUS_SUCCESS; +} + static bt_os_callouts_t* wakelock_os_callouts_saved = nullptr; static int acquire_wake_lock_cb(const char* lock_name) { @@ -1108,6 +1134,8 @@ EXPORT_SYMBOL bt_interface_t bluetoothInterface = { .pin_reply = pin_reply, .ssp_reply = ssp_reply, .get_profile_interface = get_profile_interface, + .dut_mode_configure = dut_mode_configure, + .dut_mode_send = dut_mode_send, .set_os_callouts = set_os_callouts, .read_energy_info = read_energy_info, .dump = dump, diff --git a/system/btif/src/btif_core.cc b/system/btif/src/btif_core.cc index c0499108803..ab609b30756 100644 --- a/system/btif/src/btif_core.cc +++ b/system/btif/src/btif_core.cc @@ -94,6 +94,14 @@ static void bt_jni_msg_ready(void* context); static tBTA_SERVICE_MASK btif_enabled_services = 0; +/* + * This variable should be set to 1, if the Bluedroid+BTIF libraries are to + * function in DUT mode. + * + * To set this, the btif_init_bluetooth needs to be called with argument as 1 + */ +static uint8_t btif_dut_mode = 0; + static MessageLoopThread jni_thread("bt_jni_thread"); static base::AtExitManager* exit_manager; static uid_set_t* uid_set; @@ -181,6 +189,18 @@ void post_on_bt_jni(BtJniClosure closure) { BT_STATUS_SUCCESS); } +/******************************************************************************* + * + * Function btif_is_dut_mode + * + * Description checks if BTIF is currently in DUT mode + * + * Returns true if test mode, otherwise false + * + ******************************************************************************/ + +bool btif_is_dut_mode() { return btif_dut_mode == 1; } + /******************************************************************************* * * Function btif_is_enabled @@ -192,7 +212,8 @@ void post_on_bt_jni(BtJniClosure closure) { ******************************************************************************/ int btif_is_enabled(void) { - return (stack_manager_get_interface()->get_stack_is_running()); + return ((!btif_is_dut_mode()) && + (stack_manager_get_interface()->get_stack_is_running())); } void btif_init_ok() { @@ -313,10 +334,57 @@ bt_status_t btif_cleanup_bluetooth() { jni_thread.ShutDown(); delete exit_manager; exit_manager = nullptr; + btif_dut_mode = 0; LOG_INFO("%s finished", __func__); return BT_STATUS_SUCCESS; } +/******************************************************************************* + * + * Function btif_dut_mode_cback + * + * Description Callback invoked on completion of vendor specific test mode + * command + * + * Returns None + * + ******************************************************************************/ +static void btif_dut_mode_cback(UNUSED_ATTR tBTM_VSC_CMPL* p) { + /* For now nothing to be done. */ +} + +/******************************************************************************* + * + * Function btif_dut_mode_configure + * + * Description Configure Test Mode - 'enable' to 1 puts the device in test + * mode and 0 exits test mode + * + ******************************************************************************/ +void btif_dut_mode_configure(uint8_t enable) { + BTIF_TRACE_DEBUG("%s", __func__); + + btif_dut_mode = enable; + if (enable == 1) { + BTA_EnableTestMode(); + } else { + // Can't do in process reset anyways - just quit + kill(getpid(), SIGKILL); + } +} + +/******************************************************************************* + * + * Function btif_dut_mode_send + * + * Description Sends a HCI Vendor specific command to the controller + * + ******************************************************************************/ +void btif_dut_mode_send(uint16_t opcode, uint8_t* buf, uint8_t len) { + BTIF_TRACE_DEBUG("%s", __func__); + BTM_VendorSpecificCommand(opcode, len, buf, btif_dut_mode_cback); +} + /***************************************************************************** * * btif api adapter property functions diff --git a/system/btif/test/btif_core_test.cc b/system/btif/test/btif_core_test.cc index 27df5e1b697..ab37b95cd36 100644 --- a/system/btif/test/btif_core_test.cc +++ b/system/btif/test/btif_core_test.cc @@ -85,6 +85,7 @@ void link_quality_report_callback(uint64_t timestamp, int report_id, int rssi, int packets_not_receive_count, int negative_acknowledgement_count) {} void callback_thread_event(bt_cb_thread_evt evt) { TESTCB; } +void dut_mode_recv_callback(uint16_t opcode, uint8_t* buf, uint8_t len) {} void energy_info_callback(bt_activity_energy_info* energy_info, bt_uid_traffic_t* uid_data) {} void generate_local_oob_data_callback(tBT_TRANSPORT transport, @@ -107,6 +108,7 @@ bt_callbacks_t callbacks = { .le_address_associate_cb = le_address_associate_callback, .acl_state_changed_cb = acl_state_changed_callback, .thread_evt_cb = callback_thread_event, + .dut_mode_recv_cb = dut_mode_recv_callback, .energy_info_cb = energy_info_callback, .link_quality_report_cb = link_quality_report_callback, .generate_local_oob_data_cb = generate_local_oob_data_callback, diff --git a/system/btif/test/btif_hh_test.cc b/system/btif/test/btif_hh_test.cc index b5efa5c40b7..de215c2689e 100644 --- a/system/btif/test/btif_hh_test.cc +++ b/system/btif/test/btif_hh_test.cc @@ -133,6 +133,7 @@ bt_callbacks_t bt_callbacks = { .le_address_associate_cb = nullptr, // le_address_associate_callback .acl_state_changed_cb = nullptr, // acl_state_changed_callback .thread_evt_cb = nullptr, // callback_thread_event + .dut_mode_recv_cb = nullptr, // dut_mode_recv_callback .energy_info_cb = nullptr, // energy_info_callback .link_quality_report_cb = nullptr, // link_quality_report_callback .generate_local_oob_data_cb = nullptr, // generate_local_oob_data_callback diff --git a/system/gd/rust/topshim/src/btif.rs b/system/gd/rust/topshim/src/btif.rs index 02e5559056f..0973d8ad718 100644 --- a/system/gd/rust/topshim/src/btif.rs +++ b/system/gd/rust/topshim/src/btif.rs @@ -884,6 +884,7 @@ pub enum BaseCallbacks { ), // Unimplemented so far: // thread_evt_cb + // dut_mode_recv_cb // energy_info_cb // link_quality_report_cb // switch_buffer_size_cb @@ -1070,6 +1071,7 @@ impl BluetoothInterface { le_address_associate_cb: Some(le_address_associate_cb), acl_state_changed_cb: Some(acl_state_cb), thread_evt_cb: None, + dut_mode_recv_cb: None, energy_info_cb: None, link_quality_report_cb: None, generate_local_oob_data_cb: Some(generate_local_oob_data_cb), diff --git a/system/include/hardware/bluetooth.h b/system/include/hardware/bluetooth.h index a44a75d191a..031ce226de8 100644 --- a/system/include/hardware/bluetooth.h +++ b/system/include/hardware/bluetooth.h @@ -544,6 +544,12 @@ typedef enum { ASSOCIATE_JVM, DISASSOCIATE_JVM } bt_cb_thread_evt; * attach/detach to/from the JVM */ typedef void (*callback_thread_event)(bt_cb_thread_evt evt); +/** Bluetooth Test Mode Callback */ +/* Receive any HCI event from controller. Must be in DUT Mode for this callback + * to be received */ +typedef void (*dut_mode_recv_callback)(uint16_t opcode, uint8_t* buf, + uint8_t len); + /** Callback invoked when energy details are obtained */ /* Ctrl_state-Current controller state-Active-1,scan-2,or idle-3 state as * defined by HCI spec. If the ctrl_state value is 0, it means the API call @@ -578,6 +584,7 @@ typedef struct { le_address_associate_callback le_address_associate_cb; acl_state_changed_callback acl_state_changed_cb; callback_thread_event thread_evt_cb; + dut_mode_recv_callback dut_mode_recv_cb; energy_info_callback energy_info_cb; link_quality_report_callback link_quality_report_cb; generate_local_oob_data_callback generate_local_oob_data_cb; @@ -730,6 +737,14 @@ typedef struct { /** Get Bluetooth profile interface */ const void* (*get_profile_interface)(const char* profile_id); + /** Bluetooth Test Mode APIs - Bluetooth must be enabled for these APIs */ + /* Configure DUT Mode - Use this mode to enter/exit DUT mode */ + int (*dut_mode_configure)(uint8_t enable); + + /* Send any test HCI (vendor-specific) command to the controller. Must be in + * DUT Mode */ + int (*dut_mode_send)(uint16_t opcode, uint8_t* buf, uint8_t len); + /** Sets the OS call-out functions that bluedroid needs for alarms and wake * locks. This should be called immediately after a successful |init|. */ diff --git a/system/main/shim/btm_api.h b/system/main/shim/btm_api.h index 948da468c80..e14eb4a210d 100644 --- a/system/main/shim/btm_api.h +++ b/system/main/shim/btm_api.h @@ -921,6 +921,23 @@ void BTM_WritePageTimeout(uint16_t timeout); ******************************************************************************/ void BTM_WriteVoiceSettings(uint16_t settings); +/******************************************************************************* + * + * Function BTM_EnableTestMode + * + * Description Send HCI the enable device under test command. + * + * Note: Controller can only be taken out of this mode by + * resetting the controller. + * + * Returns + * BTM_SUCCESS Command sent. + * BTM_NO_RESOURCES If out of resources to send the command. + * + * + ******************************************************************************/ +tBTM_STATUS BTM_EnableTestMode(void); + /******************************************************************************* * * Function BTM_ReadRemoteVersion diff --git a/system/stack/btm/btm_devctl.cc b/system/stack/btm/btm_devctl.cc index 91cc7b6b817..e3d214793f4 100644 --- a/system/stack/btm/btm_devctl.cc +++ b/system/stack/btm/btm_devctl.cc @@ -629,6 +629,50 @@ void BTM_WriteVoiceSettings(uint16_t settings) { btsnd_hcic_write_voice_settings((uint16_t)(settings & 0x03ff)); } +/******************************************************************************* + * + * Function BTM_EnableTestMode + * + * Description Send HCI the enable device under test command. + * + * Note: Controller can only be taken out of this mode by + * resetting the controller. + * + * Returns + * BTM_SUCCESS Command sent. + * BTM_NO_RESOURCES If out of resources to send the command. + * + * + ******************************************************************************/ +tBTM_STATUS BTM_EnableTestMode(void) { + uint8_t cond; + + BTM_TRACE_EVENT("BTM: BTM_EnableTestMode"); + + /* set auto accept connection as this is needed during test mode */ + /* Allocate a buffer to hold HCI command */ + cond = HCI_DO_AUTO_ACCEPT_CONNECT; + btsnd_hcic_set_event_filter(HCI_FILTER_CONNECTION_SETUP, + HCI_FILTER_COND_NEW_DEVICE, &cond, sizeof(cond)); + + /* put device to connectable mode */ + if (BTM_SetConnectability(BTM_CONNECTABLE) != BTM_SUCCESS) { + return BTM_NO_RESOURCES; + } + + /* put device to discoverable mode */ + if (BTM_SetDiscoverability(BTM_GENERAL_DISCOVERABLE) != BTM_SUCCESS) { + return BTM_NO_RESOURCES; + } + + /* mask off all of event from controller */ + bluetooth::shim::BTM_ClearEventMask(); + + /* Send the HCI command */ + btsnd_hcic_enable_test_mode(); + return (BTM_SUCCESS); +} + /******************************************************************************* * * Function BTM_DeleteStoredLinkKey diff --git a/system/stack/hcic/hcicmds.cc b/system/stack/hcic/hcicmds.cc index c49cd713ba2..aa45842da58 100644 --- a/system/stack/hcic/hcicmds.cc +++ b/system/stack/hcic/hcicmds.cc @@ -997,6 +997,47 @@ void btsnd_hcic_write_def_policy_set(uint16_t settings) { btu_hcif_send_cmd(LOCAL_BR_EDR_CONTROLLER_ID, p); } +void btsnd_hcic_set_event_filter(uint8_t filt_type, uint8_t filt_cond_type, + uint8_t* filt_cond, uint8_t filt_cond_len) { + BT_HDR* p = (BT_HDR*)osi_malloc(HCI_CMD_BUF_SIZE); + uint8_t* pp = (uint8_t*)(p + 1); + + p->offset = 0; + + UINT16_TO_STREAM(pp, HCI_SET_EVENT_FILTER); + + if (filt_type) { + p->len = (uint16_t)(HCIC_PREAMBLE_SIZE + 2 + filt_cond_len); + UINT8_TO_STREAM(pp, (uint8_t)(2 + filt_cond_len)); + + UINT8_TO_STREAM(pp, filt_type); + UINT8_TO_STREAM(pp, filt_cond_type); + + if (filt_cond_type == HCI_FILTER_COND_DEVICE_CLASS) { + DEVCLASS_TO_STREAM(pp, filt_cond); + filt_cond += DEV_CLASS_LEN; + DEVCLASS_TO_STREAM(pp, filt_cond); + filt_cond += DEV_CLASS_LEN; + + filt_cond_len -= (2 * DEV_CLASS_LEN); + } else if (filt_cond_type == HCI_FILTER_COND_BD_ADDR) { + BDADDR_TO_STREAM(pp, *((RawAddress*)filt_cond)); + filt_cond += BD_ADDR_LEN; + + filt_cond_len -= BD_ADDR_LEN; + } + + if (filt_cond_len) ARRAY_TO_STREAM(pp, filt_cond, filt_cond_len); + } else { + p->len = (uint16_t)(HCIC_PREAMBLE_SIZE + 1); + UINT8_TO_STREAM(pp, 1); + + UINT8_TO_STREAM(pp, filt_type); + } + + btu_hcif_send_cmd(LOCAL_BR_EDR_CONTROLLER_ID, p); +} + void btsnd_hcic_write_pin_type(uint8_t type) { BT_HDR* p = (BT_HDR*)osi_malloc(HCI_CMD_BUF_SIZE); uint8_t* pp = (uint8_t*)(p + 1); @@ -1581,6 +1622,19 @@ void btsnd_hcic_read_failed_contact_counter(uint16_t handle) { btu_hcif_send_cmd(LOCAL_BR_EDR_CONTROLLER_ID, p); } +void btsnd_hcic_enable_test_mode(void) { + BT_HDR* p = (BT_HDR*)osi_malloc(HCI_CMD_BUF_SIZE); + uint8_t* pp = (uint8_t*)(p + 1); + + p->len = HCIC_PREAMBLE_SIZE + HCIC_PARAM_SIZE_READ_CMD; + p->offset = 0; + + UINT16_TO_STREAM(pp, HCI_ENABLE_DEV_UNDER_TEST_MODE); + UINT8_TO_STREAM(pp, HCIC_PARAM_SIZE_READ_CMD); + + btu_hcif_send_cmd(LOCAL_BR_EDR_CONTROLLER_ID, p); +} + void btsnd_hcic_write_inqscan_type(uint8_t type) { BT_HDR* p = (BT_HDR*)osi_malloc(HCI_CMD_BUF_SIZE); uint8_t* pp = (uint8_t*)(p + 1); diff --git a/system/stack/include/btm_api.h b/system/stack/include/btm_api.h index 72f680d8553..12fb5b194ba 100644 --- a/system/stack/include/btm_api.h +++ b/system/stack/include/btm_api.h @@ -220,6 +220,23 @@ void BTM_WritePageTimeout(uint16_t timeout); ******************************************************************************/ void BTM_WriteVoiceSettings(uint16_t settings); +/******************************************************************************* + * + * Function BTM_EnableTestMode + * + * Description Send HCI the enable device under test command. + * + * Note: Controller can only be taken out of this mode by + * resetting the controller. + * + * Returns + * BTM_SUCCESS Command sent. + * BTM_NO_RESOURCES If out of resources to send the command. + * + * + ******************************************************************************/ +tBTM_STATUS BTM_EnableTestMode(void); + /******************************************************************************* * DEVICE DISCOVERY FUNCTIONS - Inquiry, Remote Name, Discovery, Class of Device ******************************************************************************/ diff --git a/system/stack/include/hcimsgs.h b/system/stack/include/hcimsgs.h index ac9deb17e62..675c64e6978 100644 --- a/system/stack/include/hcimsgs.h +++ b/system/stack/include/hcimsgs.h @@ -203,6 +203,12 @@ void btsnd_hcic_enhanced_flush(uint16_t handle, uint8_t packet_type); /**** end of Simple Pairing Commands ****/ +extern void btsnd_hcic_set_event_filter(uint8_t filt_type, + uint8_t filt_cond_type, + uint8_t* filt_cond, + uint8_t filt_cond_len); +/* Set Event Filter */ + /* Delete Stored Key */ void btsnd_hcic_delete_stored_key(const RawAddress& bd_addr, bool delete_all_flag); @@ -253,6 +259,7 @@ void btsnd_hcic_read_rssi(uint16_t handle); /* Read RSSI */ using ReadEncKeySizeCb = base::OnceCallback; void btsnd_hcic_read_encryption_key_size(uint16_t handle, ReadEncKeySizeCb cb); void btsnd_hcic_read_failed_contact_counter(uint16_t handle); +void btsnd_hcic_enable_test_mode(void); /* Enable Device Under Test Mode */ void btsnd_hcic_write_pagescan_type(uint8_t type); /* Write Page Scan Type */ void btsnd_hcic_write_inqscan_type(uint8_t type); /* Write Inquiry Scan Type */ void btsnd_hcic_write_inquiry_mode(uint8_t type); /* Write Inquiry Mode */ diff --git a/system/test/headless/headless.cc b/system/test/headless/headless.cc index f2cc739beb6..551a6d666a0 100644 --- a/system/test/headless/headless.cc +++ b/system/test/headless/headless.cc @@ -199,6 +199,12 @@ void thread_event([[maybe_unused]] bt_cb_thread_evt evt) { LOG_INFO("%s", __func__); } +void dut_mode_recv([[maybe_unused]] uint16_t opcode, + [[maybe_unused]] uint8_t* buf, + [[maybe_unused]] uint8_t len) { + LOG_INFO("%s", __func__); +} + void energy_info([[maybe_unused]] bt_activity_energy_info* energy_info, [[maybe_unused]] bt_uid_traffic_t* uid_data) { LOG_INFO("%s", __func__); @@ -219,6 +225,7 @@ bt_callbacks_t bt_callbacks{ .le_address_associate_cb = le_address_associate, .acl_state_changed_cb = acl_state_changed, .thread_evt_cb = thread_event, + .dut_mode_recv_cb = dut_mode_recv, .energy_info_cb = energy_info, .link_quality_report_cb = link_quality_report, .switch_buffer_size_cb = switch_buffer_size, diff --git a/system/test/mock/mock_bta_dm_api.cc b/system/test/mock/mock_bta_dm_api.cc index c61070b7159..1d9042f61e9 100644 --- a/system/test/mock/mock_bta_dm_api.cc +++ b/system/test/mock/mock_bta_dm_api.cc @@ -67,6 +67,7 @@ struct BTA_DmSetBlePrefConnParams BTA_DmSetBlePrefConnParams; struct BTA_DmSetDeviceName BTA_DmSetDeviceName; struct BTA_DmSetEncryption BTA_DmSetEncryption; struct BTA_DmSetLocalDiRecord BTA_DmSetLocalDiRecord; +struct BTA_EnableTestMode BTA_EnableTestMode; struct BTA_GetEirService BTA_GetEirService; struct BTA_VendorInit BTA_VendorInit; struct BTA_dm_init BTA_dm_init; @@ -215,6 +216,10 @@ tBTA_STATUS BTA_DmSetLocalDiRecord(tSDP_DI_RECORD* p_device_info, return test::mock::bta_dm_api::BTA_DmSetLocalDiRecord(p_device_info, p_handle); } +void BTA_EnableTestMode(void) { + inc_func_call_count(__func__); + test::mock::bta_dm_api::BTA_EnableTestMode(); +} void BTA_GetEirService(const uint8_t* p_eir, size_t eir_len, tBTA_SERVICE_MASK* p_services) { inc_func_call_count(__func__); diff --git a/system/test/mock/mock_bta_dm_api.h b/system/test/mock/mock_bta_dm_api.h index cd3473ee745..78ca8145cfd 100644 --- a/system/test/mock/mock_bta_dm_api.h +++ b/system/test/mock/mock_bta_dm_api.h @@ -418,6 +418,15 @@ struct BTA_DmSetLocalDiRecord { }; extern struct BTA_DmSetLocalDiRecord BTA_DmSetLocalDiRecord; +// Name: BTA_EnableTestMode +// Params: void +// Return: void +struct BTA_EnableTestMode { + std::function body{[](void) {}}; + void operator()(void) { body(); }; +}; +extern struct BTA_EnableTestMode BTA_EnableTestMode; + // Name: BTA_GetEirService // Params: uint8_t* p_eir, size_t eir_len, tBTA_SERVICE_MASK* p_services // Return: void diff --git a/system/test/mock/mock_btif_bluetooth.cc b/system/test/mock/mock_btif_bluetooth.cc index e9a6a8188ee..a5994721ea9 100644 --- a/system/test/mock/mock_btif_bluetooth.cc +++ b/system/test/mock/mock_btif_bluetooth.cc @@ -45,6 +45,8 @@ namespace btif_bluetooth { struct is_atv_device is_atv_device; struct is_common_criteria_mode is_common_criteria_mode; struct is_restricted_mode is_restricted_mode; +struct dut_mode_configure dut_mode_configure; +struct dut_mode_send dut_mode_send; struct get_common_criteria_config_compare_result get_common_criteria_config_compare_result; struct get_remote_device_properties get_remote_device_properties; @@ -70,6 +72,14 @@ bool is_restricted_mode() { inc_func_call_count(__func__); return test::mock::btif_bluetooth::is_restricted_mode(); } +int dut_mode_configure(uint8_t enable) { + inc_func_call_count(__func__); + return test::mock::btif_bluetooth::dut_mode_configure(enable); +} +int dut_mode_send(uint16_t opcode, uint8_t* buf, uint8_t len) { + inc_func_call_count(__func__); + return test::mock::btif_bluetooth::dut_mode_send(opcode, buf, len); +} int get_common_criteria_config_compare_result() { inc_func_call_count(__func__); return test::mock::btif_bluetooth:: diff --git a/system/test/mock/mock_btif_bluetooth.h b/system/test/mock/mock_btif_bluetooth.h index a272a4ffa5d..c007631f733 100644 --- a/system/test/mock/mock_btif_bluetooth.h +++ b/system/test/mock/mock_btif_bluetooth.h @@ -71,6 +71,25 @@ struct is_restricted_mode { bool operator()() { return body(); }; }; extern struct is_restricted_mode is_restricted_mode; +// Name: dut_mode_configure +// Params: uint8_t enable +// Returns: int +struct dut_mode_configure { + std::function body{[](uint8_t enable) { return 0; }}; + int operator()(uint8_t enable) { return body(enable); }; +}; +extern struct dut_mode_configure dut_mode_configure; +// Name: dut_mode_send +// Params: uint16_t opcode, uint8_t* buf, uint8_t len +// Returns: int +struct dut_mode_send { + std::function body{ + [](uint16_t opcode, uint8_t* buf, uint8_t len) { return 0; }}; + int operator()(uint16_t opcode, uint8_t* buf, uint8_t len) { + return body(opcode, buf, len); + }; +}; +extern struct dut_mode_send dut_mode_send; // Name: get_common_criteria_config_compare_result // Params: // Returns: int diff --git a/system/test/mock/mock_btif_core.cc b/system/test/mock/mock_btif_core.cc index 75544b45f04..59de7df0185 100644 --- a/system/test/mock/mock_btif_core.cc +++ b/system/test/mock/mock_btif_core.cc @@ -35,6 +35,10 @@ #define UNUSED_ATTR #endif +bool btif_is_dut_mode() { + inc_func_call_count(__func__); + return false; +} bool is_on_jni_thread() { inc_func_call_count(__func__); return false; @@ -94,6 +98,10 @@ void btif_adapter_properties_evt(bt_status_t status, uint32_t num_props, void btif_disable_service(tBTA_SERVICE_ID service_id) { inc_func_call_count(__func__); } +void btif_dut_mode_configure(uint8_t enable) { inc_func_call_count(__func__); } +void btif_dut_mode_send(uint16_t opcode, uint8_t* buf, uint8_t len) { + inc_func_call_count(__func__); +} void btif_enable_bluetooth_evt() { inc_func_call_count(__func__); } void btif_enable_service(tBTA_SERVICE_ID service_id) { inc_func_call_count(__func__); diff --git a/system/test/mock/mock_stack_btm_devctl.cc b/system/test/mock/mock_stack_btm_devctl.cc index 48959cd9eaa..b24df121410 100644 --- a/system/test/mock/mock_stack_btm_devctl.cc +++ b/system/test/mock/mock_stack_btm_devctl.cc @@ -75,6 +75,10 @@ tBTM_STATUS BTM_DeleteStoredLinkKey(const RawAddress* bd_addr, inc_func_call_count(__func__); return BTM_SUCCESS; } +tBTM_STATUS BTM_EnableTestMode(void) { + inc_func_call_count(__func__); + return BTM_SUCCESS; +} tBTM_STATUS BTM_ReadLocalDeviceName(const char** p_name) { inc_func_call_count(__func__); return BTM_SUCCESS; diff --git a/system/test/mock/mock_stack_hcic_hcicmds.cc b/system/test/mock/mock_stack_hcic_hcicmds.cc index 9d2af01caa0..242e6146939 100644 --- a/system/test/mock/mock_stack_hcic_hcicmds.cc +++ b/system/test/mock/mock_stack_hcic_hcicmds.cc @@ -44,6 +44,7 @@ struct btsnd_hcic_change_conn_type btsnd_hcic_change_conn_type; struct btsnd_hcic_change_name btsnd_hcic_change_name; struct btsnd_hcic_create_conn_cancel btsnd_hcic_create_conn_cancel; struct btsnd_hcic_delete_stored_key btsnd_hcic_delete_stored_key; +struct btsnd_hcic_enable_test_mode btsnd_hcic_enable_test_mode; struct btsnd_hcic_enhanced_accept_synchronous_connection btsnd_hcic_enhanced_accept_synchronous_connection; struct btsnd_hcic_enhanced_flush btsnd_hcic_enhanced_flush; @@ -76,6 +77,7 @@ struct btsnd_hcic_rmt_name_req btsnd_hcic_rmt_name_req; struct btsnd_hcic_rmt_name_req_cancel btsnd_hcic_rmt_name_req_cancel; struct btsnd_hcic_rmt_ver_req btsnd_hcic_rmt_ver_req; struct btsnd_hcic_set_conn_encrypt btsnd_hcic_set_conn_encrypt; +struct btsnd_hcic_set_event_filter btsnd_hcic_set_event_filter; struct btsnd_hcic_setup_esco_conn btsnd_hcic_setup_esco_conn; struct btsnd_hcic_sniff_mode btsnd_hcic_sniff_mode; struct btsnd_hcic_sniff_sub_rate btsnd_hcic_sniff_sub_rate; @@ -150,6 +152,10 @@ void btsnd_hcic_delete_stored_key(const RawAddress& bd_addr, test::mock::stack_hcic_hcicmds::btsnd_hcic_delete_stored_key(bd_addr, delete_all_flag); } +void btsnd_hcic_enable_test_mode(void) { + inc_func_call_count(__func__); + test::mock::stack_hcic_hcicmds::btsnd_hcic_enable_test_mode(); +} void btsnd_hcic_enhanced_accept_synchronous_connection( const RawAddress& bd_addr, enh_esco_params_t* p_params) { inc_func_call_count(__func__); @@ -289,6 +295,12 @@ void btsnd_hcic_set_conn_encrypt(uint16_t handle, bool enable) { inc_func_call_count(__func__); test::mock::stack_hcic_hcicmds::btsnd_hcic_set_conn_encrypt(handle, enable); } +void btsnd_hcic_set_event_filter(uint8_t filt_type, uint8_t filt_cond_type, + uint8_t* filt_cond, uint8_t filt_cond_len) { + inc_func_call_count(__func__); + test::mock::stack_hcic_hcicmds::btsnd_hcic_set_event_filter( + filt_type, filt_cond_type, filt_cond, filt_cond_len); +} void btsnd_hcic_setup_esco_conn(uint16_t handle, uint32_t transmit_bandwidth, uint32_t receive_bandwidth, uint16_t max_latency, uint16_t voice, diff --git a/system/test/mock/mock_stack_hcic_hcicmds.h b/system/test/mock/mock_stack_hcic_hcicmds.h index 81bbfeba3dd..54a20f03f56 100644 --- a/system/test/mock/mock_stack_hcic_hcicmds.h +++ b/system/test/mock/mock_stack_hcic_hcicmds.h @@ -153,6 +153,15 @@ struct btsnd_hcic_delete_stored_key { }; extern struct btsnd_hcic_delete_stored_key btsnd_hcic_delete_stored_key; +// Name: btsnd_hcic_enable_test_mode +// Params: void +// Return: void +struct btsnd_hcic_enable_test_mode { + std::function body{[](void) {}}; + void operator()(void) { body(); }; +}; +extern struct btsnd_hcic_enable_test_mode btsnd_hcic_enable_test_mode; + // Name: btsnd_hcic_enhanced_accept_synchronous_connection // Params: const RawAddress& bd_addr, enh_esco_params_t* p_params // Return: void @@ -487,6 +496,21 @@ struct btsnd_hcic_set_conn_encrypt { }; extern struct btsnd_hcic_set_conn_encrypt btsnd_hcic_set_conn_encrypt; +// Name: btsnd_hcic_set_event_filter +// Params: uint8_t filt_type, uint8_t filt_cond_type, uint8_t* filt_cond, +// uint8_t filt_cond_len Return: void +struct btsnd_hcic_set_event_filter { + std::function + body{[](uint8_t filt_type, uint8_t filt_cond_type, uint8_t* filt_cond, + uint8_t filt_cond_len) {}}; + void operator()(uint8_t filt_type, uint8_t filt_cond_type, uint8_t* filt_cond, + uint8_t filt_cond_len) { + body(filt_type, filt_cond_type, filt_cond, filt_cond_len); + }; +}; +extern struct btsnd_hcic_set_event_filter btsnd_hcic_set_event_filter; + // Name: btsnd_hcic_setup_esco_conn // Params: uint16_t handle, uint32_t transmit_bandwidth, uint32_t // receive_bandwidth, uint16_t max_latency, uint16_t voice, uint8_t -- GitLab From 51e580bbbc500dc897e46b7d6e41f49b2911fcdb Mon Sep 17 00:00:00 2001 From: David Duarte Date: Mon, 15 May 2023 11:39:59 +0000 Subject: [PATCH 0050/2405] Revert "Remove unused le_test_mode from bluetooth interface" This reverts commit 78edce9b0f72a6db4eb41bebf37c42156643ac86. Reason for revert: b/269397845 Bug: 269397845 Test: mma Change-Id: I07b66a087d22d6952caa4d54f08cdff028674e9d --- ...oid_bluetooth_btservice_AdapterService.cpp | 6 ++ system/btif/include/btif_api.h | 6 ++ system/btif/include/btif_common.h | 1 + system/btif/include/core_callbacks.h | 1 + system/btif/src/bluetooth.cc | 34 +++++++++ system/btif/src/btif_dm.cc | 38 ++++++++++ system/btif/test/btif_core_test.cc | 2 + system/btif/test/btif_hh_test.cc | 1 + system/gd/rust/topshim/src/btif.rs | 2 + system/include/hardware/bluetooth.h | 11 +++ system/main/shim/btm_api.cc | 19 +++++ system/main/shim/btm_api.h | 40 ++++++++++ system/stack/btm/btm_ble.cc | 75 +++++++++++++++++++ system/stack/btm/btm_int_types.h | 4 + system/stack/btu/btu_hcif.cc | 6 ++ system/stack/hcic/hciblecmds.cc | 46 ++++++++++++ system/stack/include/btm_ble_api.h | 40 ++++++++++ system/stack/include/hcimsgs.h | 6 ++ system/test/common/core_interface.cc | 1 + system/test/headless/headless.cc | 6 ++ system/test/mock/mock_bluetooth_interface.cc | 3 + system/test/mock/mock_btif_bluetooth.cc | 5 ++ system/test/mock/mock_btif_bluetooth.h | 11 +++ system/test/mock/mock_btif_dm.cc | 6 ++ system/test/mock/mock_main_shim_btm_api.cc | 13 ++++ system/test/mock/mock_stack_btm_ble.cc | 18 +++++ system/test/mock/mock_stack_btm_ble.h | 37 +++++++++ .../test/mock/mock_stack_hcic_hciblecmds.cc | 17 +++++ system/test/mock/mock_stack_hcic_hciblecmds.h | 31 ++++++++ 29 files changed, 486 insertions(+) diff --git a/android/app/jni/com_android_bluetooth_btservice_AdapterService.cpp b/android/app/jni/com_android_bluetooth_btservice_AdapterService.cpp index 32ca755e908..c4b3e7eca7b 100644 --- a/android/app/jni/com_android_bluetooth_btservice_AdapterService.cpp +++ b/android/app/jni/com_android_bluetooth_btservice_AdapterService.cpp @@ -689,6 +689,11 @@ static void dut_mode_recv_callback(uint16_t opcode, uint8_t* buf, uint8_t len) { } +static void le_test_mode_recv_callback(bt_status_t status, + uint16_t packet_count) { + ALOGV("%s: status:%d packet_count:%d ", __func__, status, packet_count); +} + static void energy_info_recv_callback(bt_activity_energy_info* p_energy_info, bt_uid_traffic_t* uid_data) { CallbackEnv sCallbackEnv(__func__); @@ -733,6 +738,7 @@ static bt_callbacks_t sBluetoothCallbacks = {sizeof(sBluetoothCallbacks), acl_state_changed_callback, callback_thread_event, dut_mode_recv_callback, + le_test_mode_recv_callback, energy_info_recv_callback, link_quality_report_callback, generate_local_oob_data_callback, diff --git a/system/btif/include/btif_api.h b/system/btif/include/btif_api.h index 6a44658b41d..fbf61cdb18d 100644 --- a/system/btif/include/btif_api.h +++ b/system/btif/include/btif_api.h @@ -350,6 +350,12 @@ bool btif_is_dut_mode(); ******************************************************************************/ void btif_dut_mode_send(uint16_t opcode, uint8_t* buf, uint8_t len); +void btif_ble_transmitter_test(uint8_t tx_freq, uint8_t test_data_len, + uint8_t packet_payload); + +void btif_ble_receiver_test(uint8_t rx_freq); +void btif_ble_test_end(); + /******************************************************************************* * * Function btif_dm_read_energy_info diff --git a/system/btif/include/btif_common.h b/system/btif/include/btif_common.h index 32488b78b2f..4868e7e481d 100644 --- a/system/btif/include/btif_common.h +++ b/system/btif/include/btif_common.h @@ -228,6 +228,7 @@ void invoke_acl_state_changed_cb(bt_status_t status, RawAddress bd_addr, bt_conn_direction_t direction, uint16_t acl_handle); void invoke_thread_evt_cb(bt_cb_thread_evt event); +void invoke_le_test_mode_cb(bt_status_t status, uint16_t count); void invoke_energy_info_cb(bt_activity_energy_info energy_info, bt_uid_traffic_t* uid_data); void invoke_link_quality_report_cb( diff --git a/system/btif/include/core_callbacks.h b/system/btif/include/core_callbacks.h index 79b42188dde..a10198b78e1 100644 --- a/system/btif/include/core_callbacks.h +++ b/system/btif/include/core_callbacks.h @@ -58,6 +58,7 @@ struct EventCallbacks { bt_conn_direction_t direction, uint16_t acl_handle); void (*invoke_thread_evt_cb)(bt_cb_thread_evt event); + void (*invoke_le_test_mode_cb)(bt_status_t status, uint16_t count); void (*invoke_energy_info_cb)(bt_activity_energy_info energy_info, bt_uid_traffic_t* uid_data); void (*invoke_link_quality_report_cb)(uint64_t timestamp, int report_id, diff --git a/system/btif/src/bluetooth.cc b/system/btif/src/bluetooth.cc index 24c45b3b7fb..bc854e0f049 100644 --- a/system/btif/src/bluetooth.cc +++ b/system/btif/src/bluetooth.cc @@ -325,6 +325,7 @@ static bluetooth::core::CoreInterface* CreateInterfaceToProfiles() { .invoke_le_address_associate_cb = invoke_le_address_associate_cb, .invoke_acl_state_changed_cb = invoke_acl_state_changed_cb, .invoke_thread_evt_cb = invoke_thread_evt_cb, + .invoke_le_test_mode_cb = invoke_le_test_mode_cb, .invoke_energy_info_cb = invoke_energy_info_cb, .invoke_link_quality_report_cb = invoke_link_quality_report_cb}; static auto configInterface = ConfigInterfaceImpl(); @@ -943,6 +944,29 @@ int dut_mode_send(uint16_t opcode, uint8_t* buf, uint8_t len) { return BT_STATUS_SUCCESS; } +int le_test_mode(uint16_t opcode, uint8_t* buf, uint8_t len) { + if (!interface_ready()) return BT_STATUS_NOT_READY; + + switch (opcode) { + case HCI_BLE_TRANSMITTER_TEST: + if (len != 3) return BT_STATUS_PARM_INVALID; + do_in_main_thread(FROM_HERE, base::BindOnce(btif_ble_transmitter_test, + buf[0], buf[1], buf[2])); + break; + case HCI_BLE_RECEIVER_TEST: + if (len != 1) return BT_STATUS_PARM_INVALID; + do_in_main_thread(FROM_HERE, + base::BindOnce(btif_ble_receiver_test, buf[0])); + break; + case HCI_BLE_TEST_END: + do_in_main_thread(FROM_HERE, base::BindOnce(btif_ble_test_end)); + break; + default: + return BT_STATUS_UNSUPPORTED; + } + return BT_STATUS_SUCCESS; +} + static bt_os_callouts_t* wakelock_os_callouts_saved = nullptr; static int acquire_wake_lock_cb(const char* lock_name) { @@ -1136,6 +1160,7 @@ EXPORT_SYMBOL bt_interface_t bluetoothInterface = { .get_profile_interface = get_profile_interface, .dut_mode_configure = dut_mode_configure, .dut_mode_send = dut_mode_send, + .le_test_mode = le_test_mode, .set_os_callouts = set_os_callouts, .read_energy_info = read_energy_info, .dump = dump, @@ -1408,6 +1433,15 @@ void invoke_thread_evt_cb(bt_cb_thread_evt event) { event)); } +void invoke_le_test_mode_cb(bt_status_t status, uint16_t count) { + do_in_jni_thread(FROM_HERE, base::BindOnce( + [](bt_status_t status, uint16_t count) { + HAL_CBACK(bt_hal_cbacks, le_test_mode_cb, + status, count); + }, + status, count)); +} + // takes ownership of |uid_data| void invoke_energy_info_cb(bt_activity_energy_info energy_info, bt_uid_traffic_t* uid_data) { diff --git a/system/btif/src/btif_dm.cc b/system/btif/src/btif_dm.cc index c242232d1ac..a77e6c6cbd1 100644 --- a/system/btif/src/btif_dm.cc +++ b/system/btif/src/btif_dm.cc @@ -3691,6 +3691,44 @@ void btif_dm_update_ble_remote_properties(const RawAddress& bd_addr, btif_update_remote_properties(bd_addr, bd_name, dev_class, dev_type); } +static void btif_dm_ble_tx_test_cback(void* p) { + char* p_param = (char*)p; + uint8_t status; + STREAM_TO_UINT8(status, p_param); + GetInterfaceToProfiles()->events->invoke_le_test_mode_cb( + (status == 0) ? BT_STATUS_SUCCESS : BT_STATUS_FAIL, 0); +} + +static void btif_dm_ble_rx_test_cback(void* p) { + char* p_param = (char*)p; + uint8_t status; + STREAM_TO_UINT8(status, p_param); + GetInterfaceToProfiles()->events->invoke_le_test_mode_cb( + (status == 0) ? BT_STATUS_SUCCESS : BT_STATUS_FAIL, 0); +} + +static void btif_dm_ble_test_end_cback(void* p) { + char* p_param = (char*)p; + uint8_t status; + uint16_t count = 0; + STREAM_TO_UINT8(status, p_param); + if (status == 0) STREAM_TO_UINT16(count, p_param); + GetInterfaceToProfiles()->events->invoke_le_test_mode_cb( + (status == 0) ? BT_STATUS_SUCCESS : BT_STATUS_FAIL, count); +} + +void btif_ble_transmitter_test(uint8_t tx_freq, uint8_t test_data_len, + uint8_t packet_payload) { + BTM_BleTransmitterTest(tx_freq, test_data_len, packet_payload, + btif_dm_ble_tx_test_cback); +} + +void btif_ble_receiver_test(uint8_t rx_freq) { + BTM_BleReceiverTest(rx_freq, btif_dm_ble_rx_test_cback); +} + +void btif_ble_test_end() { BTM_BleTestEnd(btif_dm_ble_test_end_cback); } + void btif_dm_on_disable() { /* cancel any pending pairing requests */ if (is_bonding_or_sdp()) { diff --git a/system/btif/test/btif_core_test.cc b/system/btif/test/btif_core_test.cc index ab37b95cd36..04f02992cdd 100644 --- a/system/btif/test/btif_core_test.cc +++ b/system/btif/test/btif_core_test.cc @@ -86,6 +86,7 @@ void link_quality_report_callback(uint64_t timestamp, int report_id, int rssi, int negative_acknowledgement_count) {} void callback_thread_event(bt_cb_thread_evt evt) { TESTCB; } void dut_mode_recv_callback(uint16_t opcode, uint8_t* buf, uint8_t len) {} +void le_test_mode_callback(bt_status_t status, uint16_t num_packets) {} void energy_info_callback(bt_activity_energy_info* energy_info, bt_uid_traffic_t* uid_data) {} void generate_local_oob_data_callback(tBT_TRANSPORT transport, @@ -109,6 +110,7 @@ bt_callbacks_t callbacks = { .acl_state_changed_cb = acl_state_changed_callback, .thread_evt_cb = callback_thread_event, .dut_mode_recv_cb = dut_mode_recv_callback, + .le_test_mode_cb = le_test_mode_callback, .energy_info_cb = energy_info_callback, .link_quality_report_cb = link_quality_report_callback, .generate_local_oob_data_cb = generate_local_oob_data_callback, diff --git a/system/btif/test/btif_hh_test.cc b/system/btif/test/btif_hh_test.cc index de215c2689e..6b367f2cd9b 100644 --- a/system/btif/test/btif_hh_test.cc +++ b/system/btif/test/btif_hh_test.cc @@ -134,6 +134,7 @@ bt_callbacks_t bt_callbacks = { .acl_state_changed_cb = nullptr, // acl_state_changed_callback .thread_evt_cb = nullptr, // callback_thread_event .dut_mode_recv_cb = nullptr, // dut_mode_recv_callback + .le_test_mode_cb = nullptr, // le_test_mode_callback .energy_info_cb = nullptr, // energy_info_callback .link_quality_report_cb = nullptr, // link_quality_report_callback .generate_local_oob_data_cb = nullptr, // generate_local_oob_data_callback diff --git a/system/gd/rust/topshim/src/btif.rs b/system/gd/rust/topshim/src/btif.rs index 0973d8ad718..30edb0f221a 100644 --- a/system/gd/rust/topshim/src/btif.rs +++ b/system/gd/rust/topshim/src/btif.rs @@ -885,6 +885,7 @@ pub enum BaseCallbacks { // Unimplemented so far: // thread_evt_cb // dut_mode_recv_cb + // le_test_mode_cb // energy_info_cb // link_quality_report_cb // switch_buffer_size_cb @@ -1072,6 +1073,7 @@ impl BluetoothInterface { acl_state_changed_cb: Some(acl_state_cb), thread_evt_cb: None, dut_mode_recv_cb: None, + le_test_mode_cb: None, energy_info_cb: None, link_quality_report_cb: None, generate_local_oob_data_cb: Some(generate_local_oob_data_cb), diff --git a/system/include/hardware/bluetooth.h b/system/include/hardware/bluetooth.h index 031ce226de8..00396f9b110 100644 --- a/system/include/hardware/bluetooth.h +++ b/system/include/hardware/bluetooth.h @@ -550,6 +550,12 @@ typedef void (*callback_thread_event)(bt_cb_thread_evt evt); typedef void (*dut_mode_recv_callback)(uint16_t opcode, uint8_t* buf, uint8_t len); +/* LE Test mode callbacks + * This callback shall be invoked whenever the le_tx_test, le_rx_test or + * le_test_end is invoked The num_packets is valid only for le_test_end command + */ +typedef void (*le_test_mode_callback)(bt_status_t status, uint16_t num_packets); + /** Callback invoked when energy details are obtained */ /* Ctrl_state-Current controller state-Active-1,scan-2,or idle-3 state as * defined by HCI spec. If the ctrl_state value is 0, it means the API call @@ -585,6 +591,7 @@ typedef struct { acl_state_changed_callback acl_state_changed_cb; callback_thread_event thread_evt_cb; dut_mode_recv_callback dut_mode_recv_cb; + le_test_mode_callback le_test_mode_cb; energy_info_callback energy_info_cb; link_quality_report_callback link_quality_report_cb; generate_local_oob_data_callback generate_local_oob_data_cb; @@ -744,6 +751,10 @@ typedef struct { /* Send any test HCI (vendor-specific) command to the controller. Must be in * DUT Mode */ int (*dut_mode_send)(uint16_t opcode, uint8_t* buf, uint8_t len); + /** BLE Test Mode APIs */ + /* opcode MUST be one of: LE_Receiver_Test, LE_Transmitter_Test, LE_Test_End + */ + int (*le_test_mode)(uint16_t opcode, uint8_t* buf, uint8_t len); /** Sets the OS call-out functions that bluedroid needs for alarms and wake * locks. This should be called immediately after a successful |init|. diff --git a/system/main/shim/btm_api.cc b/system/main/shim/btm_api.cc index b377a0370e9..aef03edd788 100644 --- a/system/main/shim/btm_api.cc +++ b/system/main/shim/btm_api.cc @@ -600,6 +600,25 @@ bool bluetooth::shim::BTM_ReadConnectedTransportAddress( return false; } +void bluetooth::shim::BTM_BleReceiverTest(uint8_t rx_freq, + tBTM_CMPL_CB* p_cmd_cmpl_cback) { + LOG_INFO("UNIMPLEMENTED %s", __func__); + CHECK(p_cmd_cmpl_cback != nullptr); +} + +void bluetooth::shim::BTM_BleTransmitterTest(uint8_t tx_freq, + uint8_t test_data_len, + uint8_t packet_payload, + tBTM_CMPL_CB* p_cmd_cmpl_cback) { + LOG_INFO("UNIMPLEMENTED %s", __func__); + CHECK(p_cmd_cmpl_cback != nullptr); +} + +void bluetooth::shim::BTM_BleTestEnd(tBTM_CMPL_CB* p_cmd_cmpl_cback) { + LOG_INFO("UNIMPLEMENTED %s", __func__); + CHECK(p_cmd_cmpl_cback != nullptr); +} + bool bluetooth::shim::BTM_GetLeSecurityState(const RawAddress& bd_addr, uint8_t* p_le_dev_sec_flags, uint8_t* p_le_key_size) { diff --git a/system/main/shim/btm_api.h b/system/main/shim/btm_api.h index e14eb4a210d..aa2996c4a45 100644 --- a/system/main/shim/btm_api.h +++ b/system/main/shim/btm_api.h @@ -551,6 +551,46 @@ void BTM_ReadDevInfo(const RawAddress& remote_bda, tBT_DEVICE_TYPE* p_dev_type, bool BTM_ReadConnectedTransportAddress(RawAddress* remote_bda, tBT_TRANSPORT transport); +/******************************************************************************* + * + * Function BTM_BleReceiverTest + * + * Description This function is called to start the LE Receiver test + * + * Parameter rx_freq - Frequency Range + * p_cmd_cmpl_cback - Command Complete callback + * + ******************************************************************************/ +void BTM_BleReceiverTest(uint8_t rx_freq, tBTM_CMPL_CB* p_cmd_cmpl_cback); + +/******************************************************************************* + * + * Function BTM_BleTransmitterTest + * + * Description This function is called to start the LE Transmitter test + * + * Parameter tx_freq - Frequency Range + * test_data_len - Length in bytes of payload data in each + * packet + * packet_payload - Pattern to use in the payload + * p_cmd_cmpl_cback - Command Complete callback + * + ******************************************************************************/ +void BTM_BleTransmitterTest(uint8_t tx_freq, uint8_t test_data_len, + uint8_t packet_payload, + tBTM_CMPL_CB* p_cmd_cmpl_cback); + +/******************************************************************************* + * + * Function BTM_BleTestEnd + * + * Description This function is called to stop the in-progress TX or RX test + * + * Parameter p_cmd_cmpl_cback - Command complete callback + * + ******************************************************************************/ +void BTM_BleTestEnd(tBTM_CMPL_CB* p_cmd_cmpl_cback); + /******************************************************************************* * * Function BTM_UseLeLink diff --git a/system/stack/btm/btm_ble.cc b/system/stack/btm/btm_ble.cc index 4d38297df76..7931befaef5 100644 --- a/system/stack/btm/btm_ble.cc +++ b/system/stack/btm/btm_ble.cc @@ -562,6 +562,81 @@ bool BTM_ReadConnectedTransportAddress(RawAddress* remote_bda, return false; } +/******************************************************************************* + * + * Function BTM_BleReceiverTest + * + * Description This function is called to start the LE Receiver test + * + * Parameter rx_freq - Frequency Range + * p_cmd_cmpl_cback - Command Complete callback + * + ******************************************************************************/ +void BTM_BleReceiverTest(uint8_t rx_freq, tBTM_CMPL_CB* p_cmd_cmpl_cback) { + if (bluetooth::shim::is_gd_shim_enabled()) { + return bluetooth::shim::BTM_BleReceiverTest(rx_freq, p_cmd_cmpl_cback); + } + btm_cb.devcb.p_le_test_cmd_cmpl_cb = p_cmd_cmpl_cback; + + btsnd_hcic_ble_receiver_test(rx_freq); +} + +/******************************************************************************* + * + * Function BTM_BleTransmitterTest + * + * Description This function is called to start the LE Transmitter test + * + * Parameter tx_freq - Frequency Range + * test_data_len - Length in bytes of payload data in each + * packet + * packet_payload - Pattern to use in the payload + * p_cmd_cmpl_cback - Command Complete callback + * + ******************************************************************************/ +void BTM_BleTransmitterTest(uint8_t tx_freq, uint8_t test_data_len, + uint8_t packet_payload, + tBTM_CMPL_CB* p_cmd_cmpl_cback) { + if (bluetooth::shim::is_gd_shim_enabled()) { + return bluetooth::shim::BTM_BleTransmitterTest( + tx_freq, test_data_len, packet_payload, p_cmd_cmpl_cback); + } + btm_cb.devcb.p_le_test_cmd_cmpl_cb = p_cmd_cmpl_cback; + btsnd_hcic_ble_transmitter_test(tx_freq, test_data_len, packet_payload); +} + +/******************************************************************************* + * + * Function BTM_BleTestEnd + * + * Description This function is called to stop the in-progress TX or RX + * test + * + * Parameter p_cmd_cmpl_cback - Command complete callback + * + ******************************************************************************/ +void BTM_BleTestEnd(tBTM_CMPL_CB* p_cmd_cmpl_cback) { + if (bluetooth::shim::is_gd_shim_enabled()) { + return bluetooth::shim::BTM_BleTestEnd(p_cmd_cmpl_cback); + } + btm_cb.devcb.p_le_test_cmd_cmpl_cb = p_cmd_cmpl_cback; + + btsnd_hcic_ble_test_end(); +} + +/******************************************************************************* + * Internal Functions + ******************************************************************************/ +void btm_ble_test_command_complete(uint8_t* p) { + tBTM_CMPL_CB* p_cb = btm_cb.devcb.p_le_test_cmd_cmpl_cb; + + btm_cb.devcb.p_le_test_cmd_cmpl_cb = NULL; + + if (p_cb) { + (*p_cb)(p); + } +} + /******************************************************************************* * * Function BTM_UseLeLink diff --git a/system/stack/btm/btm_int_types.h b/system/stack/btm/btm_int_types.h index b5785e70212..b61f08823d5 100644 --- a/system/stack/btm/btm_int_types.h +++ b/system/stack/btm/btm_int_types.h @@ -165,6 +165,10 @@ typedef struct tBTM_DEVCB { DEV_CLASS dev_class; /* Local device class */ + tBTM_CMPL_CB* + p_le_test_cmd_cmpl_cb; /* Callback function to be called when + LE test mode command has been sent successfully */ + RawAddress read_tx_pwr_addr; /* read TX power target address */ tBTM_BLE_LOCAL_ID_KEYS id_keys; /* local BLE ID keys */ diff --git a/system/stack/btu/btu_hcif.cc b/system/stack/btu/btu_hcif.cc index 790b7e53ce2..91cb62edc94 100644 --- a/system/stack/btu/btu_hcif.cc +++ b/system/stack/btu/btu_hcif.cc @@ -1139,6 +1139,12 @@ static void btu_hcif_hdl_command_complete(uint16_t opcode, uint8_t* p, LOG(ERROR) << "No command complete expected, but received!"; break; + case HCI_BLE_TRANSMITTER_TEST: + case HCI_BLE_RECEIVER_TEST: + case HCI_BLE_TEST_END: + btm_ble_test_command_complete(p); + break; + case HCI_BLE_ADD_DEV_RESOLVING_LIST: btm_ble_add_resolving_list_entry_complete(p, evt_len); break; diff --git a/system/stack/hcic/hciblecmds.cc b/system/stack/hcic/hciblecmds.cc index 7a363a81604..0a2ad2e7146 100644 --- a/system/stack/hcic/hciblecmds.cc +++ b/system/stack/hcic/hciblecmds.cc @@ -460,6 +460,52 @@ void btsnd_hcic_ble_ltk_req_neg_reply(uint16_t handle) { btu_hcif_send_cmd(LOCAL_BR_EDR_CONTROLLER_ID, p); } +void btsnd_hcic_ble_receiver_test(uint8_t rx_freq) { + BT_HDR* p = (BT_HDR*)osi_malloc(HCI_CMD_BUF_SIZE); + uint8_t* pp = (uint8_t*)(p + 1); + + p->len = HCIC_PREAMBLE_SIZE + HCIC_PARAM_SIZE_WRITE_PARAM1; + p->offset = 0; + + UINT16_TO_STREAM(pp, HCI_BLE_RECEIVER_TEST); + UINT8_TO_STREAM(pp, HCIC_PARAM_SIZE_WRITE_PARAM1); + + UINT8_TO_STREAM(pp, rx_freq); + + btu_hcif_send_cmd(LOCAL_BR_EDR_CONTROLLER_ID, p); +} + +void btsnd_hcic_ble_transmitter_test(uint8_t tx_freq, uint8_t test_data_len, + uint8_t payload) { + BT_HDR* p = (BT_HDR*)osi_malloc(HCI_CMD_BUF_SIZE); + uint8_t* pp = (uint8_t*)(p + 1); + + p->len = HCIC_PREAMBLE_SIZE + HCIC_PARAM_SIZE_WRITE_PARAM3; + p->offset = 0; + + UINT16_TO_STREAM(pp, HCI_BLE_TRANSMITTER_TEST); + UINT8_TO_STREAM(pp, HCIC_PARAM_SIZE_WRITE_PARAM3); + + UINT8_TO_STREAM(pp, tx_freq); + UINT8_TO_STREAM(pp, test_data_len); + UINT8_TO_STREAM(pp, payload); + + btu_hcif_send_cmd(LOCAL_BR_EDR_CONTROLLER_ID, p); +} + +void btsnd_hcic_ble_test_end(void) { + BT_HDR* p = (BT_HDR*)osi_malloc(HCI_CMD_BUF_SIZE); + uint8_t* pp = (uint8_t*)(p + 1); + + p->len = HCIC_PREAMBLE_SIZE + HCIC_PARAM_SIZE_READ_CMD; + p->offset = 0; + + UINT16_TO_STREAM(pp, HCI_BLE_TEST_END); + UINT8_TO_STREAM(pp, HCIC_PARAM_SIZE_READ_CMD); + + btu_hcif_send_cmd(LOCAL_BR_EDR_CONTROLLER_ID, p); +} + void btsnd_hcic_ble_read_host_supported(void) { BT_HDR* p = (BT_HDR*)osi_malloc(HCI_CMD_BUF_SIZE); uint8_t* pp = (uint8_t*)(p + 1); diff --git a/system/stack/include/btm_ble_api.h b/system/stack/include/btm_ble_api.h index dadfdaf6417..6136142ede1 100644 --- a/system/stack/include/btm_ble_api.h +++ b/system/stack/include/btm_ble_api.h @@ -521,6 +521,46 @@ bool BTM_BleLocalPrivacyEnabled(void); ******************************************************************************/ uint8_t BTM_BleMaxMultiAdvInstanceCount(); +/******************************************************************************* + * + * Function BTM_BleReceiverTest + * + * Description This function is called to start the LE Receiver test + * + * Parameter rx_freq - Frequency Range + * p_cmd_cmpl_cback - Command Complete callback + * + ******************************************************************************/ +void BTM_BleReceiverTest(uint8_t rx_freq, tBTM_CMPL_CB* p_cmd_cmpl_cback); + +/******************************************************************************* + * + * Function BTM_BleTransmitterTest + * + * Description This function is called to start the LE Transmitter test + * + * Parameter tx_freq - Frequency Range + * test_data_len - Length in bytes of payload data in each + * packet + * packet_payload - Pattern to use in the payload + * p_cmd_cmpl_cback - Command Complete callback + * + ******************************************************************************/ +void BTM_BleTransmitterTest(uint8_t tx_freq, uint8_t test_data_len, + uint8_t packet_payload, + tBTM_CMPL_CB* p_cmd_cmpl_cback); + +/******************************************************************************* + * + * Function BTM_BleTestEnd + * + * Description This function is called to stop the in-progress TX or RX test + * + * Parameter p_cmd_cmpl_cback - Command complete callback + * + ******************************************************************************/ +void BTM_BleTestEnd(tBTM_CMPL_CB* p_cmd_cmpl_cback); + /******************************************************************************* * * Function BTM_UseLeLink diff --git a/system/stack/include/hcimsgs.h b/system/stack/include/hcimsgs.h index 675c64e6978..a41ae437d99 100644 --- a/system/stack/include/hcimsgs.h +++ b/system/stack/include/hcimsgs.h @@ -372,6 +372,12 @@ void btsnd_hcic_ble_write_host_supported(uint8_t le_host_spt, void btsnd_hcic_ble_read_host_supported(void); +void btsnd_hcic_ble_receiver_test(uint8_t rx_freq); + +void btsnd_hcic_ble_transmitter_test(uint8_t tx_freq, uint8_t test_data_len, + uint8_t payload); +void btsnd_hcic_ble_test_end(void); + void btsnd_hcic_ble_rc_param_req_reply(uint16_t handle, uint16_t conn_int_min, uint16_t conn_int_max, uint16_t conn_latency, diff --git a/system/test/common/core_interface.cc b/system/test/common/core_interface.cc index f0b8235ec8b..e20df2cbd49 100644 --- a/system/test/common/core_interface.cc +++ b/system/test/common/core_interface.cc @@ -36,6 +36,7 @@ static bluetooth::core::EventCallbacks eventCallbacks = { .invoke_le_address_associate_cb = invoke_le_address_associate_cb, .invoke_acl_state_changed_cb = invoke_acl_state_changed_cb, .invoke_thread_evt_cb = invoke_thread_evt_cb, + .invoke_le_test_mode_cb = invoke_le_test_mode_cb, .invoke_energy_info_cb = invoke_energy_info_cb, .invoke_link_quality_report_cb = invoke_link_quality_report_cb}; diff --git a/system/test/headless/headless.cc b/system/test/headless/headless.cc index 551a6d666a0..9006afd139e 100644 --- a/system/test/headless/headless.cc +++ b/system/test/headless/headless.cc @@ -205,6 +205,11 @@ void dut_mode_recv([[maybe_unused]] uint16_t opcode, LOG_INFO("%s", __func__); } +void le_test_mode([[maybe_unused]] bt_status_t status, + [[maybe_unused]] uint16_t num_packets) { + LOG_INFO("%s", __func__); +} + void energy_info([[maybe_unused]] bt_activity_energy_info* energy_info, [[maybe_unused]] bt_uid_traffic_t* uid_data) { LOG_INFO("%s", __func__); @@ -226,6 +231,7 @@ bt_callbacks_t bt_callbacks{ .acl_state_changed_cb = acl_state_changed, .thread_evt_cb = thread_event, .dut_mode_recv_cb = dut_mode_recv, + .le_test_mode_cb = le_test_mode, .energy_info_cb = energy_info, .link_quality_report_cb = link_quality_report, .switch_buffer_size_cb = switch_buffer_size, diff --git a/system/test/mock/mock_bluetooth_interface.cc b/system/test/mock/mock_bluetooth_interface.cc index cd0f805fd5a..412214c056e 100644 --- a/system/test/mock/mock_bluetooth_interface.cc +++ b/system/test/mock/mock_bluetooth_interface.cc @@ -50,6 +50,9 @@ void invoke_acl_state_changed_cb(bt_status_t status, RawAddress bd_addr, bt_conn_direction_t direction, uint16_t acl_handle) {} void invoke_thread_evt_cb(bt_cb_thread_evt event) {} + +void invoke_le_test_mode_cb(bt_status_t status, uint16_t count) {} + void invoke_energy_info_cb(bt_activity_energy_info energy_info, bt_uid_traffic_t* uid_data) {} void invoke_link_quality_report_cb(uint64_t timestamp, int report_id, int rssi, diff --git a/system/test/mock/mock_btif_bluetooth.cc b/system/test/mock/mock_btif_bluetooth.cc index a5994721ea9..0a9de746b73 100644 --- a/system/test/mock/mock_btif_bluetooth.cc +++ b/system/test/mock/mock_btif_bluetooth.cc @@ -52,6 +52,7 @@ struct get_common_criteria_config_compare_result struct get_remote_device_properties get_remote_device_properties; struct get_remote_device_property get_remote_device_property; struct get_remote_services get_remote_services; +struct le_test_mode le_test_mode; struct set_remote_device_property set_remote_device_property; struct set_hal_cbacks set_hal_cbacks; @@ -99,6 +100,10 @@ int get_remote_services(RawAddress* remote_addr) { inc_func_call_count(__func__); return test::mock::btif_bluetooth::get_remote_services(remote_addr); } +int le_test_mode(uint16_t opcode, uint8_t* buf, uint8_t len) { + inc_func_call_count(__func__); + return test::mock::btif_bluetooth::le_test_mode(opcode, buf, len); +} int set_remote_device_property(RawAddress* remote_addr, const bt_property_t* property) { inc_func_call_count(__func__); diff --git a/system/test/mock/mock_btif_bluetooth.h b/system/test/mock/mock_btif_bluetooth.h index c007631f733..6535fb20c34 100644 --- a/system/test/mock/mock_btif_bluetooth.h +++ b/system/test/mock/mock_btif_bluetooth.h @@ -128,6 +128,17 @@ struct get_remote_services { int operator()(RawAddress* remote_addr) { return body(remote_addr); }; }; extern struct get_remote_services get_remote_services; +// Name: le_test_mode +// Params: uint16_t opcode, uint8_t* buf, uint8_t len +// Returns: int +struct le_test_mode { + std::function body{ + [](uint16_t opcode, uint8_t* buf, uint8_t len) { return 0; }}; + int operator()(uint16_t opcode, uint8_t* buf, uint8_t len) { + return body(opcode, buf, len); + }; +}; +extern struct le_test_mode le_test_mode; // Name: set_remote_device_property // Params: RawAddress* remote_addr, const bt_property_t* property // Returns: int diff --git a/system/test/mock/mock_btif_dm.cc b/system/test/mock/mock_btif_dm.cc index 0559729e2ef..556cbe4bfa7 100644 --- a/system/test/mock/mock_btif_dm.cc +++ b/system/test/mock/mock_btif_dm.cc @@ -69,6 +69,12 @@ void BTIF_dm_report_inquiry_status_change(uint8_t status) { void bte_dm_evt(tBTA_DM_SEC_EVT event, tBTA_DM_SEC* p_data) { inc_func_call_count(__func__); } +void btif_ble_receiver_test(uint8_t rx_freq) { inc_func_call_count(__func__); } +void btif_ble_test_end() { inc_func_call_count(__func__); } +void btif_ble_transmitter_test(uint8_t tx_freq, uint8_t test_data_len, + uint8_t packet_payload) { + inc_func_call_count(__func__); +} void btif_debug_bond_event_dump(int fd) { inc_func_call_count(__func__); } void btif_dm_ble_sec_req_evt(tBTA_DM_BLE_SEC_REQ* p_ble_req, bool is_consent) { inc_func_call_count(__func__); diff --git a/system/test/mock/mock_main_shim_btm_api.cc b/system/test/mock/mock_main_shim_btm_api.cc index 2cf7689927f..884278b0d58 100644 --- a/system/test/mock/mock_main_shim_btm_api.cc +++ b/system/test/mock/mock_main_shim_btm_api.cc @@ -271,6 +271,10 @@ void bluetooth::shim::BTM_BleReadPhy( base::Callback cb) { inc_func_call_count(__func__); } +void bluetooth::shim::BTM_BleReceiverTest(uint8_t rx_freq, + tBTM_CMPL_CB* p_cmd_cmpl_cback) { + inc_func_call_count(__func__); +} void bluetooth::shim::BTM_BleSecureConnectionOobDataReply( const RawAddress& bd_addr, uint8_t* p_c, uint8_t* p_r) { inc_func_call_count(__func__); @@ -290,6 +294,15 @@ void bluetooth::shim::BTM_BleSetPrefConnParams(const RawAddress& bd_addr, uint16_t supervision_tout) { inc_func_call_count(__func__); } +void bluetooth::shim::BTM_BleTestEnd(tBTM_CMPL_CB* p_cmd_cmpl_cback) { + inc_func_call_count(__func__); +} +void bluetooth::shim::BTM_BleTransmitterTest(uint8_t tx_freq, + uint8_t test_data_len, + uint8_t packet_payload, + tBTM_CMPL_CB* p_cmd_cmpl_cback) { + inc_func_call_count(__func__); +} void bluetooth::shim::BTM_BleUpdateAdvFilterPolicy(tBTM_BLE_AFP adv_policy) { inc_func_call_count(__func__); } diff --git a/system/test/mock/mock_stack_btm_ble.cc b/system/test/mock/mock_stack_btm_ble.cc index b52c05be64f..f9b115e03b1 100644 --- a/system/test/mock/mock_stack_btm_ble.cc +++ b/system/test/mock/mock_stack_btm_ble.cc @@ -43,9 +43,12 @@ struct BTM_BleLoadLocalKeys BTM_BleLoadLocalKeys; struct BTM_BleOobDataReply BTM_BleOobDataReply; struct BTM_BlePasskeyReply BTM_BlePasskeyReply; struct BTM_BleReadPhy BTM_BleReadPhy; +struct BTM_BleReceiverTest BTM_BleReceiverTest; struct BTM_BleSecureConnectionOobDataReply BTM_BleSecureConnectionOobDataReply; struct BTM_BleSetPhy BTM_BleSetPhy; struct BTM_BleSetPrefConnParams BTM_BleSetPrefConnParams; +struct BTM_BleTestEnd BTM_BleTestEnd; +struct BTM_BleTransmitterTest BTM_BleTransmitterTest; struct BTM_BleVerifySignature BTM_BleVerifySignature; struct BTM_GetDeviceDHK BTM_GetDeviceDHK; struct BTM_GetDeviceEncRoot BTM_GetDeviceEncRoot; @@ -160,6 +163,10 @@ void BTM_BleReadPhy( inc_func_call_count(__func__); test::mock::stack_btm_ble::BTM_BleReadPhy(bd_addr, cb); } +void BTM_BleReceiverTest(uint8_t rx_freq, tBTM_CMPL_CB* p_cmd_cmpl_cback) { + inc_func_call_count(__func__); + test::mock::stack_btm_ble::BTM_BleReceiverTest(rx_freq, p_cmd_cmpl_cback); +} void BTM_BleSecureConnectionOobDataReply(const RawAddress& bd_addr, uint8_t* p_c, uint8_t* p_r) { inc_func_call_count(__func__); @@ -181,6 +188,17 @@ void BTM_BleSetPrefConnParams(const RawAddress& bd_addr, uint16_t min_conn_int, bd_addr, min_conn_int, max_conn_int, peripheral_latency, supervision_tout); } +void BTM_BleTestEnd(tBTM_CMPL_CB* p_cmd_cmpl_cback) { + inc_func_call_count(__func__); + test::mock::stack_btm_ble::BTM_BleTestEnd(p_cmd_cmpl_cback); +} +void BTM_BleTransmitterTest(uint8_t tx_freq, uint8_t test_data_len, + uint8_t packet_payload, + tBTM_CMPL_CB* p_cmd_cmpl_cback) { + inc_func_call_count(__func__); + test::mock::stack_btm_ble::BTM_BleTransmitterTest( + tx_freq, test_data_len, packet_payload, p_cmd_cmpl_cback); +} bool BTM_BleVerifySignature(const RawAddress& bd_addr, uint8_t* p_orig, uint16_t len, uint32_t counter, uint8_t* p_comp) { inc_func_call_count(__func__); diff --git a/system/test/mock/mock_stack_btm_ble.h b/system/test/mock/mock_stack_btm_ble.h index 6db86536091..1699a9c9b14 100644 --- a/system/test/mock/mock_stack_btm_ble.h +++ b/system/test/mock/mock_stack_btm_ble.h @@ -156,6 +156,18 @@ struct BTM_BleReadPhy { }; extern struct BTM_BleReadPhy BTM_BleReadPhy; +// Name: BTM_BleReceiverTest +// Params: uint8_t rx_freq, tBTM_CMPL_CB* p_cmd_cmpl_cback +// Return: void +struct BTM_BleReceiverTest { + std::function body{ + [](uint8_t rx_freq, tBTM_CMPL_CB* p_cmd_cmpl_cback) {}}; + void operator()(uint8_t rx_freq, tBTM_CMPL_CB* p_cmd_cmpl_cback) { + body(rx_freq, p_cmd_cmpl_cback); + }; +}; +extern struct BTM_BleReceiverTest BTM_BleReceiverTest; + // Name: BTM_BleSecureConnectionOobDataReply // Params: const RawAddress& bd_addr, uint8_t* p_c, uint8_t* p_r // Return: void @@ -204,6 +216,31 @@ struct BTM_BleSetPrefConnParams { }; extern struct BTM_BleSetPrefConnParams BTM_BleSetPrefConnParams; +// Name: BTM_BleTestEnd +// Params: tBTM_CMPL_CB* p_cmd_cmpl_cback +// Return: void +struct BTM_BleTestEnd { + std::function body{ + [](tBTM_CMPL_CB* p_cmd_cmpl_cback) {}}; + void operator()(tBTM_CMPL_CB* p_cmd_cmpl_cback) { body(p_cmd_cmpl_cback); }; +}; +extern struct BTM_BleTestEnd BTM_BleTestEnd; + +// Name: BTM_BleTransmitterTest +// Params: uint8_t tx_freq, uint8_t test_data_len, uint8_t packet_payload, +// tBTM_CMPL_CB* p_cmd_cmpl_cback Return: void +struct BTM_BleTransmitterTest { + std::function + body{[](uint8_t tx_freq, uint8_t test_data_len, uint8_t packet_payload, + tBTM_CMPL_CB* p_cmd_cmpl_cback) {}}; + void operator()(uint8_t tx_freq, uint8_t test_data_len, + uint8_t packet_payload, tBTM_CMPL_CB* p_cmd_cmpl_cback) { + body(tx_freq, test_data_len, packet_payload, p_cmd_cmpl_cback); + }; +}; +extern struct BTM_BleTransmitterTest BTM_BleTransmitterTest; + // Name: BTM_BleVerifySignature // Params: const RawAddress& bd_addr, uint8_t* p_orig, uint16_t len, uint32_t // counter, uint8_t* p_comp Return: bool diff --git a/system/test/mock/mock_stack_hcic_hciblecmds.cc b/system/test/mock/mock_stack_hcic_hciblecmds.cc index 37add1216df..605f28757fc 100644 --- a/system/test/mock/mock_stack_hcic_hciblecmds.cc +++ b/system/test/mock/mock_stack_hcic_hciblecmds.cc @@ -75,6 +75,7 @@ struct btsnd_hcic_ble_read_resolvable_addr_local btsnd_hcic_ble_read_resolvable_addr_local; struct btsnd_hcic_ble_read_resolvable_addr_peer btsnd_hcic_ble_read_resolvable_addr_peer; +struct btsnd_hcic_ble_receiver_test btsnd_hcic_ble_receiver_test; struct btsnd_hcic_ble_set_addr_resolution_enable btsnd_hcic_ble_set_addr_resolution_enable; struct btsnd_hcic_ble_set_adv_data btsnd_hcic_ble_set_adv_data; @@ -100,6 +101,8 @@ struct btsnd_hcic_ble_set_scan_enable btsnd_hcic_ble_set_scan_enable; struct btsnd_hcic_ble_set_scan_params btsnd_hcic_ble_set_scan_params; struct btsnd_hcic_ble_set_scan_rsp_data btsnd_hcic_ble_set_scan_rsp_data; struct btsnd_hcic_ble_start_enc btsnd_hcic_ble_start_enc; +struct btsnd_hcic_ble_test_end btsnd_hcic_ble_test_end; +struct btsnd_hcic_ble_transmitter_test btsnd_hcic_ble_transmitter_test; struct btsnd_hcic_ble_upd_ll_conn_params btsnd_hcic_ble_upd_ll_conn_params; struct btsnd_hcic_ble_write_adv_params btsnd_hcic_ble_write_adv_params; struct btsnd_hcic_create_big btsnd_hcic_create_big; @@ -300,6 +303,10 @@ void btsnd_hcic_ble_read_resolvable_addr_peer(uint8_t addr_type_peer, test::mock::stack_hcic_hciblecmds::btsnd_hcic_ble_read_resolvable_addr_peer( addr_type_peer, bda_peer); } +void btsnd_hcic_ble_receiver_test(uint8_t rx_freq) { + inc_func_call_count(__func__); + test::mock::stack_hcic_hciblecmds::btsnd_hcic_ble_receiver_test(rx_freq); +} void btsnd_hcic_ble_set_addr_resolution_enable(uint8_t addr_resolution_enable) { inc_func_call_count(__func__); test::mock::stack_hcic_hciblecmds::btsnd_hcic_ble_set_addr_resolution_enable( @@ -411,6 +418,16 @@ void btsnd_hcic_ble_start_enc(uint16_t handle, test::mock::stack_hcic_hciblecmds::btsnd_hcic_ble_start_enc(handle, rand, ediv, ltk); } +void btsnd_hcic_ble_test_end(void) { + inc_func_call_count(__func__); + test::mock::stack_hcic_hciblecmds::btsnd_hcic_ble_test_end(); +} +void btsnd_hcic_ble_transmitter_test(uint8_t tx_freq, uint8_t test_data_len, + uint8_t payload) { + inc_func_call_count(__func__); + test::mock::stack_hcic_hciblecmds::btsnd_hcic_ble_transmitter_test( + tx_freq, test_data_len, payload); +} void btsnd_hcic_ble_upd_ll_conn_params(uint16_t handle, uint16_t conn_int_min, uint16_t conn_int_max, uint16_t conn_latency, diff --git a/system/test/mock/mock_stack_hcic_hciblecmds.h b/system/test/mock/mock_stack_hcic_hciblecmds.h index 0f374b37452..9e32f076f19 100644 --- a/system/test/mock/mock_stack_hcic_hciblecmds.h +++ b/system/test/mock/mock_stack_hcic_hciblecmds.h @@ -464,6 +464,16 @@ struct btsnd_hcic_ble_read_resolvable_addr_peer { }; extern struct btsnd_hcic_ble_read_resolvable_addr_peer btsnd_hcic_ble_read_resolvable_addr_peer; + +// Name: btsnd_hcic_ble_receiver_test +// Params: uint8_t rx_freq +// Return: void +struct btsnd_hcic_ble_receiver_test { + std::function body{[](uint8_t rx_freq) {}}; + void operator()(uint8_t rx_freq) { body(rx_freq); }; +}; +extern struct btsnd_hcic_ble_receiver_test btsnd_hcic_ble_receiver_test; + // Name: btsnd_hcic_ble_rm_device_resolving_list // Params: uint8_t addr_type_peer, const RawAddress& bda_peer // Return: void @@ -721,6 +731,27 @@ struct btsnd_hcic_ble_start_enc { }; extern struct btsnd_hcic_ble_start_enc btsnd_hcic_ble_start_enc; +// Name: btsnd_hcic_ble_test_end +// Params: void +// Return: void +struct btsnd_hcic_ble_test_end { + std::function body{[](void) {}}; + void operator()(void) { body(); }; +}; +extern struct btsnd_hcic_ble_test_end btsnd_hcic_ble_test_end; + +// Name: btsnd_hcic_ble_transmitter_test +// Params: uint8_t tx_freq, uint8_t test_data_len, uint8_t payload +// Return: void +struct btsnd_hcic_ble_transmitter_test { + std::function + body{[](uint8_t tx_freq, uint8_t test_data_len, uint8_t payload) {}}; + void operator()(uint8_t tx_freq, uint8_t test_data_len, uint8_t payload) { + body(tx_freq, test_data_len, payload); + }; +}; +extern struct btsnd_hcic_ble_transmitter_test btsnd_hcic_ble_transmitter_test; + // Name: btsnd_hcic_ble_upd_ll_conn_params // Params: uint16_t handle, uint16_t conn_int_min, uint16_t conn_int_max, // uint16_t conn_latency, uint16_t conn_timeout, uint16_t min_ce_len, uint16_t -- GitLab From 30432617be959c878ccba57ed750f74a83895be5 Mon Sep 17 00:00:00 2001 From: Josh Wu Date: Fri, 12 May 2023 19:03:07 +0800 Subject: [PATCH 0051/2405] SMP: Use single quirk flag to control CSRK distribution Allowing all-configurable io capabilities may result in unexpected behaviors. For CSRK stability issue, using a single quirk flag should be safer. Bug: 274790094 Test: avatar Change-Id: I9545a20409e939c2204c00d0444081ceec571e46 --- system/stack/btm/btm_ble.cc | 42 +++++++++++++------------------------ 1 file changed, 15 insertions(+), 27 deletions(-) diff --git a/system/stack/btm/btm_ble.cc b/system/stack/btm/btm_ble.cc index edba2da2ede..cebbf1bc824 100644 --- a/system/stack/btm/btm_ble.cc +++ b/system/stack/btm/btm_ble.cc @@ -70,21 +70,8 @@ namespace { constexpr char kBtmLogTag[] = "SEC"; } -// Pairing parameters defined in Vol 3, Part H, Chapter 3.5.1 - 3.5.2 -// All present in the exact decimal values, not hex -// Ex: bluetooth.core.smp.le.ctkd.initiator_key_distribution 15(0x0f) -static const char kPropertyCtkdAuthRequest[] = - "bluetooth.core.smp.le.ctkd.auth_request"; -static const char kPropertyCtkdIoCapabilities[] = - "bluetooth.core.smp.le.ctkd.io_capabilities"; -// Vol 3, Part H, Chapter 3.6.1, Figure 3.11 -// |EncKey(1)|IdKey(1)|SignKey(1)|LinkKey(1)|Reserved(4)| -static const char kPropertyCtkdInitiatorKeyDistribution[] = - "bluetooth.core.smp.le.ctkd.initiator_key_distribution"; -static const char kPropertyCtkdResponderKeyDistribution[] = - "bluetooth.core.smp.le.ctkd.responder_key_distribution"; -static const char kPropertyCtkdMaxKeySize[] = - "bluetooth.core.smp.le.ctkd.max_key_size"; +static constexpr char kPropertyCtkdDisableCsrkDistribution[] = + "bluetooth.core.smp.le.ctkd.quirk_disable_csrk_distribution"; /******************************************************************************/ /* External Function to be called by other modules */ @@ -1671,18 +1658,19 @@ uint8_t btm_ble_br_keys_req(tBTM_SEC_DEV_REC* p_dev_rec, tBTM_LE_IO_REQ* p_data) { uint8_t callback_rc = BTM_SUCCESS; BTM_TRACE_DEBUG("%s", __func__); - p_data->io_cap = - osi_property_get_int32(kPropertyCtkdIoCapabilities, BTM_IO_CAP_UNKNOWN); - p_data->auth_req = osi_property_get_int32(kPropertyCtkdAuthRequest, - BTM_LE_AUTH_REQ_SC_MITM_BOND); - p_data->init_keys = osi_property_get_int32( - kPropertyCtkdInitiatorKeyDistribution, SMP_BR_SEC_DEFAULT_KEY); - p_data->resp_keys = osi_property_get_int32( - kPropertyCtkdResponderKeyDistribution, SMP_BR_SEC_DEFAULT_KEY); - p_data->max_key_size = - osi_property_get_int32(kPropertyCtkdMaxKeySize, BTM_BLE_MAX_KEY_SIZE); - // No OOB data for BR/EDR - p_data->oob_data = false; + *p_data = tBTM_LE_IO_REQ{ + .io_cap = BTM_IO_CAP_UNKNOWN, + .auth_req = BTM_LE_AUTH_REQ_SC_MITM_BOND, + .init_keys = SMP_BR_SEC_DEFAULT_KEY, + .resp_keys = SMP_BR_SEC_DEFAULT_KEY, + .max_key_size = BTM_BLE_MAX_KEY_SIZE, + .oob_data = false, + }; + + if (osi_property_get_bool(kPropertyCtkdDisableCsrkDistribution, false)) { + p_data->init_keys &= (~SMP_SEC_KEY_TYPE_CSRK); + p_data->resp_keys &= (~SMP_SEC_KEY_TYPE_CSRK); + } return callback_rc; } -- GitLab From 408e3f90c93a4c681c96711d8d218cc5af18138c Mon Sep 17 00:00:00 2001 From: David Duarte Date: Mon, 15 May 2023 12:18:29 +0000 Subject: [PATCH 0052/2405] Remove fluoride_test_prod_shared_defaults Test: mma Bug: 279502784 Change-Id: I343d627b60ebba08867b2d54e272693629758ca9 --- system/build/Android.bp | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/system/build/Android.bp b/system/build/Android.bp index 4f3b3936549..ced9a226295 100644 --- a/system/build/Android.bp +++ b/system/build/Android.bp @@ -113,14 +113,9 @@ cc_defaults { min_sdk_version: "current", } -cc_defaults { - name: "fluoride_test_prod_shared_defaults", - defaults: ["fluoride_defaults"], -} - cc_defaults { name: "fluoride_test_defaults", - defaults: ["fluoride_test_prod_shared_defaults"], + defaults: ["fluoride_defaults"], host_supported: true, shared_libs: [ "libcrypto", @@ -145,7 +140,7 @@ cc_defaults { cc_defaults { name: "fluoride_basic_defaults", defaults: [ - "fluoride_test_prod_shared_defaults", + "fluoride_defaults", ], apex_available: [ "//apex_available:platform", -- GitLab From de67766df90056cd84fd51102c6d7d317846e1b5 Mon Sep 17 00:00:00 2001 From: David Duarte Date: Mon, 15 May 2023 12:20:45 +0000 Subject: [PATCH 0053/2405] Remove fluoride_types_defaults Test: mma Bug: 279502784 Change-Id: Ia230329cd003ab80786fb09b70cc294176eaa2ce --- system/build/Android.bp | 8 -------- system/types/Android.bp | 2 +- 2 files changed, 1 insertion(+), 9 deletions(-) diff --git a/system/build/Android.bp b/system/build/Android.bp index ced9a226295..f51fce1fc19 100644 --- a/system/build/Android.bp +++ b/system/build/Android.bp @@ -71,13 +71,6 @@ cc_defaults { }, } -cc_defaults { - name: "fluoride_types_defaults", - defaults: [ - "fluoride_types_defaults_fuzzable", - ], -} - cc_defaults { name: "fluoride_defaults_fuzzable", target: { @@ -187,7 +180,6 @@ cc_defaults { name: "fluoride_defaults", defaults: [ "fluoride_defaults_fuzzable", - "fluoride_types_defaults", ], static_libs: [ "libbluetooth_gd", diff --git a/system/types/Android.bp b/system/types/Android.bp index c9d52b2c245..06a420eed63 100644 --- a/system/types/Android.bp +++ b/system/types/Android.bp @@ -34,7 +34,7 @@ cc_library_headers { cc_library_static { name: "libbluetooth-types", vendor_available: true, - defaults: ["fluoride_types_defaults"], + defaults: ["fluoride_types_defaults_fuzzable"], cflags: [ /* we export all classes, so change default visibility, instead of having EXPORT_SYMBOL on each class*/ "-fvisibility=default", -- GitLab From b7bf508d1f206cc68eddce43c696e74df239abee Mon Sep 17 00:00:00 2001 From: David Duarte Date: Mon, 15 May 2023 14:00:36 +0000 Subject: [PATCH 0054/2405] Remove libchrome_support_defaults Bug: 279502784 Test: mma Change-Id: I610f657e6c3a88dbc3ea6678ad6fdf594deabe48 --- system/Android.bp | 1 - system/btcore/Android.bp | 1 - system/build/Android.bp | 24 ------------------------ system/gd/Android.bp | 11 ++++++----- system/gd/rust/shim/Android.bp | 2 -- system/gd/rust/topshim/Android.bp | 2 +- system/gd/rust/topshim/facade/Android.bp | 1 - system/include/Android.bp | 3 +-- system/packet/Android.bp | 2 +- system/packet/avrcp/Android.bp | 3 ++- system/packet/base/Android.bp | 3 ++- system/profile/avrcp/Android.bp | 6 +++--- system/rust/Android.bp | 5 ++--- system/test/rootcanal/Android.bp | 2 -- 14 files changed, 18 insertions(+), 48 deletions(-) diff --git a/system/Android.bp b/system/Android.bp index 481a55a63d5..4a4f5258f97 100644 --- a/system/Android.bp +++ b/system/Android.bp @@ -186,7 +186,6 @@ genrule { // Export system headers for rules that can't simply use `include_dirs` cc_library_headers { name: "libbluetooth_system_headers", - defaults: ["libchrome_support_defaults"], visibility: [ "//packages/modules/Bluetooth/system:__subpackages__", ], diff --git a/system/btcore/Android.bp b/system/btcore/Android.bp index b3b7d45dbce..0361a809c06 100644 --- a/system/btcore/Android.bp +++ b/system/btcore/Android.bp @@ -69,7 +69,6 @@ cc_library_static { cc_library_headers { name: "libbtcore_headers", - defaults: ["libchrome_support_defaults"], export_include_dirs: ["./"], vendor_available: true, host_supported: true, diff --git a/system/build/Android.bp b/system/build/Android.bp index f51fce1fc19..9b5d24992e2 100644 --- a/system/build/Android.bp +++ b/system/build/Android.bp @@ -23,30 +23,6 @@ cc_defaults { ], } -cc_defaults { - name: "libchrome_support_defaults", - defaults: ["fluoride_common_options"], - static_libs: [ - "libchrome", - "libevent", - "libmodpb64", - ], - shared_libs: [ - "libbase", - ], - target: { - darwin: { - enabled: false, - }, - android: { - shared_libs: [ - "libcutils", - "liblog", - ], - }, - }, -} - // Fuzzable defaults are the subset of defaults that are used in fuzzing, which // requires no shared libraries, and no explicit sanitization. cc_defaults { diff --git a/system/gd/Android.bp b/system/gd/Android.bp index 656afad7d54..b01953ee0aa 100644 --- a/system/gd/Android.bp +++ b/system/gd/Android.bp @@ -98,7 +98,6 @@ cc_defaults { name: "libbluetooth_gd_defaults", defaults: [ "gd_defaults", - "libchrome_support_defaults", ], host_supported: true, target: { @@ -194,6 +193,7 @@ cc_library { "com.android.btservices", ], min_sdk_version: "31", + static_libs: ["libchrome"], } cc_library { @@ -208,6 +208,7 @@ cc_library { "-DFUZZ_TARGET", "-DUSE_FAKE_TIMERS", ], + static_libs: ["libchrome"], } cc_library { @@ -221,13 +222,13 @@ cc_library { cflags: [ "-DUSE_FAKE_TIMERS", ], + static_libs: ["libchrome"], } cc_binary { name: "bluetooth_stack_with_facade", defaults: [ "gd_defaults", - "libchrome_support_defaults", ], host_supported: true, srcs: [ @@ -263,6 +264,7 @@ cc_binary { "libbluetooth_rust_interop", "libbt_shim_bridge", "libbt_shim_ffi", + "libchrome", "libflatbuffers-cpp", ], shared_libs: [ @@ -307,7 +309,6 @@ cc_test { defaults: [ "bluetooth_gtest_x86_asan_workaround", "gd_defaults", - "libchrome_support_defaults", "mts_defaults", ], host_supported: true, @@ -385,6 +386,7 @@ cc_test { "libbt_shim_bridge", "libbt_shim_ffi", "libc++fs", + "libchrome", "libflatbuffers-cpp", "libgmock", ], @@ -403,7 +405,6 @@ cc_test { defaults: [ "bluetooth_gtest_x86_asan_workaround", "gd_defaults", - "libchrome_support_defaults", "mts_defaults", ], include_dirs: ["packages/modules/Bluetooth/system/gd"], @@ -534,7 +535,6 @@ cc_benchmark { name: "bluetooth_benchmark_gd", defaults: [ "gd_defaults", - "libchrome_support_defaults", ], host_supported: true, srcs: [ @@ -544,6 +544,7 @@ cc_benchmark { static_libs: [ "libbluetooth_gd", "libbt_shim_bridge", + "libchrome", ], } diff --git a/system/gd/rust/shim/Android.bp b/system/gd/rust/shim/Android.bp index 85dd49d8213..3bce89aecac 100644 --- a/system/gd/rust/shim/Android.bp +++ b/system/gd/rust/shim/Android.bp @@ -67,7 +67,6 @@ cc_library_static { name: "libbt_shim_bridge", defaults: [ "gd_ffi_defaults", - "libchrome_support_defaults", ], generated_headers: [ "cxx-bridge-header", @@ -97,7 +96,6 @@ cc_library_static { name: "libbluetooth_rust_interop", defaults: [ "gd_ffi_defaults", - "libchrome_support_defaults", ], static_libs: [ "libbt_shim_bridge", diff --git a/system/gd/rust/topshim/Android.bp b/system/gd/rust/topshim/Android.bp index 839e9a6ec12..236d75756f2 100644 --- a/system/gd/rust/topshim/Android.bp +++ b/system/gd/rust/topshim/Android.bp @@ -45,7 +45,6 @@ cc_library_static { name: "libbt_topshim_cxx", defaults: [ "gd_ffi_defaults", - "libchrome_support_defaults", ], srcs: [ "btav/btav_shim.cc", @@ -71,6 +70,7 @@ cc_library_static { "packages/modules/Bluetooth/system/types", ], host_supported: true, + static_libs: ["libchrome"], } gensrcs { diff --git a/system/gd/rust/topshim/facade/Android.bp b/system/gd/rust/topshim/facade/Android.bp index 4b639daae8c..b18b4eb9c76 100644 --- a/system/gd/rust/topshim/facade/Android.bp +++ b/system/gd/rust/topshim/facade/Android.bp @@ -11,7 +11,6 @@ rust_defaults { name: "bt_topshim_facade.defaults", defaults: [ "gd_rust_defaults", - "libchrome_support_defaults", ], crate_name: "bt_topshim_facade", srcs: ["src/main.rs"], diff --git a/system/include/Android.bp b/system/include/Android.bp index 0665fc4b251..f76b6fcccbe 100644 --- a/system/include/Android.bp +++ b/system/include/Android.bp @@ -9,13 +9,13 @@ package { cc_library_headers { name: "avrcp_headers", - defaults: ["libchrome_support_defaults"], export_include_dirs: ["./hardware/avrcp/"], header_libs: ["internal_include_headers"], export_header_lib_headers: ["internal_include_headers"], // We need this in case some file outside of the Bluetooth project includes // bluetooth.h but doesn't include libchrome which avrcp.h depends on. + static_libs: ["libchrome"], export_static_lib_headers: ["libchrome"], vendor_available: true, @@ -29,7 +29,6 @@ cc_library_headers { cc_library_headers { name: "libbluetooth_headers", - defaults: ["libchrome_support_defaults"], visibility: [ "//packages/apps/Test/connectivity/sl4n", "//packages/modules/Bluetooth:__subpackages__", diff --git a/system/packet/Android.bp b/system/packet/Android.bp index 26c69424fa8..2b806673287 100644 --- a/system/packet/Android.bp +++ b/system/packet/Android.bp @@ -9,7 +9,7 @@ package { cc_library_static { name: "lib-bt-packets", - defaults: ["libchrome_support_defaults"], + defaults: ["fluoride_common_options"], host_supported: true, export_include_dirs: [ "./", diff --git a/system/packet/avrcp/Android.bp b/system/packet/avrcp/Android.bp index 63de109539d..265d63b1740 100644 --- a/system/packet/avrcp/Android.bp +++ b/system/packet/avrcp/Android.bp @@ -9,7 +9,7 @@ package { cc_library_static { name: "lib-bt-packets-avrcp", - defaults: ["libchrome_support_defaults"], + defaults: ["fluoride_common_options"], header_libs: ["avrcp_headers"], export_header_lib_headers: ["avrcp_headers"], export_include_dirs: ["."], @@ -44,6 +44,7 @@ cc_library_static { ], static_libs: [ "lib-bt-packets-base", + "libchrome", ], apex_available: [ "com.android.btservices", diff --git a/system/packet/base/Android.bp b/system/packet/base/Android.bp index 114af2cd237..4933c37feec 100644 --- a/system/packet/base/Android.bp +++ b/system/packet/base/Android.bp @@ -9,7 +9,7 @@ package { cc_library_static { name: "lib-bt-packets-base", - defaults: ["libchrome_support_defaults"], + defaults: ["fluoride_common_options"], export_include_dirs: ["./"], host_supported: true, include_dirs: ["packages/modules/Bluetooth/system/include"], @@ -22,4 +22,5 @@ cc_library_static { "com.android.btservices", ], min_sdk_version: "30", + static_libs: ["libchrome"], } diff --git a/system/profile/avrcp/Android.bp b/system/profile/avrcp/Android.bp index 941296560b7..1b8c5bdc589 100644 --- a/system/profile/avrcp/Android.bp +++ b/system/profile/avrcp/Android.bp @@ -11,7 +11,6 @@ cc_library_static { name: "avrcp-target-service", defaults: [ "fluoride_defaults", - "libchrome_support_defaults", ], host_supported: true, include_dirs: [ @@ -46,7 +45,6 @@ cc_test { defaults: [ "bluetooth_gtest_x86_asan_workaround", "fluoride_defaults", - "libchrome_support_defaults", "mts_defaults", ], host_supported: true, @@ -69,7 +67,9 @@ cc_test { "lib-bt-packets-base", "libbase", "libbtdevice", + "libchrome", "libcutils", + "libevent", "libgmock", "liblog", "libosi", @@ -86,7 +86,6 @@ cc_fuzz { host_supported: true, defaults: [ "fluoride_defaults_fuzzable", - "libchrome_support_defaults", ], srcs: [ "tests/avrcp_device_fuzz/avrcp_device_fuzz.cc", @@ -104,6 +103,7 @@ cc_fuzz { "lib-bt-packets-base", "libbase", "libbluetooth_gd", + "libchrome", "libcutils", "libevent", "liblog", diff --git a/system/rust/Android.bp b/system/rust/Android.bp index 153d5e9490a..738a0ed5b13 100644 --- a/system/rust/Android.bp +++ b/system/rust/Android.bp @@ -109,9 +109,7 @@ rust_test_host { cc_library_static { name: "libbluetooth_core_rs_bridge", - defaults: [ - "libchrome_support_defaults", - ], + defaults: ["fluoride_common_options"], srcs: [ "src/connection/ffi/connection_shim.cc", "src/core/ffi/module.cc", @@ -131,6 +129,7 @@ cc_library_static { "libbt_shim_bridge", "libbt_shim_ffi", + "libchrome", "libflatbuffers-cpp", ], generated_headers: [ diff --git a/system/test/rootcanal/Android.bp b/system/test/rootcanal/Android.bp index 99caf40608f..d102002005a 100644 --- a/system/test/rootcanal/Android.bp +++ b/system/test/rootcanal/Android.bp @@ -26,7 +26,6 @@ cc_binary { name: "android.hardware.bluetooth@1.1-service.sim", defaults: [ "gd_defaults", - "libchrome_support_defaults", ], proprietary: true, relative_install_path: "hw", @@ -76,7 +75,6 @@ cc_library_shared { name: "android.hardware.bluetooth@1.1-impl-sim", defaults: [ "gd_defaults", - "libchrome_support_defaults", ], proprietary: true, relative_install_path: "hw", -- GitLab From 755e172510c9dce6b2d549c79c279591e3566623 Mon Sep 17 00:00:00 2001 From: Henri Chataing Date: Mon, 8 May 2023 11:08:35 -0700 Subject: [PATCH 0055/2405] pdl: Implement support for array padding Bug: 279494407 Test: cargo test Change-Id: If27672842425ba09fc0be5d28ada25e3204587db --- tools/pdl/Android.bp | 2 + tools/pdl/src/analyzer.rs | 58 ++++- tools/pdl/src/backends/rust.rs | 15 ++ tools/pdl/src/backends/rust/parser.rs | 40 ++-- tools/pdl/src/backends/rust/serializer.rs | 40 +++- tools/pdl/src/bin/generate-canonical-tests.rs | 4 + tools/pdl/src/lint.rs | 5 +- .../pdl/tests/canonical/le_rust_test_file.pdl | 35 +++ ...ket_decl_array_dynamic_count_big_endian.rs | 4 +- ..._decl_array_dynamic_count_little_endian.rs | 4 +- ..._element_width_dynamic_count_big_endian.rs | 4 +- ...ement_width_dynamic_count_little_endian.rs | 4 +- ...n_element_width_dynamic_size_big_endian.rs | 4 +- ...lement_width_dynamic_size_little_endian.rs | 4 +- ...cket_decl_array_with_padding_big_endian.rs | 221 ++++++++++++++++++ ...t_decl_array_with_padding_little_endian.rs | 221 ++++++++++++++++++ 16 files changed, 617 insertions(+), 48 deletions(-) create mode 100644 tools/pdl/tests/generated/packet_decl_array_with_padding_big_endian.rs create mode 100644 tools/pdl/tests/generated/packet_decl_array_with_padding_little_endian.rs diff --git a/tools/pdl/Android.bp b/tools/pdl/Android.bp index d9d98560b87..5bd51d77a93 100644 --- a/tools/pdl/Android.bp +++ b/tools/pdl/Android.bp @@ -77,6 +77,8 @@ filegroup { "tests/generated/packet_decl_array_unknown_element_width_dynamic_count_little_endian.rs", "tests/generated/packet_decl_array_unknown_element_width_dynamic_size_big_endian.rs", "tests/generated/packet_decl_array_unknown_element_width_dynamic_size_little_endian.rs", + "tests/generated/packet_decl_array_with_padding_big_endian.rs", + "tests/generated/packet_decl_array_with_padding_little_endian.rs", "tests/generated/packet_decl_child_packets_big_endian.rs", "tests/generated/packet_decl_child_packets_little_endian.rs", "tests/generated/packet_decl_complex_scalars_big_endian.rs", diff --git a/tools/pdl/src/analyzer.rs b/tools/pdl/src/analyzer.rs index e9e8d2561bb..733d4ef9e94 100644 --- a/tools/pdl/src/analyzer.rs +++ b/tools/pdl/src/analyzer.rs @@ -54,6 +54,9 @@ pub mod ast { pub struct FieldAnnotation { // Size of field. pub size: Size, + // Size of field with padding bytes. + // This information exists only for array fields. + pub padded_size: Option, } #[derive(Default, Debug, Clone)] @@ -65,6 +68,12 @@ pub mod ast { pub payload_size: Size, } + impl FieldAnnotation { + pub fn new(size: Size) -> Self { + FieldAnnotation { size, padded_size: None } + } + } + impl std::ops::Add for Size { type Output = Size; fn add(self, rhs: Size) -> Self::Output { @@ -1320,7 +1329,7 @@ fn compute_field_sizes(file: &parser_ast::File) -> ast::File { ) -> ast::Field { field.annotate(match &field.desc { FieldDesc::Checksum { .. } | FieldDesc::Padding { .. } => { - ast::FieldAnnotation { size: ast::Size::Static(0) } + ast::FieldAnnotation::new(ast::Size::Static(0)) } FieldDesc::Size { width, .. } | FieldDesc::Count { width, .. } @@ -1328,7 +1337,7 @@ fn compute_field_sizes(file: &parser_ast::File) -> ast::File { | FieldDesc::FixedScalar { width, .. } | FieldDesc::Reserved { width } | FieldDesc::Scalar { width, .. } => { - ast::FieldAnnotation { size: ast::Size::Static(*width) } + ast::FieldAnnotation::new(ast::Size::Static(*width)) } FieldDesc::Body | FieldDesc::Payload { .. } => { let has_payload_size = decl.fields().any(|field| match &field.desc { @@ -1337,22 +1346,24 @@ fn compute_field_sizes(file: &parser_ast::File) -> ast::File { } _ => false, }); - ast::FieldAnnotation { - size: if has_payload_size { ast::Size::Dynamic } else { ast::Size::Unknown }, - } + ast::FieldAnnotation::new(if has_payload_size { + ast::Size::Dynamic + } else { + ast::Size::Unknown + }) } FieldDesc::Typedef { type_id, .. } | FieldDesc::FixedEnum { enum_id: type_id, .. } | FieldDesc::Group { group_id: type_id, .. } => { let type_annot = scope.get(type_id).unwrap(); - ast::FieldAnnotation { size: type_annot.size + type_annot.payload_size } + ast::FieldAnnotation::new(type_annot.size + type_annot.payload_size) } FieldDesc::Array { width: Some(width), size: Some(size), .. } => { - ast::FieldAnnotation { size: ast::Size::Static(*size * *width) } + ast::FieldAnnotation::new(ast::Size::Static(*size * *width)) } FieldDesc::Array { width: None, size: Some(size), type_id: Some(type_id), .. } => { let type_annot = scope.get(type_id).unwrap(); - ast::FieldAnnotation { size: (type_annot.size + type_annot.payload_size) * *size } + ast::FieldAnnotation::new((type_annot.size + type_annot.payload_size) * *size) } FieldDesc::Array { id, size: None, .. } => { // The element does not matter when the size of the array is @@ -1364,9 +1375,11 @@ fn compute_field_sizes(file: &parser_ast::File) -> ast::File { } _ => false, }); - ast::FieldAnnotation { - size: if has_array_size { ast::Size::Dynamic } else { ast::Size::Unknown }, - } + ast::FieldAnnotation::new(if has_array_size { + ast::Size::Dynamic + } else { + ast::Size::Unknown + }) } FieldDesc::Array { .. } => unreachable!(), }) @@ -1394,6 +1407,28 @@ fn compute_field_sizes(file: &parser_ast::File) -> ast::File { } } +/// Inline padding fields. +/// The padding information is added directly to the targeted fields. +fn inline_paddings(file: &mut ast::File) { + for decl in file.declarations.iter_mut() { + match &mut decl.desc { + DeclDesc::Struct { fields, .. } + | DeclDesc::Packet { fields, .. } + | DeclDesc::Group { fields, .. } => { + let mut padding = None; + for field in fields.iter_mut().rev() { + field.annot.padded_size = padding; + padding = match &field.desc { + FieldDesc::Padding { size } => Some(*size), + _ => None, + }; + } + } + _ => (), + } + } +} + /// Inline group fields and remove group declarations. fn inline_groups(file: &mut ast::File) -> Result<(), Diagnostics> { fn inline_fields<'a>( @@ -1474,6 +1509,7 @@ pub fn analyze(file: &parser_ast::File) -> Result { check_padding_fields(file)?; check_checksum_fields(file, &scope)?; let mut file = compute_field_sizes(file); + inline_paddings(&mut file); inline_groups(&mut file)?; Ok(file) } diff --git a/tools/pdl/src/backends/rust.rs b/tools/pdl/src/backends/rust.rs index d034d4ba875..d7e355b427b 100644 --- a/tools/pdl/src/backends/rust.rs +++ b/tools/pdl/src/backends/rust.rs @@ -1329,6 +1329,21 @@ mod tests { " ); + test_pdl!( + packet_decl_array_with_padding, + " + struct Foo { + _count_(a): 40, + a: 16[], + } + + packet Bar { + a: Foo[], + _padding_ [128], + } + " + ); + test_pdl!( packet_decl_reserved_field, " diff --git a/tools/pdl/src/backends/rust/parser.rs b/tools/pdl/src/backends/rust/parser.rs index b1fa7167109..b3e7d422b3c 100644 --- a/tools/pdl/src/backends/rust/parser.rs +++ b/tools/pdl/src/backends/rust/parser.rs @@ -63,12 +63,13 @@ impl<'a> FieldParser<'a> { pub fn add(&mut self, field: &'a analyzer_ast::Field) { match &field.desc { _ if self.scope.is_bitfield(field) => self.add_bit_field(field), - ast::FieldDesc::Padding { .. } => todo!("Padding fields are not supported"), + ast::FieldDesc::Padding { .. } => (), ast::FieldDesc::Array { id, width, type_id, size, .. } => self.add_array_field( id, *width, type_id.as_deref(), *size, + field.annot.padded_size, self.scope.get_field_declaration(field), ), ast::FieldDesc::Typedef { id, type_id } => self.add_typedef_field(id, type_id), @@ -91,7 +92,7 @@ impl<'a> FieldParser<'a> { let end_offset = self.offset + size; let wanted = proc_macro2::Literal::usize_unsuffixed(size); - self.check_size("e!(#wanted)); + self.check_size(self.span, "e!(#wanted)); let chunk_type = types::Integer::new(self.shift); // TODO(mgeisler): generate Rust variable names which cannot @@ -252,9 +253,8 @@ impl<'a> FieldParser<'a> { Some(offset) } - fn check_size(&mut self, wanted: &proc_macro2::TokenStream) { + fn check_size(&mut self, span: &proc_macro2::Ident, wanted: &proc_macro2::TokenStream) { let packet_name = &self.packet_name; - let span = self.span; self.code.push(quote! { if #span.get().remaining() < #wanted { return Err(Error::InvalidLengthError { @@ -277,6 +277,7 @@ impl<'a> FieldParser<'a> { // `size`: the size of the array in number of elements (if // known). If None, the array is a Vec with a dynamic size. size: Option, + padding_size: Option, decl: Option<&analyzer_ast::Decl>, ) { enum ElementWidth { @@ -312,18 +313,29 @@ impl<'a> FieldParser<'a> { // TODO size modifier - // TODO padded_size + let span = match padding_size { + Some(padding_size) => { + let span = self.span; + self.check_size(span, "e!(#padding_size)); + self.code.push(quote! { + let (head, tail) = #span.get().split_at(#padding_size); + let mut head = &mut Cell::new(head); + #span.replace(tail); + }); + format_ident!("head") + } + None => self.span.clone(), + }; let id = format_ident!("{id}"); - let span = self.span; - let parse_element = self.parse_array_element(self.span, width, type_id, decl); + let parse_element = self.parse_array_element(&span, width, type_id, decl); match (element_width, &array_shape) { (ElementWidth::Unknown, ArrayShape::SizeField(size_field)) => { // The element width is not known, but the array full // octet size is known by size field. Parse elements // item by item as a vector. - self.check_size("e!(#size_field)); + self.check_size(&span, "e!(#size_field)); let parse_element = self.parse_array_element(&format_ident!("head"), width, type_id, decl); self.code.push(quote! { @@ -383,7 +395,7 @@ impl<'a> FieldParser<'a> { let element_width = syn::Index::from(element_width); quote!(#count * #element_width) }; - self.check_size(&array_size); + self.check_size(&span, "e! { #array_size }); self.code.push(quote! { // TODO(mgeisler): use // https://doc.rust-lang.org/std/array/fn.try_from_fn.html @@ -395,10 +407,10 @@ impl<'a> FieldParser<'a> { .map_err(|_| Error::InvalidPacketError)?; }); } - (ElementWidth::Static(_), ArrayShape::CountField(count_field)) => { + (ElementWidth::Static(element_width), ArrayShape::CountField(count_field)) => { // The element width is known, and the array element // count is known dynamically by the count field. - self.check_size("e!(#count_field)); + self.check_size(&span, "e!(#count_field * #element_width)); self.code.push(quote! { let #id = (0..#count_field) .map(|_| #parse_element) @@ -411,7 +423,7 @@ impl<'a> FieldParser<'a> { // is known by size field, or unknown (in which case // it is the remaining span length). let array_size = if let ArrayShape::SizeField(size_field) = &array_shape { - self.check_size("e!(#size_field)); + self.check_size(&span, "e!(#size_field)); quote!(#size_field) } else { quote!(#span.get().remaining()) @@ -531,7 +543,7 @@ impl<'a> FieldParser<'a> { // payload and update the span in case fields are placed // after the payload. let size_field = size_field_ident(field_id); - self.check_size("e!(#size_field )); + self.check_size(self.span, "e!(#size_field )); self.code.push(quote! { let payload = &#span.get()[..#size_field]; #span.get_mut().advance(#size_field); @@ -553,7 +565,7 @@ impl<'a> FieldParser<'a> { "Payload field offset from end of packet is not a multiple of 8" ); let offset_from_end = syn::Index::from(offset_from_end / 8); - self.check_size("e!(#offset_from_end)); + self.check_size(self.span, "e!(#offset_from_end)); self.code.push(quote! { let payload = &#span.get()[..#span.get().len() - #offset_from_end]; #span.get_mut().advance(payload.len()); diff --git a/tools/pdl/src/backends/rust/serializer.rs b/tools/pdl/src/backends/rust/serializer.rs index 1cb7ecbca83..70a86536e1c 100644 --- a/tools/pdl/src/backends/rust/serializer.rs +++ b/tools/pdl/src/backends/rust/serializer.rs @@ -55,15 +55,20 @@ impl<'a> FieldSerializer<'a> { pub fn add(&mut self, field: &analyzer_ast::Field) { match &field.desc { _ if self.scope.is_bitfield(field) => self.add_bit_field(field), - ast::FieldDesc::Array { id, width, .. } => { - self.add_array_field(id, *width, self.scope.get_field_declaration(field)) - } + ast::FieldDesc::Array { id, width, .. } => self.add_array_field( + id, + *width, + field.annot.padded_size, + self.scope.get_field_declaration(field), + ), ast::FieldDesc::Typedef { id, type_id } => { self.add_typedef_field(id, type_id); } ast::FieldDesc::Payload { .. } | ast::FieldDesc::Body { .. } => { self.add_payload_field() } + // Padding field handled in serialization of associated array field. + ast::FieldDesc::Padding { .. } => (), _ => todo!("Cannot yet serialize {field:?}"), } } @@ -258,10 +263,10 @@ impl<'a> FieldSerializer<'a> { &mut self, id: &str, width: Option, + padding_size: Option, decl: Option<&analyzer_ast::Decl>, ) { - // TODO: padding - + let span = format_ident!("{}", self.span); let serialize = match width { Some(width) => { let value = quote!(*elem); @@ -277,7 +282,6 @@ impl<'a> FieldSerializer<'a> { self.span, ) } else { - let span = format_ident!("{}", self.span); quote! { elem.write_to(#span) } @@ -286,10 +290,26 @@ impl<'a> FieldSerializer<'a> { }; let id = format_ident!("{id}"); - self.code.push(quote! { - for elem in &self.#id { - #serialize; - } + + self.code.push(match padding_size { + Some(padding_size) => + quote! { + let current_size = #span.len(); + for elem in &self.#id { + #serialize; + } + let array_size = #span.len() - current_size; + if array_size > #padding_size { + panic!("attempted to serialize an array larger than the enclosing padding size"); + } + #span.put_bytes(0, #padding_size - array_size); + }, + None => + quote! { + for elem in &self.#id { + #serialize; + } + } }); } diff --git a/tools/pdl/src/bin/generate-canonical-tests.rs b/tools/pdl/src/bin/generate-canonical-tests.rs index 070cd3c994a..06246392497 100644 --- a/tools/pdl/src/bin/generate-canonical-tests.rs +++ b/tools/pdl/src/bin/generate-canonical-tests.rs @@ -173,6 +173,8 @@ fn main() { "Packet_Array_Field_UnsizedElement_UnknownSize", "Packet_Array_Field_UnsizedElement_VariableCount", "Packet_Array_Field_UnsizedElement_VariableSize", + "Packet_Array_Field_SizedElement_VariableSize_Padded", + "Packet_Array_Field_UnsizedElement_VariableCount_Padded", "Packet_Body_Field_UnknownSize", "Packet_Body_Field_UnknownSize_Terminal", "Packet_Body_Field_VariableSize", @@ -226,6 +228,8 @@ fn main() { "Struct_Array_Field_UnsizedElement_VariableCount", "Struct_Array_Field_UnsizedElement_VariableSize", "Struct_Array_Field_UnsizedElement_VariableSize", + "Struct_Array_Field_SizedElement_VariableSize_Padded", + "Struct_Array_Field_UnsizedElement_VariableCount_Padded", "Struct_Enum_Field", "Struct_FixedEnum_Field", "Struct_FixedScalar_Field", diff --git a/tools/pdl/src/lint.rs b/tools/pdl/src/lint.rs index 27457ac078a..7a389fd1fcb 100644 --- a/tools/pdl/src/lint.rs +++ b/tools/pdl/src/lint.rs @@ -275,7 +275,10 @@ impl<'d> Scope<'d> { | FieldDesc::ElementSize { width, .. } | FieldDesc::Reserved { width, .. } | FieldDesc::FixedScalar { width, .. } => Some(*width), - FieldDesc::Padding { .. } => todo!(), + FieldDesc::Padding { .. } => Some(0), + FieldDesc::Array { .. } if field.annot.padded_size.is_some() => { + Some(field.annot.padded_size.unwrap() * 8) + } FieldDesc::Array { size: Some(size), width, .. } => { let element_width = width .or_else(|| self.get_decl_width(self.get_field_declaration(field)?, false))?; diff --git a/tools/pdl/tests/canonical/le_rust_test_file.pdl b/tools/pdl/tests/canonical/le_rust_test_file.pdl index d1450de564b..cdb20b3ec63 100644 --- a/tools/pdl/tests/canonical/le_rust_test_file.pdl +++ b/tools/pdl/tests/canonical/le_rust_test_file.pdl @@ -260,6 +260,21 @@ packet Packet_Array_Field_UnsizedElement_UnknownSize { array: UnsizedStruct[], } +// The parser must be able to handle arrays with padded size. +packet Packet_Array_Field_SizedElement_VariableSize_Padded { + _size_(array) : 4, + _reserved_: 4, + array: 16[], + _padding_ [16], +} + +// The parser must be able to handle arrays with padded size. +packet Packet_Array_Field_UnsizedElement_VariableCount_Padded { + _count_(array) : 8, + array: UnsizedStruct[], + _padding_ [16], +} + // Packet inheritance // The parser must handle specialization into @@ -536,3 +551,23 @@ packet Struct_Array_Field_UnsizedElement_UnknownSize { s: Struct_Array_Field_UnsizedElement_UnknownSize_, } +// The parser must be able to handle arrays with padded size. +struct Struct_Array_Field_SizedElement_VariableSize_Padded_ { + _size_(array) : 4, + _reserved_: 4, + array: 16[], + _padding_ [16], +} +packet Struct_Array_Field_SizedElement_VariableSize_Padded { + s: Struct_Array_Field_SizedElement_VariableSize_Padded_, +} + +// The parser must be able to handle arrays with padded size. +struct Struct_Array_Field_UnsizedElement_VariableCount_Padded_ { + _count_(array) : 8, + array: UnsizedStruct[], + _padding_ [16], +} +packet Struct_Array_Field_UnsizedElement_VariableCount_Padded { + s: Struct_Array_Field_UnsizedElement_VariableCount_Padded_, +} diff --git a/tools/pdl/tests/generated/packet_decl_array_dynamic_count_big_endian.rs b/tools/pdl/tests/generated/packet_decl_array_dynamic_count_big_endian.rs index 412285fb888..3628db4666f 100644 --- a/tools/pdl/tests/generated/packet_decl_array_dynamic_count_big_endian.rs +++ b/tools/pdl/tests/generated/packet_decl_array_dynamic_count_big_endian.rs @@ -85,10 +85,10 @@ impl FooData { let chunk = bytes.get_mut().get_u8(); let x_count = (chunk & 0x1f) as usize; let padding = ((chunk >> 5) & 0x7); - if bytes.get().remaining() < x_count { + if bytes.get().remaining() < x_count * 3usize { return Err(Error::InvalidLengthError { obj: "Foo".to_string(), - wanted: x_count, + wanted: x_count * 3usize, got: bytes.get().remaining(), }); } diff --git a/tools/pdl/tests/generated/packet_decl_array_dynamic_count_little_endian.rs b/tools/pdl/tests/generated/packet_decl_array_dynamic_count_little_endian.rs index 40999524292..ef8c84955d9 100644 --- a/tools/pdl/tests/generated/packet_decl_array_dynamic_count_little_endian.rs +++ b/tools/pdl/tests/generated/packet_decl_array_dynamic_count_little_endian.rs @@ -85,10 +85,10 @@ impl FooData { let chunk = bytes.get_mut().get_u8(); let x_count = (chunk & 0x1f) as usize; let padding = ((chunk >> 5) & 0x7); - if bytes.get().remaining() < x_count { + if bytes.get().remaining() < x_count * 3usize { return Err(Error::InvalidLengthError { obj: "Foo".to_string(), - wanted: x_count, + wanted: x_count * 3usize, got: bytes.get().remaining(), }); } diff --git a/tools/pdl/tests/generated/packet_decl_array_unknown_element_width_dynamic_count_big_endian.rs b/tools/pdl/tests/generated/packet_decl_array_unknown_element_width_dynamic_count_big_endian.rs index 0d533b5a1a6..e1a54c7f82c 100644 --- a/tools/pdl/tests/generated/packet_decl_array_unknown_element_width_dynamic_count_big_endian.rs +++ b/tools/pdl/tests/generated/packet_decl_array_unknown_element_width_dynamic_count_big_endian.rs @@ -70,10 +70,10 @@ impl Foo { }); } let a_count = bytes.get_mut().get_uint(5) as usize; - if bytes.get().remaining() < a_count { + if bytes.get().remaining() < a_count * 2usize { return Err(Error::InvalidLengthError { obj: "Foo".to_string(), - wanted: a_count, + wanted: a_count * 2usize, got: bytes.get().remaining(), }); } diff --git a/tools/pdl/tests/generated/packet_decl_array_unknown_element_width_dynamic_count_little_endian.rs b/tools/pdl/tests/generated/packet_decl_array_unknown_element_width_dynamic_count_little_endian.rs index 8a33453edff..4a1e47c6b9c 100644 --- a/tools/pdl/tests/generated/packet_decl_array_unknown_element_width_dynamic_count_little_endian.rs +++ b/tools/pdl/tests/generated/packet_decl_array_unknown_element_width_dynamic_count_little_endian.rs @@ -70,10 +70,10 @@ impl Foo { }); } let a_count = bytes.get_mut().get_uint_le(5) as usize; - if bytes.get().remaining() < a_count { + if bytes.get().remaining() < a_count * 2usize { return Err(Error::InvalidLengthError { obj: "Foo".to_string(), - wanted: a_count, + wanted: a_count * 2usize, got: bytes.get().remaining(), }); } diff --git a/tools/pdl/tests/generated/packet_decl_array_unknown_element_width_dynamic_size_big_endian.rs b/tools/pdl/tests/generated/packet_decl_array_unknown_element_width_dynamic_size_big_endian.rs index b85578ff14f..efd41a25a4f 100644 --- a/tools/pdl/tests/generated/packet_decl_array_unknown_element_width_dynamic_size_big_endian.rs +++ b/tools/pdl/tests/generated/packet_decl_array_unknown_element_width_dynamic_size_big_endian.rs @@ -70,10 +70,10 @@ impl Foo { }); } let a_count = bytes.get_mut().get_uint(5) as usize; - if bytes.get().remaining() < a_count { + if bytes.get().remaining() < a_count * 2usize { return Err(Error::InvalidLengthError { obj: "Foo".to_string(), - wanted: a_count, + wanted: a_count * 2usize, got: bytes.get().remaining(), }); } diff --git a/tools/pdl/tests/generated/packet_decl_array_unknown_element_width_dynamic_size_little_endian.rs b/tools/pdl/tests/generated/packet_decl_array_unknown_element_width_dynamic_size_little_endian.rs index dff0ab107d8..4fdaa545aa0 100644 --- a/tools/pdl/tests/generated/packet_decl_array_unknown_element_width_dynamic_size_little_endian.rs +++ b/tools/pdl/tests/generated/packet_decl_array_unknown_element_width_dynamic_size_little_endian.rs @@ -70,10 +70,10 @@ impl Foo { }); } let a_count = bytes.get_mut().get_uint_le(5) as usize; - if bytes.get().remaining() < a_count { + if bytes.get().remaining() < a_count * 2usize { return Err(Error::InvalidLengthError { obj: "Foo".to_string(), - wanted: a_count, + wanted: a_count * 2usize, got: bytes.get().remaining(), }); } diff --git a/tools/pdl/tests/generated/packet_decl_array_with_padding_big_endian.rs b/tools/pdl/tests/generated/packet_decl_array_with_padding_big_endian.rs new file mode 100644 index 00000000000..9e285db1444 --- /dev/null +++ b/tools/pdl/tests/generated/packet_decl_array_with_padding_big_endian.rs @@ -0,0 +1,221 @@ +// @generated rust packets from test + +use bytes::{Buf, BufMut, Bytes, BytesMut}; +use std::cell::Cell; +use std::convert::{TryFrom, TryInto}; +use std::fmt; +use std::sync::Arc; +use thiserror::Error; + +type Result = std::result::Result; + +#[doc = r" Private prevents users from creating arbitrary scalar values"] +#[doc = r" in situations where the value needs to be validated."] +#[doc = r" Users can freely deref the value, but only the backend"] +#[doc = r" may create it."] +#[derive(Debug, Clone, Copy, Hash, PartialEq, Eq, PartialOrd, Ord)] +pub struct Private(T); +impl std::ops::Deref for Private { + type Target = T; + fn deref(&self) -> &Self::Target { + &self.0 + } +} + +#[derive(Debug, Error)] +pub enum Error { + #[error("Packet parsing failed")] + InvalidPacketError, + #[error("{field} was {value:x}, which is not known")] + ConstraintOutOfBounds { field: String, value: u64 }, + #[error("Got {actual:x}, expected {expected:x}")] + InvalidFixedValue { expected: u64, actual: u64 }, + #[error("when parsing {obj} needed length of {wanted} but got {got}")] + InvalidLengthError { obj: String, wanted: usize, got: usize }, + #[error("array size ({array} bytes) is not a multiple of the element size ({element} bytes)")] + InvalidArraySize { array: usize, element: usize }, + #[error("Due to size restrictions a struct could not be parsed.")] + ImpossibleStructError, + #[error("when parsing field {obj}.{field}, {value} is not a valid {type_} value")] + InvalidEnumValueError { obj: String, field: String, value: u64, type_: String }, + #[error("expected child {expected}, got {actual}")] + InvalidChildError { expected: &'static str, actual: String }, +} + +pub trait Packet { + fn to_bytes(self) -> Bytes; + fn to_vec(self) -> Vec; +} + +#[derive(Debug, Clone, PartialEq, Eq)] +#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] +pub struct Foo { + pub a: Vec, +} +impl Foo { + fn conforms(bytes: &[u8]) -> bool { + bytes.len() >= 5 + } + pub fn parse(bytes: &[u8]) -> Result { + let mut cell = Cell::new(bytes); + let packet = Self::parse_inner(&mut cell)?; + Ok(packet) + } + fn parse_inner(mut bytes: &mut Cell<&[u8]>) -> Result { + if bytes.get().remaining() < 5 { + return Err(Error::InvalidLengthError { + obj: "Foo".to_string(), + wanted: 5, + got: bytes.get().remaining(), + }); + } + let a_count = bytes.get_mut().get_uint(5) as usize; + if bytes.get().remaining() < a_count * 2usize { + return Err(Error::InvalidLengthError { + obj: "Foo".to_string(), + wanted: a_count * 2usize, + got: bytes.get().remaining(), + }); + } + let a = (0..a_count) + .map(|_| Ok::<_, Error>(bytes.get_mut().get_u16())) + .collect::>>()?; + Ok(Self { a }) + } + fn write_to(&self, buffer: &mut BytesMut) { + if self.a.len() > 0xff_ffff_ffff_usize { + panic!( + "Invalid length for {}::{}: {} > {}", + "Foo", + "a", + self.a.len(), + 0xff_ffff_ffff_usize + ); + } + buffer.put_uint(self.a.len() as u64, 5); + for elem in &self.a { + buffer.put_u16(*elem); + } + } + fn get_total_size(&self) -> usize { + self.get_size() + } + fn get_size(&self) -> usize { + 5 + self.a.len() * 2 + } +} + +#[derive(Debug, Clone, PartialEq, Eq)] +#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] +pub struct BarData { + a: Vec, +} +#[derive(Debug, Clone, PartialEq, Eq)] +#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] +pub struct Bar { + #[cfg_attr(feature = "serde", serde(flatten))] + bar: Arc, +} +#[derive(Debug)] +#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] +pub struct BarBuilder { + pub a: Vec, +} +impl BarData { + fn conforms(bytes: &[u8]) -> bool { + bytes.len() >= 128 + } + fn parse(bytes: &[u8]) -> Result { + let mut cell = Cell::new(bytes); + let packet = Self::parse_inner(&mut cell)?; + Ok(packet) + } + fn parse_inner(mut bytes: &mut Cell<&[u8]>) -> Result { + if bytes.get().remaining() < 128usize { + return Err(Error::InvalidLengthError { + obj: "Bar".to_string(), + wanted: 128usize, + got: bytes.get().remaining(), + }); + } + let (head, tail) = bytes.get().split_at(128usize); + let mut head = &mut Cell::new(head); + bytes.replace(tail); + let mut a = Vec::new(); + while !head.get().is_empty() { + a.push(Foo::parse_inner(head)?); + } + Ok(Self { a }) + } + fn write_to(&self, buffer: &mut BytesMut) { + let current_size = buffer.len(); + for elem in &self.a { + elem.write_to(buffer); + } + let array_size = buffer.len() - current_size; + if array_size > 128usize { + panic!("attempted to serialize an array larger than the enclosing padding size"); + } + buffer.put_bytes(0, 128usize - array_size); + } + fn get_total_size(&self) -> usize { + self.get_size() + } + fn get_size(&self) -> usize { + 128 + } +} +impl Packet for Bar { + fn to_bytes(self) -> Bytes { + let mut buffer = BytesMut::with_capacity(self.bar.get_size()); + self.bar.write_to(&mut buffer); + buffer.freeze() + } + fn to_vec(self) -> Vec { + self.to_bytes().to_vec() + } +} +impl From for Bytes { + fn from(packet: Bar) -> Self { + packet.to_bytes() + } +} +impl From for Vec { + fn from(packet: Bar) -> Self { + packet.to_vec() + } +} +impl Bar { + pub fn parse(bytes: &[u8]) -> Result { + let mut cell = Cell::new(bytes); + let packet = Self::parse_inner(&mut cell)?; + Ok(packet) + } + fn parse_inner(mut bytes: &mut Cell<&[u8]>) -> Result { + let data = BarData::parse_inner(&mut bytes)?; + Self::new(Arc::new(data)) + } + fn new(bar: Arc) -> Result { + Ok(Self { bar }) + } + pub fn get_a(&self) -> &Vec { + &self.bar.as_ref().a + } + fn write_to(&self, buffer: &mut BytesMut) { + self.bar.write_to(buffer) + } + pub fn get_size(&self) -> usize { + self.bar.get_size() + } +} +impl BarBuilder { + pub fn build(self) -> Bar { + let bar = Arc::new(BarData { a: self.a }); + Bar::new(bar).unwrap() + } +} +impl From for Bar { + fn from(builder: BarBuilder) -> Bar { + builder.build().into() + } +} diff --git a/tools/pdl/tests/generated/packet_decl_array_with_padding_little_endian.rs b/tools/pdl/tests/generated/packet_decl_array_with_padding_little_endian.rs new file mode 100644 index 00000000000..df694a61a5c --- /dev/null +++ b/tools/pdl/tests/generated/packet_decl_array_with_padding_little_endian.rs @@ -0,0 +1,221 @@ +// @generated rust packets from test + +use bytes::{Buf, BufMut, Bytes, BytesMut}; +use std::cell::Cell; +use std::convert::{TryFrom, TryInto}; +use std::fmt; +use std::sync::Arc; +use thiserror::Error; + +type Result = std::result::Result; + +#[doc = r" Private prevents users from creating arbitrary scalar values"] +#[doc = r" in situations where the value needs to be validated."] +#[doc = r" Users can freely deref the value, but only the backend"] +#[doc = r" may create it."] +#[derive(Debug, Clone, Copy, Hash, PartialEq, Eq, PartialOrd, Ord)] +pub struct Private(T); +impl std::ops::Deref for Private { + type Target = T; + fn deref(&self) -> &Self::Target { + &self.0 + } +} + +#[derive(Debug, Error)] +pub enum Error { + #[error("Packet parsing failed")] + InvalidPacketError, + #[error("{field} was {value:x}, which is not known")] + ConstraintOutOfBounds { field: String, value: u64 }, + #[error("Got {actual:x}, expected {expected:x}")] + InvalidFixedValue { expected: u64, actual: u64 }, + #[error("when parsing {obj} needed length of {wanted} but got {got}")] + InvalidLengthError { obj: String, wanted: usize, got: usize }, + #[error("array size ({array} bytes) is not a multiple of the element size ({element} bytes)")] + InvalidArraySize { array: usize, element: usize }, + #[error("Due to size restrictions a struct could not be parsed.")] + ImpossibleStructError, + #[error("when parsing field {obj}.{field}, {value} is not a valid {type_} value")] + InvalidEnumValueError { obj: String, field: String, value: u64, type_: String }, + #[error("expected child {expected}, got {actual}")] + InvalidChildError { expected: &'static str, actual: String }, +} + +pub trait Packet { + fn to_bytes(self) -> Bytes; + fn to_vec(self) -> Vec; +} + +#[derive(Debug, Clone, PartialEq, Eq)] +#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] +pub struct Foo { + pub a: Vec, +} +impl Foo { + fn conforms(bytes: &[u8]) -> bool { + bytes.len() >= 5 + } + pub fn parse(bytes: &[u8]) -> Result { + let mut cell = Cell::new(bytes); + let packet = Self::parse_inner(&mut cell)?; + Ok(packet) + } + fn parse_inner(mut bytes: &mut Cell<&[u8]>) -> Result { + if bytes.get().remaining() < 5 { + return Err(Error::InvalidLengthError { + obj: "Foo".to_string(), + wanted: 5, + got: bytes.get().remaining(), + }); + } + let a_count = bytes.get_mut().get_uint_le(5) as usize; + if bytes.get().remaining() < a_count * 2usize { + return Err(Error::InvalidLengthError { + obj: "Foo".to_string(), + wanted: a_count * 2usize, + got: bytes.get().remaining(), + }); + } + let a = (0..a_count) + .map(|_| Ok::<_, Error>(bytes.get_mut().get_u16_le())) + .collect::>>()?; + Ok(Self { a }) + } + fn write_to(&self, buffer: &mut BytesMut) { + if self.a.len() > 0xff_ffff_ffff_usize { + panic!( + "Invalid length for {}::{}: {} > {}", + "Foo", + "a", + self.a.len(), + 0xff_ffff_ffff_usize + ); + } + buffer.put_uint_le(self.a.len() as u64, 5); + for elem in &self.a { + buffer.put_u16_le(*elem); + } + } + fn get_total_size(&self) -> usize { + self.get_size() + } + fn get_size(&self) -> usize { + 5 + self.a.len() * 2 + } +} + +#[derive(Debug, Clone, PartialEq, Eq)] +#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] +pub struct BarData { + a: Vec, +} +#[derive(Debug, Clone, PartialEq, Eq)] +#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] +pub struct Bar { + #[cfg_attr(feature = "serde", serde(flatten))] + bar: Arc, +} +#[derive(Debug)] +#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] +pub struct BarBuilder { + pub a: Vec, +} +impl BarData { + fn conforms(bytes: &[u8]) -> bool { + bytes.len() >= 128 + } + fn parse(bytes: &[u8]) -> Result { + let mut cell = Cell::new(bytes); + let packet = Self::parse_inner(&mut cell)?; + Ok(packet) + } + fn parse_inner(mut bytes: &mut Cell<&[u8]>) -> Result { + if bytes.get().remaining() < 128usize { + return Err(Error::InvalidLengthError { + obj: "Bar".to_string(), + wanted: 128usize, + got: bytes.get().remaining(), + }); + } + let (head, tail) = bytes.get().split_at(128usize); + let mut head = &mut Cell::new(head); + bytes.replace(tail); + let mut a = Vec::new(); + while !head.get().is_empty() { + a.push(Foo::parse_inner(head)?); + } + Ok(Self { a }) + } + fn write_to(&self, buffer: &mut BytesMut) { + let current_size = buffer.len(); + for elem in &self.a { + elem.write_to(buffer); + } + let array_size = buffer.len() - current_size; + if array_size > 128usize { + panic!("attempted to serialize an array larger than the enclosing padding size"); + } + buffer.put_bytes(0, 128usize - array_size); + } + fn get_total_size(&self) -> usize { + self.get_size() + } + fn get_size(&self) -> usize { + 128 + } +} +impl Packet for Bar { + fn to_bytes(self) -> Bytes { + let mut buffer = BytesMut::with_capacity(self.bar.get_size()); + self.bar.write_to(&mut buffer); + buffer.freeze() + } + fn to_vec(self) -> Vec { + self.to_bytes().to_vec() + } +} +impl From for Bytes { + fn from(packet: Bar) -> Self { + packet.to_bytes() + } +} +impl From for Vec { + fn from(packet: Bar) -> Self { + packet.to_vec() + } +} +impl Bar { + pub fn parse(bytes: &[u8]) -> Result { + let mut cell = Cell::new(bytes); + let packet = Self::parse_inner(&mut cell)?; + Ok(packet) + } + fn parse_inner(mut bytes: &mut Cell<&[u8]>) -> Result { + let data = BarData::parse_inner(&mut bytes)?; + Self::new(Arc::new(data)) + } + fn new(bar: Arc) -> Result { + Ok(Self { bar }) + } + pub fn get_a(&self) -> &Vec { + &self.bar.as_ref().a + } + fn write_to(&self, buffer: &mut BytesMut) { + self.bar.write_to(buffer) + } + pub fn get_size(&self) -> usize { + self.bar.get_size() + } +} +impl BarBuilder { + pub fn build(self) -> Bar { + let bar = Arc::new(BarData { a: self.a }); + Bar::new(bar).unwrap() + } +} +impl From for Bar { + fn from(builder: BarBuilder) -> Bar { + builder.build().into() + } +} -- GitLab From 418ef2ff9ad0c964567fd26576c49c31c6257099 Mon Sep 17 00:00:00 2001 From: Chris Manton Date: Fri, 12 May 2023 08:08:43 -0700 Subject: [PATCH 0056/2405] test: Remove source inclusion hf_client_add_record/dip Bug: 282166128 Bug: 282234005 Test: net_test_bta Test: bt_host_test_bta64 Change-Id: Ief8817b79169b5c65e7df86acb113bf5c0ae98a7 --- system/bta/Android.bp | 17 ++++++++++ system/bta/sdp/bta_sdp_act.cc | 15 +++++++++ system/bta/test/bta_dip_test.cc | 31 ++++++++++--------- .../bta/test/bta_hf_client_add_record_test.cc | 27 ++-------------- 4 files changed, 50 insertions(+), 40 deletions(-) diff --git a/system/bta/Android.bp b/system/bta/Android.bp index fe13a8ad5bb..52ef2379ae9 100644 --- a/system/bta/Android.bp +++ b/system/bta/Android.bp @@ -199,9 +199,11 @@ cc_test { ], test_suites: ["device-tests"], srcs: [ + ":LegacyStackSdp", ":TestCommonLogMsg", ":TestCommonMockFunctions", ":TestMockBtif", + ":TestMockMainShim", ":TestMockStackBtm", "test/bta_dip_test.cc", "test/bta_dm_cust_uuid_test.cc", @@ -211,6 +213,10 @@ cc_test { "test/gatt/database_builder_test.cc", "test/gatt/database_test.cc", ], + generated_headers: [ + "BluetoothGeneratedDumpsysDataSchema_h", + "BluetoothGeneratedPackets_h", + ], shared_libs: [ "android.hardware.bluetooth.audio@2.0", "android.hardware.bluetooth.audio@2.1", @@ -228,6 +234,7 @@ cc_test { "libbtcore", "libchrome", "libcom.android.sysprop.bluetooth", + "libgmock", "libosi", ], data: [ @@ -324,6 +331,14 @@ cc_test { "gatt/bta_gattc_utils.cc", "gatt/database.cc", "gatt/database_builder.cc", + "hf_client/bta_hf_client_act.cc", + "hf_client/bta_hf_client_api.cc", + "hf_client/bta_hf_client_at.cc", + "hf_client/bta_hf_client_main.cc", + "hf_client/bta_hf_client_rfc.cc", + "hf_client/bta_hf_client_sco.cc", + "hf_client/bta_hf_client_sdp.cc", + "hfp/bta_hfp_api.cc", "hh/bta_hh_act.cc", "hh/bta_hh_api.cc", "hh/bta_hh_cfg.cc", @@ -333,9 +348,11 @@ cc_test { "pan/bta_pan_act.cc", "pan/bta_pan_api.cc", "pan/bta_pan_main.cc", + "sdp/bta_sdp_cfg.cc", "sys/bta_sys_conn.cc", "sys/bta_sys_main.cc", "sys/utl.cc", + "test/bta_hf_client_add_record_test.cc", "test/bta_api_test.cc", "test/bta_av_test.cc", "test/bta_dm_test.cc", diff --git a/system/bta/sdp/bta_sdp_act.cc b/system/bta/sdp/bta_sdp_act.cc index b29597d4e27..f0f22914759 100644 --- a/system/bta/sdp/bta_sdp_act.cc +++ b/system/bta/sdp/bta_sdp_act.cc @@ -569,3 +569,18 @@ void bta_sdp_remove_record(void* user_data) { if (bta_sdp_cb.p_dm_cback) bta_sdp_cb.p_dm_cback(BTA_SDP_REMOVE_RECORD_USER_EVT, NULL, user_data); } + +namespace bluetooth { +namespace testing { + +void bta_create_dip_sdp_record(bluetooth_sdp_record* record, + tSDP_DISC_REC* p_rec) { + ::bta_create_dip_sdp_record(record, p_rec); +} + +void bta_sdp_search_cback(tSDP_RESULT result, const void* user_data) { + ::bta_sdp_search_cback(result, user_data); +} + +} // namespace testing +} // namespace bluetooth diff --git a/system/bta/test/bta_dip_test.cc b/system/bta/test/bta_dip_test.cc index 3e71e2e6e16..2f480a7ae72 100644 --- a/system/bta/test/bta_dip_test.cc +++ b/system/bta/test/bta_dip_test.cc @@ -18,9 +18,10 @@ #include -#include "bta/sdp/bta_sdp_act.cc" +#include "bta/sdp/bta_sdp_int.h" +#include "btif/include/btif_sock_sdp.h" #include "main/shim/metrics_api.h" -#include "stack/sdp/sdp_api.cc" +#include "test/mock/mock_stack_sdp_api.h" #include "types/bluetooth/uuid.h" #include "types/raw_address.h" @@ -28,8 +29,7 @@ namespace { const RawAddress bdaddr({0x11, 0x22, 0x33, 0x44, 0x55, 0x66}); } // namespace -extern tBTA_SDP_CB bta_sdp_cb; -extern tBTA_SDP_CFG* p_bta_sdp_cfg; +tBTA_SDP_CB bta_sdp_cb; static tSDP_DISC_ATTR g_attr_service_class_id_list; static tSDP_DISC_ATTR g_sub_attr; @@ -41,19 +41,11 @@ static tSDP_DISC_ATTR g_attr_vendor_product_version; static tSDP_DISC_ATTR g_attr_vendor_product_primary_record; static tSDP_DISC_REC g_rec; -bool sdpu_compare_uuid_with_attr(const Uuid& uuid, tSDP_DISC_ATTR* p_attr) { - return true; -} - static void sdp_dm_cback(tBTA_SDP_EVT event, tBTA_SDP* p_data, void* user_data) { return; } -bool bluetooth::shim::CountCounterMetrics(int32_t key, int64_t count) { - return true; -} - class BtaDipTest : public ::testing::Test { protected: void SetUp() override { @@ -109,11 +101,21 @@ class BtaDipTest : public ::testing::Test { void TearDown() override {} }; +namespace bluetooth { +namespace testing { + +void bta_create_dip_sdp_record(bluetooth_sdp_record* record, + tSDP_DISC_REC* p_rec); +void bta_sdp_search_cback(tSDP_RESULT result, const void* user_data); + +} // namespace testing +} // namespace bluetooth + // Test that bta_create_dip_sdp_record can parse sdp record to bluetooth_sdp_record correctly TEST_F(BtaDipTest, test_bta_create_dip_sdp_record) { bluetooth_sdp_record record; - bta_create_dip_sdp_record(&record, &g_rec); + bluetooth::testing::bta_create_dip_sdp_record(&record, &g_rec); ASSERT_EQ(record.dip.spec_id, 0x0103); ASSERT_EQ(record.dip.vendor, 0x18d1); @@ -127,6 +129,5 @@ TEST_F(BtaDipTest, test_bta_sdp_search_cback) { Uuid* userdata = (Uuid*)malloc(sizeof(Uuid)); memcpy(userdata, &UUID_DIP, sizeof(UUID_DIP)); - bta_sdp_search_cback(SDP_SUCCESS, userdata); + bluetooth::testing::bta_sdp_search_cback(SDP_SUCCESS, userdata); } - diff --git a/system/bta/test/bta_hf_client_add_record_test.cc b/system/bta/test/bta_hf_client_add_record_test.cc index 4b16cd5221a..851315f1658 100644 --- a/system/bta/test/bta_hf_client_add_record_test.cc +++ b/system/bta/test/bta_hf_client_add_record_test.cc @@ -19,35 +19,12 @@ #include #include -#include "bta/hf_client/bta_hf_client_sdp.cc" +#include "bta/hf_client/bta_hf_client_int.h" #include "bta/include/bta_hf_client_api.h" -#include "btif/src/btif_hf_client.cc" #include "types/bluetooth/uuid.h" static uint16_t gVersion; -bool SDP_AddProtocolList(uint32_t handle, uint16_t num_elem, - tSDP_PROTOCOL_ELEM* p_elem_list) { - return false; -} -bool SDP_AddServiceClassIdList(uint32_t handle, uint16_t num_services, - uint16_t* p_service_uuids) { - return false; -} -bool SDP_AddProfileDescriptorList(uint32_t handle, uint16_t profile_uuid, - uint16_t version) { - gVersion = version; - return false; -} -bool SDP_AddAttribute(uint32_t handle, uint16_t attr_id, uint8_t attr_type, - uint32_t attr_len, uint8_t* p_val) { - return false; -} -bool SDP_AddUuidSequence(uint32_t handle, uint16_t attr_id, uint16_t num_uuids, - uint16_t* p_uuids) { - return false; -} - class BtaHfClientAddRecordTest : public ::testing::Test { protected: void SetUp() override { @@ -63,6 +40,6 @@ TEST_F(BtaHfClientAddRecordTest, test_hf_client_add_record) { uint8_t scn = 0; bta_hf_client_add_record("Handsfree", scn, features, sdp_handle); - ASSERT_EQ(gVersion, get_default_hfp_version()); + ASSERT_EQ(HFP_VERSION_1_7, get_default_hfp_version()); } -- GitLab From 15bfb90d87623d387f1a6d504e47092e4988b663 Mon Sep 17 00:00:00 2001 From: Yuyang Huang Date: Tue, 28 Mar 2023 16:44:47 -0700 Subject: [PATCH 0057/2405] Add ASHA packet drop frequency limit Some HA companies need packet sequence number to align with real world time. Limit drop frequency to decrease clock drift heuristic's impact. Test: manual Bug: 233715486 Change-Id: Ie698626e27aa28d02a775287e68173e8e79c249e --- system/bta/hearing_aid/hearing_aid.cc | 23 +++++++++++++++++++++-- system/gd/rust/common/src/init_flags.rs | 1 + system/gd/rust/shim/src/init_flags.rs | 1 + 3 files changed, 23 insertions(+), 2 deletions(-) diff --git a/system/bta/hearing_aid/hearing_aid.cc b/system/bta/hearing_aid/hearing_aid.cc index 5971d4d4dae..50835a4b249 100644 --- a/system/bta/hearing_aid/hearing_aid.cc +++ b/system/bta/hearing_aid/hearing_aid.cc @@ -25,6 +25,7 @@ #include #include // HexEncode +#include #include #include #include @@ -33,6 +34,7 @@ #include "bta/include/bta_gatt_queue.h" #include "bta/include/bta_hearing_aid_api.h" #include "btm_iso_api.h" +#include "common/init_flags.h" #include "device/include/controller.h" #include "embdrv/g722/g722_enc_dec.h" #include "osi/include/compat.h" @@ -259,6 +261,11 @@ class HearingAidImpl : public HearingAid { "persist.bluetooth.hearing_aid_max_ce_len"; // Record whether the connection parameter needs to update to a better one bool needs_parameter_update = false; + std::chrono::time_point last_drop_time_point = + std::chrono::steady_clock::now(); + // at most 1 packet DROP per DROP_FREQUENCY_THRESHOLD seconds + const int DROP_FREQUENCY_THRESHOLD = + bluetooth::common::init_flags::get_asha_packet_drop_frequency_threshold(); public: ~HearingAidImpl() override = default; @@ -395,6 +402,16 @@ class HearingAidImpl : public HearingAid { return connection_interval; } + bool IsBelowDropFrequency( + std::chrono::time_point tp) { + auto duration = tp - last_drop_time_point; + bool droppable = + std::chrono::duration_cast(duration).count() >= + DROP_FREQUENCY_THRESHOLD; + LOG_INFO("IsBelowDropFrequency %s", droppable ? "true" : "false"); + return droppable; + } + void Connect(const RawAddress& address) { LOG_DEBUG("%s", ADDRESS_TO_LOGGABLE_CSTR(address)); hearingDevices.Add(HearingDevice(address, true)); @@ -1383,6 +1400,7 @@ class HearingAidImpl : public HearingAid { // reallocations // TODO: this should basically fit the encoded data, tune the size later std::vector encoded_data_left; + auto time_point = std::chrono::steady_clock::now(); if (left) { // TODO: instead of a magic number, we need to figure out the correct // buffer size @@ -1397,7 +1415,7 @@ class HearingAidImpl : public HearingAid { if (packets_in_chans) { // Compare the two sides LE CoC credit value to confirm need to drop or // skip audio packet. - if (NeedToDropPacket(left, right)) { + if (NeedToDropPacket(left, right) && IsBelowDropFrequency(time_point)) { LOG_INFO("%s triggers dropping, %u packets in channel", ADDRESS_TO_LOGGABLE_CSTR(left->address), packets_in_chans); @@ -1431,7 +1449,7 @@ class HearingAidImpl : public HearingAid { if (packets_in_chans) { // Compare the two sides LE CoC credit value to confirm need to drop or // skip audio packet. - if (NeedToDropPacket(right, left)) { + if (NeedToDropPacket(right, left) && IsBelowDropFrequency(time_point)) { LOG_INFO("%s triggers dropping, %u packets in channel", ADDRESS_TO_LOGGABLE_CSTR(right->address), packets_in_chans); @@ -1457,6 +1475,7 @@ class HearingAidImpl : public HearingAid { CalcCompressedAudioPacketSize(codec_in_use, default_data_interval_ms); if (need_drop) { + last_drop_time_point = time_point; if (left) { left->audio_stats.packet_drop_count++; } diff --git a/system/gd/rust/common/src/init_flags.rs b/system/gd/rust/common/src/init_flags.rs index 4cdf12dd04a..fdb0bcee5f3 100644 --- a/system/gd/rust/common/src/init_flags.rs +++ b/system/gd/rust/common/src/init_flags.rs @@ -358,6 +358,7 @@ pub const LOG_TAG_VERBOSE: i32 = 6; init_flags!( name: InitFlags flags: { + asha_packet_drop_frequency_threshold: i32 = 60, always_send_services_if_gatt_disc_done = true, always_use_private_gatt_for_debugging, asynchronously_start_l2cap_coc = true, diff --git a/system/gd/rust/shim/src/init_flags.rs b/system/gd/rust/shim/src/init_flags.rs index 5b0123988bd..09750d11e4f 100644 --- a/system/gd/rust/shim/src/init_flags.rs +++ b/system/gd/rust/shim/src/init_flags.rs @@ -34,6 +34,7 @@ mod ffi { fn get_default_log_level() -> i32; fn get_hci_adapter() -> i32; fn get_log_level_for_tag(tag: &str) -> i32; + fn get_asha_packet_drop_frequency_threshold() -> i32; fn hfp_dynamic_version_is_enabled() -> bool; fn irk_rotation_is_enabled() -> bool; fn leaudio_targeted_announcement_reconnection_mode_is_enabled() -> bool; -- GitLab From 81ed99ea3b28d3797b16401079b169b5e004b0e5 Mon Sep 17 00:00:00 2001 From: Henri Chataing Date: Mon, 15 May 2023 11:21:50 -0700 Subject: [PATCH 0058/2405] RootCanal: Validate connections in phy update procedure The connection may be lost if disconnected in the middle of a phy update procedure. Ingore LL_PHY_REQ, LL_PHY_RSP, and LL_PHY_IND pdus that are not sent on a valid connection. Test: atest avatar Bug: 275970864 Change-Id: I15d9e861851933879ac1056567693acb51ad7a47 --- .../model/controller/link_layer_controller.cc | 24 +++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/tools/rootcanal/model/controller/link_layer_controller.cc b/tools/rootcanal/model/controller/link_layer_controller.cc index 00eb1b0c422..81a1248e6e2 100644 --- a/tools/rootcanal/model/controller/link_layer_controller.cc +++ b/tools/rootcanal/model/controller/link_layer_controller.cc @@ -460,6 +460,14 @@ void LinkLayerController::IncomingLlPhyReq( ASSERT(phy_req.IsValid()); uint16_t connection_handle = connections_.GetHandleOnlyAddress(incoming.GetSourceAddress()); + + if (connection_handle == kReservedHandle) { + LOG_INFO("@%s: Unknown connection @%s", + incoming.GetDestinationAddress().ToString().c_str(), + incoming.GetSourceAddress().ToString().c_str()); + return; + } + AclConnection& connection = connections_.GetAclConnection(connection_handle); if (connection.GetRole() == bluetooth::hci::Role::PERIPHERAL) { @@ -515,6 +523,14 @@ void LinkLayerController::IncomingLlPhyRsp( ASSERT(phy_rsp.IsValid()); uint16_t connection_handle = connections_.GetHandleOnlyAddress(incoming.GetSourceAddress()); + + if (connection_handle == kReservedHandle) { + LOG_INFO("@%s: Unknown connection @%s", + incoming.GetDestinationAddress().ToString().c_str(), + incoming.GetSourceAddress().ToString().c_str()); + return; + } + AclConnection& connection = connections_.GetAclConnection(connection_handle); ASSERT(connection.GetRole() == bluetooth::hci::Role::CENTRAL); @@ -559,6 +575,14 @@ void LinkLayerController::IncomingLlPhyUpdateInd( ASSERT(phy_update_ind.IsValid()); uint16_t connection_handle = connections_.GetHandleOnlyAddress(incoming.GetSourceAddress()); + + if (connection_handle == kReservedHandle) { + LOG_INFO("@%s: Unknown connection @%s", + incoming.GetDestinationAddress().ToString().c_str(), + incoming.GetSourceAddress().ToString().c_str()); + return; + } + AclConnection& connection = connections_.GetAclConnection(connection_handle); ASSERT(connection.GetRole() == bluetooth::hci::Role::PERIPHERAL); -- GitLab From 081966285a12d053e1410868afef4edb575a2fc8 Mon Sep 17 00:00:00 2001 From: Jakub Pawlowski Date: Fri, 19 Nov 2021 12:10:52 +0100 Subject: [PATCH 0059/2405] Clear identity bit when passing address to filter Legacy stack kept Identity Address Type without the identity bit set. It is later passed without any masking to "Add to accept list", "add to resolving list", and VSC filter command. All these commands specify that the identity bit should not be set in related specifications. This is a CP with partial revert of aosp/2030646. Test: manual test with DCK application Bug: 201255908 Bug: 280811285 Change-Id: Id68e81a6706ac40d7394e2803ec3339a7bc44a0a Merged-In: Id68e81a6706ac40d7394e2803ec3339a7bc44a0a --- system/stack/btm/btm_ble_adv_filter.cc | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/system/stack/btm/btm_ble_adv_filter.cc b/system/stack/btm/btm_ble_adv_filter.cc index 73a12aeb2ac..e8923efb10c 100644 --- a/system/stack/btm/btm_ble_adv_filter.cc +++ b/system/stack/btm/btm_ble_adv_filter.cc @@ -648,7 +648,7 @@ void BTM_LE_PF_set(tBTM_BLE_PF_FILT_INDEX filt_index, case BTM_BLE_PF_ADDR_FILTER: { tBLE_BD_ADDR target_addr; target_addr.bda = cmd.address; - target_addr.type = to_ble_addr_type(cmd.addr_type); + target_addr.type = (cmd.addr_type & (~BLE_ADDR_TYPE_ID_BIT)); BTM_LE_PF_addr_filter(action, filt_index, target_addr, base::DoNothing()); @@ -687,7 +687,8 @@ void BTM_LE_PF_set(tBTM_BLE_PF_FILT_INDEX filt_index, // Set the IRK tBTM_LE_PID_KEYS pid_keys; pid_keys.irk = cmd.irk; - pid_keys.identity_addr_type = to_ble_addr_type(cmd.addr_type); + pid_keys.identity_addr_type = + (cmd.addr_type & (~BLE_ADDR_TYPE_ID_BIT)); pid_keys.identity_addr = cmd.address; // Add it to the union to pass to SecAddBleKey tBTM_LE_KEY_VALUE le_key; -- GitLab From 9b53b7c9da55f3a1dd2fb72946343911d482698f Mon Sep 17 00:00:00 2001 From: William Escande Date: Fri, 12 May 2023 17:45:59 -0700 Subject: [PATCH 0060/2405] Add some log around mode change delayed Bug: 282013616 Test: Adding some log for further debugging - noOp Change-Id: Ie8fd50456422a8d74561bef310f7a000acd12f4e --- .../bluetooth/BluetoothManagerService.java | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/service/src/com/android/server/bluetooth/BluetoothManagerService.java b/service/src/com/android/server/bluetooth/BluetoothManagerService.java index f237c53264b..e54a3d3b110 100644 --- a/service/src/com/android/server/bluetooth/BluetoothManagerService.java +++ b/service/src/com/android/server/bluetooth/BluetoothManagerService.java @@ -396,6 +396,23 @@ public class BluetoothManagerService extends IBluetoothManager.Stub { || mHandler.hasMessages(MESSAGE_RESTART_BLUETOOTH_SERVICE) || mHandler.hasMessages(MESSAGE_TIMEOUT_BIND) || mHandler.hasMessages(MESSAGE_BIND_PROFILE_SERVICE)) { + Log.d( + TAG, + "Busy reason:" + + " ENABLE=" + + mHandler.hasMessages(MESSAGE_ENABLE) + + " DISABLE=" + + mHandler.hasMessages(MESSAGE_DISABLE) + + " HANDLE_ENABLE_DELAYED=" + + mHandler.hasMessages(MESSAGE_HANDLE_ENABLE_DELAYED) + + " HANDLE_DISABLE_DELAYED=" + + mHandler.hasMessages(MESSAGE_HANDLE_DISABLE_DELAYED) + + " RESTART_BLUETOOTH_SERVICE=" + + mHandler.hasMessages(MESSAGE_RESTART_BLUETOOTH_SERVICE) + + " TIMEOUT_BIND=" + + mHandler.hasMessages(MESSAGE_TIMEOUT_BIND) + + " BIND_PROFILE_SERVICE=" + + mHandler.hasMessages(MESSAGE_BIND_PROFILE_SERVICE)); // Bluetooth is restarting return SERVICE_RESTART_TIME_MS; } -- GitLab From 21f67a8f11a80941c0222487eaa993b90a762dbc Mon Sep 17 00:00:00 2001 From: William Escande Date: Fri, 12 May 2023 17:46:22 -0700 Subject: [PATCH 0061/2405] Handle mode change cb in handler thread even the first time Bug: 282013616 Test: Manual toggle AirplaneMode Change-Id: Ide499103880ba9664bcc504f4187eae77faa065b --- .../bluetooth/BluetoothManagerService.java | 34 ++++++++++++++----- 1 file changed, 26 insertions(+), 8 deletions(-) diff --git a/service/src/com/android/server/bluetooth/BluetoothManagerService.java b/service/src/com/android/server/bluetooth/BluetoothManagerService.java index e54a3d3b110..61b43d39794 100644 --- a/service/src/com/android/server/bluetooth/BluetoothManagerService.java +++ b/service/src/com/android/server/bluetooth/BluetoothManagerService.java @@ -420,8 +420,6 @@ public class BluetoothManagerService extends IBluetoothManager.Stub { } private void delayModeChangedIfNeeded(Object token, Runnable r, String modechanged) { - mHandler.removeCallbacksAndMessages(token); - final int state = getState(); final int delayMs = estimateBusyTime(state); Log.d(TAG, "delayModeChangedIfNeeded(" + modechanged + "): " @@ -431,6 +429,8 @@ public class BluetoothManagerService extends IBluetoothManager.Stub { + ", isSatelliteModeOn()=" + isSatelliteModeOn() + ", delayed=" + delayMs + "ms"); + mHandler.removeCallbacksAndMessages(token); + if (delayMs > 0) { mHandler.postDelayed(() -> delayModeChangedIfNeeded(token, r, modechanged), token, delayMs); @@ -445,20 +445,38 @@ public class BluetoothManagerService extends IBluetoothManager.Stub { @RequiresPermission(android.Manifest.permission.BLUETOOTH_PRIVILEGED) void onAirplaneModeChanged() { - delayModeChangedIfNeeded(ON_AIRPLANE_MODE_CHANGED_TOKEN, - () -> handleAirplaneModeChanged(), "onAirplaneModeChanged"); + mHandler.postDelayed( + () -> + delayModeChangedIfNeeded( + ON_AIRPLANE_MODE_CHANGED_TOKEN, + () -> handleAirplaneModeChanged(), + "onAirplaneModeChanged"), + ON_AIRPLANE_MODE_CHANGED_TOKEN, + 0); } @RequiresPermission(android.Manifest.permission.BLUETOOTH_PRIVILEGED) void onSatelliteModeChanged() { - delayModeChangedIfNeeded(ON_SATELLITE_MODE_CHANGED_TOKEN, - () -> handleSatelliteModeChanged(), "onSatelliteModeChanged"); + mHandler.postDelayed( + () -> + delayModeChangedIfNeeded( + ON_SATELLITE_MODE_CHANGED_TOKEN, + () -> handleSatelliteModeChanged(), + "onSatelliteModeChanged"), + ON_SATELLITE_MODE_CHANGED_TOKEN, + 0); } @RequiresPermission(android.Manifest.permission.BLUETOOTH_PRIVILEGED) void onSwitchUser(UserHandle userHandle) { - delayModeChangedIfNeeded(ON_SWITCH_USER_TOKEN, - () -> handleSwitchUser(userHandle), "onSwitchUser"); + mHandler.postDelayed( + () -> + delayModeChangedIfNeeded( + ON_SWITCH_USER_TOKEN, + () -> handleSwitchUser(userHandle), + "onSwitchUser"), + ON_SWITCH_USER_TOKEN, + 0); } @RequiresPermission(android.Manifest.permission.BLUETOOTH_PRIVILEGED) -- GitLab From e0746b1d5643b1fd791c2d5405db1624a21f0060 Mon Sep 17 00:00:00 2001 From: Chris Manton Date: Sun, 14 May 2023 18:31:47 -0700 Subject: [PATCH 0062/2405] Break out stack::include::sdp_status.h Bug: 282723271 Test: net_test_stack_sdp Change-Id: Ifaf23880710f7730cd0790689bd635110002bff4 --- system/stack/include/sdp_api.h | 67 +----------------- system/stack/include/sdp_status.h | 93 +++++++++++++++++++++++++ system/stack/test/sdp/stack_sdp_test.cc | 34 +++++++++ 3 files changed, 129 insertions(+), 65 deletions(-) create mode 100644 system/stack/include/sdp_status.h diff --git a/system/stack/include/sdp_api.h b/system/stack/include/sdp_api.h index 8cceb04ded3..c7c4364e9b0 100644 --- a/system/stack/include/sdp_api.h +++ b/system/stack/include/sdp_api.h @@ -23,7 +23,8 @@ #include #include "bt_target.h" -#include "sdpdefs.h" +#include "stack/include/sdp_status.h" +#include "stack/include/sdpdefs.h" #include "types/bluetooth/uuid.h" #include "types/raw_address.h" @@ -31,70 +32,6 @@ * Constants ****************************************************************************/ -/* Success code and error codes */ -typedef enum : uint16_t { - SDP_SUCCESS = 0x0000, - SDP_INVALID_VERSION = 0x0001, - SDP_INVALID_SERV_REC_HDL = 0x0002, - SDP_INVALID_REQ_SYNTAX = 0x0003, - SDP_INVALID_PDU_SIZE = 0x0004, - SDP_INVALID_CONT_STATE = 0x0005, - SDP_NO_RESOURCES = 0x0006, - SDP_DI_REG_FAILED = 0x0007, - SDP_DI_DISC_FAILED = 0x0008, - SDP_NO_DI_RECORD_FOUND = 0x0009, - SDP_ERR_ATTR_NOT_PRESENT = 0x000A, - SDP_ILLEGAL_PARAMETER = 0x000B, - - HID_SDP_NO_SERV_UUID = (SDP_ILLEGAL_PARAMETER + 1), - HID_SDP_MANDATORY_MISSING, - - SDP_NO_RECS_MATCH = 0xFFF0, - SDP_CONN_FAILED = 0xFFF1, - SDP_CFG_FAILED = 0xFFF2, - SDP_GENERIC_ERROR = 0xFFF3, - SDP_DB_FULL = 0xFFF4, - SDP_CANCEL = 0xFFF8, -} tSDP_STATUS; -using tSDP_RESULT = tSDP_STATUS; -using tSDP_REASON = tSDP_STATUS; - -#define CASE_RETURN_TEXT(code) \ - case code: \ - return #code - -inline std::string sdp_status_text(const tSDP_STATUS& status) { - switch (status) { - CASE_RETURN_TEXT(SDP_SUCCESS); - CASE_RETURN_TEXT(SDP_INVALID_VERSION); - CASE_RETURN_TEXT(SDP_INVALID_SERV_REC_HDL); - CASE_RETURN_TEXT(SDP_INVALID_REQ_SYNTAX); - CASE_RETURN_TEXT(SDP_INVALID_PDU_SIZE); - CASE_RETURN_TEXT(SDP_INVALID_CONT_STATE); - CASE_RETURN_TEXT(SDP_NO_RESOURCES); - CASE_RETURN_TEXT(SDP_DI_REG_FAILED); - CASE_RETURN_TEXT(SDP_DI_DISC_FAILED); - CASE_RETURN_TEXT(SDP_NO_DI_RECORD_FOUND); - CASE_RETURN_TEXT(SDP_ERR_ATTR_NOT_PRESENT); - CASE_RETURN_TEXT(SDP_ILLEGAL_PARAMETER); - - CASE_RETURN_TEXT(HID_SDP_NO_SERV_UUID); - CASE_RETURN_TEXT(HID_SDP_MANDATORY_MISSING); - - CASE_RETURN_TEXT(SDP_NO_RECS_MATCH); - CASE_RETURN_TEXT(SDP_CONN_FAILED); - CASE_RETURN_TEXT(SDP_CFG_FAILED); - CASE_RETURN_TEXT(SDP_GENERIC_ERROR); - CASE_RETURN_TEXT(SDP_DB_FULL); - CASE_RETURN_TEXT(SDP_CANCEL); - default: - return base::StringPrintf("UNKNOWN[%hu]", status); - } -} -const auto sdp_result_text = sdp_status_text; - -#undef CASE_RETURN_TEXT - /* Masks for attr_value field of tSDP_DISC_ATTR */ #define SDP_DISC_ATTR_LEN_MASK 0x0FFF #define SDP_DISC_ATTR_TYPE(len_type) ((len_type) >> 12) diff --git a/system/stack/include/sdp_status.h b/system/stack/include/sdp_status.h new file mode 100644 index 00000000000..bd5cf75e0d7 --- /dev/null +++ b/system/stack/include/sdp_status.h @@ -0,0 +1,93 @@ +/****************************************************************************** + * + * Copyright 1999-2012 Broadcom Corporation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + ******************************************************************************/ + +#pragma once + +#include + +#include + +/***************************************************************************** + * Constants + ****************************************************************************/ + +/* Success code and error codes */ +typedef enum : uint16_t { + SDP_SUCCESS = 0x0000, + SDP_INVALID_VERSION = 0x0001, + SDP_INVALID_SERV_REC_HDL = 0x0002, + SDP_INVALID_REQ_SYNTAX = 0x0003, + SDP_INVALID_PDU_SIZE = 0x0004, + SDP_INVALID_CONT_STATE = 0x0005, + SDP_NO_RESOURCES = 0x0006, + SDP_DI_REG_FAILED = 0x0007, + SDP_DI_DISC_FAILED = 0x0008, + SDP_NO_DI_RECORD_FOUND = 0x0009, + SDP_ERR_ATTR_NOT_PRESENT = 0x000A, + SDP_ILLEGAL_PARAMETER = 0x000B, + + HID_SDP_NO_SERV_UUID = (SDP_ILLEGAL_PARAMETER + 1), + HID_SDP_MANDATORY_MISSING, + + SDP_NO_RECS_MATCH = 0xFFF0, + SDP_CONN_FAILED = 0xFFF1, + SDP_CFG_FAILED = 0xFFF2, + SDP_GENERIC_ERROR = 0xFFF3, + SDP_DB_FULL = 0xFFF4, + SDP_CANCEL = 0xFFF8, +} tSDP_STATUS; +using tSDP_RESULT = tSDP_STATUS; +using tSDP_REASON = tSDP_STATUS; + +#ifndef CASE_RETURN_TEXT +#define CASE_RETURN_TEXT(code) \ + case code: \ + return #code +#endif // CASE_RETURN_TEXT + +inline std::string sdp_status_text(const tSDP_STATUS& status) { + switch (status) { + CASE_RETURN_TEXT(SDP_SUCCESS); + CASE_RETURN_TEXT(SDP_INVALID_VERSION); + CASE_RETURN_TEXT(SDP_INVALID_SERV_REC_HDL); + CASE_RETURN_TEXT(SDP_INVALID_REQ_SYNTAX); + CASE_RETURN_TEXT(SDP_INVALID_PDU_SIZE); + CASE_RETURN_TEXT(SDP_INVALID_CONT_STATE); + CASE_RETURN_TEXT(SDP_NO_RESOURCES); + CASE_RETURN_TEXT(SDP_DI_REG_FAILED); + CASE_RETURN_TEXT(SDP_DI_DISC_FAILED); + CASE_RETURN_TEXT(SDP_NO_DI_RECORD_FOUND); + CASE_RETURN_TEXT(SDP_ERR_ATTR_NOT_PRESENT); + CASE_RETURN_TEXT(SDP_ILLEGAL_PARAMETER); + + CASE_RETURN_TEXT(HID_SDP_NO_SERV_UUID); + CASE_RETURN_TEXT(HID_SDP_MANDATORY_MISSING); + + CASE_RETURN_TEXT(SDP_NO_RECS_MATCH); + CASE_RETURN_TEXT(SDP_CONN_FAILED); + CASE_RETURN_TEXT(SDP_CFG_FAILED); + CASE_RETURN_TEXT(SDP_GENERIC_ERROR); + CASE_RETURN_TEXT(SDP_DB_FULL); + CASE_RETURN_TEXT(SDP_CANCEL); + default: + return base::StringPrintf("UNKNOWN[%hu]", status); + } +} +const auto sdp_result_text = sdp_status_text; + +#undef CASE_RETURN_TEXT diff --git a/system/stack/test/sdp/stack_sdp_test.cc b/system/stack/test/sdp/stack_sdp_test.cc index ef146e2465e..21c389ae9fe 100644 --- a/system/stack/test/sdp/stack_sdp_test.cc +++ b/system/stack/test/sdp/stack_sdp_test.cc @@ -227,3 +227,37 @@ TEST_F(StackSdpMainTest, sdp_flags_text) { std::numeric_limits::max())) .c_str()); } + +TEST_F(StackSdpMainTest, sdp_status_text) { + std::vector> status = { + std::make_pair(SDP_SUCCESS, "SDP_SUCCESS"), + std::make_pair(SDP_INVALID_VERSION, "SDP_INVALID_VERSION"), + std::make_pair(SDP_INVALID_SERV_REC_HDL, "SDP_INVALID_SERV_REC_HDL"), + std::make_pair(SDP_INVALID_REQ_SYNTAX, "SDP_INVALID_REQ_SYNTAX"), + std::make_pair(SDP_INVALID_PDU_SIZE, "SDP_INVALID_PDU_SIZE"), + std::make_pair(SDP_INVALID_CONT_STATE, "SDP_INVALID_CONT_STATE"), + std::make_pair(SDP_NO_RESOURCES, "SDP_NO_RESOURCES"), + std::make_pair(SDP_DI_REG_FAILED, "SDP_DI_REG_FAILED"), + std::make_pair(SDP_DI_DISC_FAILED, "SDP_DI_DISC_FAILED"), + std::make_pair(SDP_NO_DI_RECORD_FOUND, "SDP_NO_DI_RECORD_FOUND"), + std::make_pair(SDP_ERR_ATTR_NOT_PRESENT, "SDP_ERR_ATTR_NOT_PRESENT"), + std::make_pair(SDP_ILLEGAL_PARAMETER, "SDP_ILLEGAL_PARAMETER"), + std::make_pair(HID_SDP_NO_SERV_UUID, "HID_SDP_NO_SERV_UUID"), + std::make_pair(HID_SDP_MANDATORY_MISSING, "HID_SDP_MANDATORY_MISSING"), + std::make_pair(SDP_NO_RECS_MATCH, "SDP_NO_RECS_MATCH"), + std::make_pair(SDP_CONN_FAILED, "SDP_CONN_FAILED"), + std::make_pair(SDP_CFG_FAILED, "SDP_CFG_FAILED"), + std::make_pair(SDP_GENERIC_ERROR, "SDP_GENERIC_ERROR"), + std::make_pair(SDP_DB_FULL, "SDP_DB_FULL"), + std::make_pair(SDP_CANCEL, "SDP_CANCEL"), + }; + for (const auto& stat : status) { + ASSERT_STREQ(stat.second.c_str(), sdp_status_text(stat.first).c_str()); + } + auto unknown = + base::StringPrintf("UNKNOWN[%hu]", std::numeric_limits::max()); + ASSERT_STREQ(unknown.c_str(), + sdp_status_text(static_cast( + std::numeric_limits::max())) + .c_str()); +} -- GitLab From 44c2f09708e407017cff3e9ca6c661cf24b7cbcf Mon Sep 17 00:00:00 2001 From: Henri Chataing Date: Mon, 15 May 2023 11:15:13 -0700 Subject: [PATCH 0063/2405] RootCanal: Implement Read Failed Contact Counter command Bug: 282772663 Test: None Change-Id: If4d39eacb25a584bb2f5d2f159ae5755cd87774f --- .../model/controller/dual_mode_controller.cc | 37 +++++++++++++++++-- .../model/controller/dual_mode_controller.h | 4 ++ .../model/controller/link_layer_controller.cc | 4 ++ .../model/controller/link_layer_controller.h | 3 ++ 4 files changed, 44 insertions(+), 4 deletions(-) diff --git a/tools/rootcanal/model/controller/dual_mode_controller.cc b/tools/rootcanal/model/controller/dual_mode_controller.cc index b6efbd4510d..57585c7fdab 100644 --- a/tools/rootcanal/model/controller/dual_mode_controller.cc +++ b/tools/rootcanal/model/controller/dual_mode_controller.cc @@ -301,6 +301,35 @@ void DualModeController::ReadBufferSize(CommandView command) { properties_.total_num_sco_data_packets)); } +void DualModeController::ReadFailedContactCounter(CommandView command) { + auto command_view = + bluetooth::hci::ReadFailedContactCounterView::Create(command); + ASSERT(command_view.IsValid()); + + uint16_t connection_handle = command_view.GetConnectionHandle(); + uint16_t failed_contact_counter = 0; + ErrorCode status = link_layer_controller_.HasAclConnection(connection_handle) + ? ErrorCode::SUCCESS + : ErrorCode::UNKNOWN_CONNECTION; + + send_event_(bluetooth::hci::ReadFailedContactCounterCompleteBuilder::Create( + kNumCommandPackets, status, connection_handle, failed_contact_counter)); +} + +void DualModeController::ResetFailedContactCounter(CommandView command) { + auto command_view = + bluetooth::hci::ReadFailedContactCounterView::Create(command); + ASSERT(command_view.IsValid()); + + uint16_t connection_handle = command_view.GetConnectionHandle(); + ErrorCode status = link_layer_controller_.HasAclConnection(connection_handle) + ? ErrorCode::SUCCESS + : ErrorCode::UNKNOWN_CONNECTION; + + send_event_(bluetooth::hci::ResetFailedContactCounterCompleteBuilder::Create( + kNumCommandPackets, status, connection_handle)); +} + void DualModeController::ReadRssi(CommandView command) { auto command_view = bluetooth::hci::ReadRssiView::Create(command); ASSERT(command_view.IsValid()); @@ -3510,10 +3539,10 @@ const std::unordered_map //&DualModeController::ReadLocalSupportedControllerDelay}, // STATUS_PARAMETERS - //{OpCode::READ_FAILED_CONTACT_COUNTER, - //&DualModeController::ReadFailedContactCounter}, - //{OpCode::RESET_FAILED_CONTACT_COUNTER, - //&DualModeController::ResetFailedContactCounter}, + {OpCode::READ_FAILED_CONTACT_COUNTER, + &DualModeController::ReadFailedContactCounter}, + {OpCode::RESET_FAILED_CONTACT_COUNTER, + &DualModeController::ResetFailedContactCounter}, //{OpCode::READ_LINK_QUALITY, &DualModeController::ReadLinkQuality}, {OpCode::READ_RSSI, &DualModeController::ReadRssi}, //{OpCode::READ_AFH_CHANNEL_MAP, diff --git a/tools/rootcanal/model/controller/dual_mode_controller.h b/tools/rootcanal/model/controller/dual_mode_controller.h index 181348c9927..0d4f2b6b623 100644 --- a/tools/rootcanal/model/controller/dual_mode_controller.h +++ b/tools/rootcanal/model/controller/dual_mode_controller.h @@ -349,6 +349,10 @@ class DualModeController : public Device { // Status Parameters Commands // Bluetooth Core Specification Version 4.2 Volume 2 Part E 7.5 + // 7.5.1 - 7.5.2 + void ReadFailedContactCounter(CommandView command); + void ResetFailedContactCounter(CommandView command); + // 7.5.4 void ReadRssi(CommandView command); diff --git a/tools/rootcanal/model/controller/link_layer_controller.cc b/tools/rootcanal/model/controller/link_layer_controller.cc index 81a1248e6e2..df1d4dc173a 100644 --- a/tools/rootcanal/model/controller/link_layer_controller.cc +++ b/tools/rootcanal/model/controller/link_layer_controller.cc @@ -5875,6 +5875,10 @@ bool LinkLayerController::HasAclConnection() { return !connections_.GetAclHandles().empty(); } +bool LinkLayerController::HasAclConnection(uint16_t connection_handle) { + return connections_.HasHandle(connection_handle); +} + void LinkLayerController::LeReadIsoTxSync(uint16_t /* handle */) {} void LinkLayerController::LeSetCigParameters( diff --git a/tools/rootcanal/model/controller/link_layer_controller.h b/tools/rootcanal/model/controller/link_layer_controller.h index f7300747ee7..63987a693ec 100644 --- a/tools/rootcanal/model/controller/link_layer_controller.h +++ b/tools/rootcanal/model/controller/link_layer_controller.h @@ -345,7 +345,10 @@ class LinkLayerController { uint8_t retransmission_effort, uint16_t packet_types); ErrorCode RejectSynchronousConnection(Address bd_addr, uint16_t reason); + // Returns true if any ACL connection exists. bool HasAclConnection(); + // Returns true if the specified ACL connection handle is valid. + bool HasAclConnection(uint16_t connection_handle); void HandleIso(bluetooth::hci::IsoView iso); -- GitLab From 5426b155a2e587ddd0ec760a510e3a111c483991 Mon Sep 17 00:00:00 2001 From: William Escande Date: Wed, 26 Apr 2023 22:00:18 -0700 Subject: [PATCH 0064/2405] Extract binder from BluetoothManagerService Goal is to start shrinking down the code from the BluetoothManagerService. This CL remove the capacity to directly be a Binder and defer the permission check into another class Bug: 262605980 Test: manual boot + togling + shell command Test: atest ServiceBluetoothTests Test: adding new test for BluetoothServiceBinderTest Change-Id: I4ae690b55c4610ee987b4035453aabea27f6f480 --- .../bluetooth/BluetoothManagerService.java | 555 +++--------------- .../server/bluetooth/BluetoothService.kt | 2 +- .../bluetooth/BluetoothServiceBinder.java | 371 ++++++++++++ .../bluetooth/BluetoothShellCommand.java | 10 +- .../server/bluetooth/BtPermissionUtils.java | 357 +++++++++++ service/tests/Android.bp | 2 + .../bluetooth/BluetoothServiceBinderTest.java | 481 +++++++++++++++ .../bluetooth/BluetoothShellCommandTest.java | 20 +- 8 files changed, 1309 insertions(+), 489 deletions(-) create mode 100644 service/src/com/android/server/bluetooth/BluetoothServiceBinder.java create mode 100644 service/src/com/android/server/bluetooth/BtPermissionUtils.java create mode 100644 service/tests/src/com/android/server/bluetooth/BluetoothServiceBinderTest.java diff --git a/service/src/com/android/server/bluetooth/BluetoothManagerService.java b/service/src/com/android/server/bluetooth/BluetoothManagerService.java index f237c53264b..a5e159c66aa 100644 --- a/service/src/com/android/server/bluetooth/BluetoothManagerService.java +++ b/service/src/com/android/server/bluetooth/BluetoothManagerService.java @@ -16,10 +16,7 @@ package com.android.server.bluetooth; -import static android.Manifest.permission.BLUETOOTH_CONNECT; import static android.os.PowerExemptionManager.TEMPORARY_ALLOW_LIST_TYPE_FOREGROUND_SERVICE_ALLOWED; -import static android.permission.PermissionManager.PERMISSION_GRANTED; -import static android.permission.PermissionManager.PERMISSION_HARD_DENIED; import static com.android.server.bluetooth.BluetoothAirplaneModeListener.APM_BT_ENABLED_NOTIFICATION; import static com.android.server.bluetooth.BluetoothAirplaneModeListener.APM_ENHANCEMENT; @@ -27,17 +24,14 @@ import static com.android.server.bluetooth.BluetoothAirplaneModeListener.APM_USE import static com.android.server.bluetooth.BluetoothAirplaneModeListener.BLUETOOTH_APM_STATE; import static com.android.server.bluetooth.BluetoothAirplaneModeListener.NOTIFICATION_NOT_SHOWN; import static com.android.server.bluetooth.BluetoothAirplaneModeListener.USED; -import static com.android.server.bluetooth.ChangeIds.RESTRICT_ENABLE_DISABLE; -import android.Manifest; +import static java.util.Objects.requireNonNull; + import android.annotation.NonNull; import android.annotation.RequiresPermission; import android.annotation.SuppressLint; import android.app.ActivityManager; -import android.app.AppOpsManager; import android.app.BroadcastOptions; -import android.app.admin.DevicePolicyManager; -import android.app.compat.CompatChanges; import android.bluetooth.BluetoothA2dp; import android.bluetooth.BluetoothAdapter; import android.bluetooth.BluetoothHearingAid; @@ -73,7 +67,6 @@ import android.os.HandlerThread; import android.os.IBinder; import android.os.Looper; import android.os.Message; -import android.os.ParcelFileDescriptor; import android.os.PowerExemptionManager; import android.os.Process; import android.os.RemoteCallbackList; @@ -82,13 +75,11 @@ import android.os.SystemClock; import android.os.SystemProperties; import android.os.UserHandle; import android.os.UserManager; -import android.permission.PermissionManager; import android.provider.Settings; import android.provider.Settings.SettingNotFoundException; import android.sysprop.BluetoothProperties; import android.text.TextUtils; import android.util.Log; -import android.util.Pair; import android.util.proto.ProtoOutputStream; import com.android.internal.annotations.GuardedBy; @@ -115,7 +106,7 @@ import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.TimeoutException; import java.util.concurrent.locks.ReentrantReadWriteLock; -public class BluetoothManagerService extends IBluetoothManager.Stub { +class BluetoothManagerService { private static final String TAG = "BluetoothManagerService"; private static final boolean DBG = true; @@ -216,6 +207,7 @@ public class BluetoothManagerService extends IBluetoothManager.Stub { private final RemoteCallbackList mCallbacks; private final RemoteCallbackList mStateChangeCallbacks; private IBinder mBluetoothBinder; + private final BluetoothServiceBinder mBinder; private final ReentrantReadWriteLock mBluetoothLock = new ReentrantReadWriteLock(); @GuardedBy("mBluetoothLock") @@ -246,9 +238,7 @@ public class BluetoothManagerService extends IBluetoothManager.Stub { .format(Instant.ofEpochMilli(timestamp)); } - /** - * Used for tracking apps that enabled / disabled Bluetooth. - */ + // Used for tracking apps that enabled / disabled Bluetooth. private class ActiveLog { private int mReason; private String mPackageName; @@ -293,15 +283,13 @@ public class BluetoothManagerService extends IBluetoothManager.Stub { private final HandlerThread mBluetoothHandlerThread; private final BluetoothHandler mHandler; private int mErrorRecoveryRetryCounter; - private final int mSystemUiUid; private boolean mIsHearingAidProfileSupported; - private AppOpsManager mAppOps; - // Save a ProfileServiceConnections object for each of the bound // bluetooth profile services private final Map mProfileServices = new HashMap<>(); + @GuardedBy("mProfileServices") private boolean mUnbindingAll = false; @@ -338,10 +326,7 @@ public class BluetoothManagerService extends IBluetoothManager.Stub { // TODO(b/265386284) } - public boolean onFactoryReset(AttributionSource attributionSource) { - mContext.enforceCallingOrSelfPermission(BLUETOOTH_PRIVILEGED, - "Need BLUETOOTH_PRIVILEGED permission"); - + boolean onFactoryReset(AttributionSource source) { // Wait for stable state if bluetooth is temporary state. int state = getState(); if (state == BluetoothAdapter.STATE_BLE_TURNING_ON @@ -364,13 +349,13 @@ public class BluetoothManagerService extends IBluetoothManager.Stub { addActiveLog( BluetoothProtoEnums.ENABLE_DISABLE_REASON_FACTORY_RESET, mContext.getPackageName(), false); - synchronousOnBrEdrDown(attributionSource); + synchronousOnBrEdrDown(source); return true; } else if (state == BluetoothAdapter.STATE_ON) { addActiveLog( BluetoothProtoEnums.ENABLE_DISABLE_REASON_FACTORY_RESET, mContext.getPackageName(), false); - synchronousDisable(attributionSource); + synchronousDisable(source); return true; } } catch (RemoteException | TimeoutException e) { @@ -613,6 +598,13 @@ public class BluetoothManagerService extends IBluetoothManager.Stub { }; BluetoothManagerService(Context context) { + mContext = context; + mUserManager = + requireNonNull( + mContext.getSystemService(UserManager.class), + "UserManager system service cannot be null"); + + mBinder = new BluetoothServiceBinder(this, context, mUserManager); mBluetoothHandlerThread = BluetoothServerProxy.getInstance() .createHandlerThread("BluetoothManagerService"); mBluetoothHandlerThread.start(); @@ -620,8 +612,6 @@ public class BluetoothManagerService extends IBluetoothManager.Stub { mHandler = BluetoothServerProxy.getInstance().newBluetoothHandler( new BluetoothHandler(mBluetoothHandlerThread.getLooper())); - mContext = context; - mCrashes = 0; mBluetooth = null; mBluetoothBinder = null; @@ -642,8 +632,6 @@ public class BluetoothManagerService extends IBluetoothManager.Stub { mCallbacks = new RemoteCallbackList(); mStateChangeCallbacks = new RemoteCallbackList(); - mUserManager = mContext.getSystemService(UserManager.class); - mBluetoothNotificationManager = new BluetoothNotificationManager(mContext); // Disable ASHA if BLE is not supported, overriding any system property @@ -722,23 +710,14 @@ public class BluetoothManagerService extends IBluetoothManager.Stub { mBluetoothNotificationManager); } - int systemUiUid = -1; - // Check if device is configured with no home screen, which implies no SystemUI. - try { - systemUiUid = mContext.createContextAsUser(UserHandle.SYSTEM, 0) - .getPackageManager() - .getPackageUid("com.android.systemui", - PackageManager.PackageInfoFlags.of(PackageManager.MATCH_SYSTEM_ONLY)); - Log.d(TAG, "Detected SystemUiUid: " + Integer.toString(systemUiUid)); - } catch (PackageManager.NameNotFoundException e) { - Log.w(TAG, "Unable to resolve SystemUI's UID."); - } - mSystemUiUid = systemUiUid; - mBluetoothSatelliteModeListener = new BluetoothSatelliteModeListener( this, mBluetoothHandlerThread.getLooper(), context); } + IBluetoothManager.Stub getBinder() { + return mBinder; + } + /** * Returns true if airplane mode is currently on */ @@ -942,48 +921,28 @@ public class BluetoothManagerService extends IBluetoothManager.Stub { } } - public IBluetooth registerAdapter(IBluetoothManagerCallback callback) { - if (callback == null) { - Log.w(TAG, "Callback is null in registerAdapter"); - return null; - } + IBluetooth registerAdapter(IBluetoothManagerCallback callback) { synchronized (mCallbacks) { mCallbacks.register(callback); } return mBluetooth; } - public void unregisterAdapter(IBluetoothManagerCallback callback) { - if (callback == null) { - Log.w(TAG, "Callback is null in unregisterAdapter"); - return; - } + void unregisterAdapter(IBluetoothManagerCallback callback) { synchronized (mCallbacks) { mCallbacks.unregister(callback); } } - public void registerStateChangeCallback(IBluetoothStateChangeCallback callback) { - if (callback == null) { - Log.w(TAG, "registerStateChangeCallback: Callback is null!"); - return; - } - Message msg = mHandler.obtainMessage(MESSAGE_REGISTER_STATE_CHANGE_CALLBACK); - msg.obj = callback; - mHandler.sendMessage(msg); + void registerStateChangeCallback(IBluetoothStateChangeCallback callback) { + mHandler.obtainMessage(MESSAGE_REGISTER_STATE_CHANGE_CALLBACK, callback).sendToTarget(); } - public void unregisterStateChangeCallback(IBluetoothStateChangeCallback callback) { - if (callback == null) { - Log.w(TAG, "unregisterStateChangeCallback: Callback is null!"); - return; - } - Message msg = mHandler.obtainMessage(MESSAGE_UNREGISTER_STATE_CHANGE_CALLBACK); - msg.obj = callback; - mHandler.sendMessage(msg); + void unregisterStateChangeCallback(IBluetoothStateChangeCallback callback) { + mHandler.obtainMessage(MESSAGE_UNREGISTER_STATE_CHANGE_CALLBACK, callback).sendToTarget(); } - public boolean isEnabled() { + boolean isEnabled() { return getState() == BluetoothAdapter.STATE_ON; } @@ -1106,12 +1065,7 @@ public class BluetoothManagerService extends IBluetoothManager.Stub { } } - public int getState() { - if (!isCallerSystem(getCallingAppId()) && !checkIfCallerIsForegroundUser()) { - Log.w(TAG, "getState(): report OFF for non-active and non system user"); - return BluetoothAdapter.STATE_OFF; - } - + int getState() { mBluetoothLock.readLock().lock(); try { if (mBluetooth != null) { @@ -1152,8 +1106,7 @@ public class BluetoothManagerService extends IBluetoothManager.Stub { } } - @Override - public boolean isBleScanAlwaysAvailable() { + boolean isBleScanAlwaysAvailable() { if (isAirplaneModeOn() && !mEnable) { return false; } @@ -1165,8 +1118,7 @@ public class BluetoothManagerService extends IBluetoothManager.Stub { return false; } - @Override - public boolean isHearingAidProfileSupported() { + boolean isHearingAidProfileSupported() { return mIsHearingAidProfileSupported; } @@ -1275,41 +1227,14 @@ public class BluetoothManagerService extends IBluetoothManager.Stub { return appCount; } - @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT) - private boolean checkBluetoothPermissions(AttributionSource attributionSource, String message, - boolean requireForeground) { - if (isBluetoothDisallowed()) { - if (DBG) { - Log.d(TAG, "checkBluetoothPermissions: bluetooth disallowed"); - } + boolean enableBle(String packageName, IBinder token) { + if (isAirplaneModeOn()) { + Log.d(TAG, "enableBle(): not enabling - airplaneMode is on"); return false; } - int callingAppId = getCallingAppId(); - if (!isCallerSystem(callingAppId) - && !isCallerShell(callingAppId) - && !isCallerRoot(callingAppId)) { - checkPackage(attributionSource.getPackageName()); - - if (requireForeground && !checkIfCallerIsForegroundUser()) { - Log.w(TAG, "Not allowed for non-active and non system user"); - return false; - } - - if (!checkConnectPermissionForDataDelivery(mContext, attributionSource, message)) { - return false; - } - } - return true; - } - public boolean enableBle(AttributionSource attributionSource, IBinder token) - throws RemoteException { - final String packageName = attributionSource.getPackageName(); - if (!checkBluetoothPermissions(attributionSource, "enableBle", false) - || isAirplaneModeOn()) { - if (DBG) { - Log.d(TAG, "enableBle(): bluetooth disallowed"); - } + if (isSatelliteModeOn()) { + Log.d(TAG, "enableBle(): not enabling - satellite mode is on."); return false; } @@ -1319,11 +1244,6 @@ public class BluetoothManagerService extends IBluetoothManager.Stub { + BluetoothAdapter.nameForState(mState)); } - if (isSatelliteModeOn()) { - Log.d(TAG, "enableBle(): not enabling - satellite mode is on."); - return false; - } - updateBleAppCount(token, true, packageName); if (mState == BluetoothAdapter.STATE_ON @@ -1342,17 +1262,7 @@ public class BluetoothManagerService extends IBluetoothManager.Stub { return true; } - @RequiresPermission(android.Manifest.permission.BLUETOOTH_PRIVILEGED) - public boolean disableBle(AttributionSource attributionSource, IBinder token) - throws RemoteException { - final String packageName = attributionSource.getPackageName(); - if (!checkBluetoothPermissions(attributionSource, "disableBle", false)) { - if (DBG) { - Log.d(TAG, "disableBLE(): bluetooth disallowed"); - } - return false; - } - + boolean disableBle(AttributionSource source, String packageName, IBinder token) { if (DBG) { Log.d(TAG, "disableBle(" + packageName + "): mBluetooth =" + mBluetooth + " mBinding = " + mBinding + " mState = " @@ -1377,7 +1287,7 @@ public class BluetoothManagerService extends IBluetoothManager.Stub { if (!mEnableExternal) { addActiveLog(BluetoothProtoEnums.ENABLE_DISABLE_REASON_APPLICATION_REQUEST, packageName, false); - sendBrEdrDownCallback(attributionSource); + sendBrEdrDownCallback(source); } } return true; @@ -1388,8 +1298,7 @@ public class BluetoothManagerService extends IBluetoothManager.Stub { mBleApps.clear(); } - /** @hide */ - public boolean isBleAppPresent() { + boolean isBleAppPresent() { if (DBG) { Log.d(TAG, "isBleAppPresent() count: " + mBleApps.size()); } @@ -1430,14 +1339,15 @@ public class BluetoothManagerService extends IBluetoothManager.Stub { } /** - * Inform BluetoothAdapter instances that BREDR part is down - * and turn off all service and stack if no LE app needs it + * Inform BluetoothAdapter instances that BREDR part is down and turn off all service and stack + * if no LE app needs it */ - @RequiresPermission(allOf = { - android.Manifest.permission.BLUETOOTH_CONNECT, - android.Manifest.permission.BLUETOOTH_PRIVILEGED, - }) - private void sendBrEdrDownCallback(AttributionSource attributionSource) { + @RequiresPermission( + allOf = { + android.Manifest.permission.BLUETOOTH_CONNECT, + android.Manifest.permission.BLUETOOTH_PRIVILEGED, + }) + private void sendBrEdrDownCallback(AttributionSource source) { if (DBG) { Log.d(TAG, "Calling sendBrEdrDownCallback callbacks"); } @@ -1451,7 +1361,7 @@ public class BluetoothManagerService extends IBluetoothManager.Stub { // Need to stay at BLE ON. Disconnect all Gatt connections try { final SynchronousResultReceiver recv = SynchronousResultReceiver.get(); - mBluetoothGatt.unregAll(attributionSource, recv); + mBluetoothGatt.unregAll(source, recv); recv.awaitResultNoInterrupt(getSyncTimeout()).getValue(null); } catch (RemoteException | TimeoutException e) { Log.e(TAG, "Unable to disconnect all apps.", e); @@ -1460,7 +1370,7 @@ public class BluetoothManagerService extends IBluetoothManager.Stub { mBluetoothLock.readLock().lock(); try { if (mBluetooth != null) { - synchronousOnBrEdrDown(attributionSource); + synchronousOnBrEdrDown(source); } } catch (RemoteException | TimeoutException e) { Log.e(TAG, "Call to onBrEdrDown() failed.", e); @@ -1468,28 +1378,9 @@ public class BluetoothManagerService extends IBluetoothManager.Stub { mBluetoothLock.readLock().unlock(); } } - } - public boolean enableNoAutoConnect(AttributionSource attributionSource) { - final String packageName = attributionSource.getPackageName(); - if (!checkBluetoothPermissions(attributionSource, "enableNoAutoConnect", false)) { - if (DBG) { - Log.d(TAG, "enableNoAutoConnect(): not enabling - bluetooth disallowed"); - } - return false; - } - - if (DBG) { - Log.d(TAG, "enableNoAutoConnect(): mBluetooth =" + mBluetooth + " mBinding = " - + mBinding); - } - - int callingAppId = UserHandle.getAppId(Binder.getCallingUid()); - if (callingAppId != Process.NFC_UID) { - throw new SecurityException("no permission to enable Bluetooth quietly"); - } - + boolean enableNoAutoConnect(String packageName) { if (isSatelliteModeOn()) { Log.d(TAG, "enableNoAutoConnect(): not enabling - satellite mode is on."); return false; @@ -1504,27 +1395,7 @@ public class BluetoothManagerService extends IBluetoothManager.Stub { return true; } - public boolean enable(AttributionSource attributionSource) throws RemoteException { - final String packageName = attributionSource.getPackageName(); - if (!checkBluetoothPermissions(attributionSource, "enable", true)) { - if (DBG) { - Log.d(TAG, "enable(): not enabling - bluetooth disallowed"); - } - return false; - } - - final int callingUid = Binder.getCallingUid(); - final int callingPid = Binder.getCallingPid(); - if (CompatChanges.isChangeEnabled(RESTRICT_ENABLE_DISABLE, callingUid) - && !isPrivileged(callingPid, callingUid) - && !isSystem(packageName, callingUid) - && !isDeviceOwner(callingUid, packageName) - && !isProfileOwner(callingUid, packageName)) { - Log.d(TAG, "enable(): not enabling - Caller is not one of: " - + "privileged | system | deviceOwner | profileOwner"); - return false; - } - + boolean enable(String packageName) { if (isSatelliteModeOn()) { Log.d(TAG, "enable(): not enabling - satellite mode is on."); return false; @@ -1568,33 +1439,7 @@ public class BluetoothManagerService extends IBluetoothManager.Stub { return true; } - public boolean disable(AttributionSource attributionSource, boolean persist) - throws RemoteException { - if (!persist) { - mContext.enforceCallingOrSelfPermission(BLUETOOTH_PRIVILEGED, - "Need BLUETOOTH_PRIVILEGED permission"); - } - - final String packageName = attributionSource.getPackageName(); - if (!checkBluetoothPermissions(attributionSource, "disable", true)) { - if (DBG) { - Log.d(TAG, "disable(): not disabling - bluetooth disallowed"); - } - return false; - } - - final int callingUid = Binder.getCallingUid(); - final int callingPid = Binder.getCallingPid(); - if (CompatChanges.isChangeEnabled(RESTRICT_ENABLE_DISABLE, callingUid) - && !isPrivileged(callingPid, callingUid) - && !isSystem(packageName, callingUid) - && !isDeviceOwner(callingUid, packageName) - && !isProfileOwner(callingUid, packageName)) { - Log.d(TAG, "disable(): not disabling - Caller is not one of: " - + "privileged | system | deviceOwner | profileOwner"); - return false; - } - + boolean disable(String packageName, boolean persist) { if (isSatelliteModeOn()) { Log.d(TAG, "disable: not disabling - satellite mode is on."); return false; @@ -1624,52 +1469,8 @@ public class BluetoothManagerService extends IBluetoothManager.Stub { return true; } - /** - * Check if AppOpsManager is available and the packageName belongs to calling uid - * - * A null package belongs to any uid - */ - private void checkPackage(String packageName) { - int callingUid = Binder.getCallingUid(); - - if (mAppOps == null) { - Log.w(TAG, "checkPackage(): called before system boot up, uid " - + callingUid + ", packageName " + packageName); - throw new IllegalStateException("System has not boot yet"); - } - if (packageName == null) { - Log.w(TAG, "checkPackage(): called with null packageName from " + callingUid); - return; - } - - try { - mAppOps.checkPackage(callingUid, packageName); - } catch (SecurityException e) { - Log.w(TAG, "checkPackage(): " + packageName + " does not belong to uid " + callingUid); - throw new SecurityException(e.getMessage()); - } - } - - /** - * Check if the caller must still pass permission check or if the caller is exempted - * from the consent UI via the MANAGE_BLUETOOTH_WHEN_WIRELESS_CONSENT_REQUIRED check. - * - * Commands from some callers may be exempted from triggering the consent UI when - * enabling bluetooth. This exemption is checked via the - * MANAGE_BLUETOOTH_WHEN_WIRELESS_CONSENT_REQUIRED and allows calls to skip - * the consent UI where it may otherwise be required. - * - * @hide - */ - @SuppressLint("AndroidFrameworkRequiresPermission") - private boolean checkBluetoothPermissionWhenWirelessConsentRequired() { - int result = mContext.checkCallingPermission( - android.Manifest.permission.MANAGE_BLUETOOTH_WHEN_WIRELESS_CONSENT_REQUIRED); - return result == PackageManager.PERMISSION_GRANTED; - } - @RequiresPermission(android.Manifest.permission.BLUETOOTH_PRIVILEGED) - public void unbindAndFinish() { + void unbindAndFinish() { if (DBG) { Log.d(TAG, "unbindAndFinish(): " + mBluetooth + " mBinding = " + mBinding + " mUnbinding = " + mUnbinding); @@ -1705,14 +1506,13 @@ public class BluetoothManagerService extends IBluetoothManager.Stub { } } - public IBluetoothGatt getBluetoothGatt() { + IBluetoothGatt getBluetoothGatt() { // sync protection return mBluetoothGatt; } - @Override - public boolean bindBluetoothProfileService(int bluetoothProfile, String serviceName, - IBluetoothProfileServiceConnection proxy) { + boolean bindBluetoothProfileService( + int bluetoothProfile, String serviceName, IBluetoothProfileServiceConnection proxy) { if (mState != BluetoothAdapter.STATE_ON) { if (DBG) { Log.d(TAG, "Trying to bind to profile: " + bluetoothProfile @@ -1750,9 +1550,8 @@ public class BluetoothManagerService extends IBluetoothManager.Stub { return true; } - @Override - public void unbindBluetoothProfileService(int bluetoothProfile, - IBluetoothProfileServiceConnection proxy) { + void unbindBluetoothProfileService( + int bluetoothProfile, IBluetoothProfileServiceConnection proxy) { synchronized (mProfileServices) { Integer profile = new Integer(bluetoothProfile); ProfileServiceConnections psc = mProfileServices.get(profile); @@ -1761,7 +1560,7 @@ public class BluetoothManagerService extends IBluetoothManager.Stub { } psc.removeProxy(proxy); if (psc.isEmpty()) { - // All prxoies are disconnected, unbind with the service. + // All proxies are disconnected, unbind with the service. try { mContext.unbindService(psc); } catch (IllegalArgumentException e) { @@ -1795,11 +1594,10 @@ public class BluetoothManagerService extends IBluetoothManager.Stub { * Send enable message and set adapter name and address. Called when the boot phase becomes * PHASE_SYSTEM_SERVICES_READY. */ - public void handleOnBootPhase() { + void handleOnBootPhase() { if (DBG) { Log.d(TAG, "Bluetooth boot completed"); } - mAppOps = mContext.getSystemService(AppOpsManager.class); final boolean isBluetoothDisallowed = isBluetoothDisallowed(); if (isBluetoothDisallowed) { return; @@ -1869,10 +1667,8 @@ public class BluetoothManagerService extends IBluetoothManager.Stub { mHandler.obtainMessage(MESSAGE_USER_SWITCHED, userHandle.getIdentifier(), 0).sendToTarget(); } - /** - * Called when user is unlocked. - */ - public void handleOnUnlockUser(UserHandle userHandle) { + /** Called when user is unlocked. */ + void handleOnUnlockUser(UserHandle userHandle) { if (DBG) { Log.d(TAG, "User " + userHandle + " unlocked"); } @@ -2104,25 +1900,11 @@ public class BluetoothManagerService extends IBluetoothManager.Stub { } } - public String getAddress(AttributionSource attributionSource) { - if (!checkConnectPermissionForDataDelivery(mContext, attributionSource, "getAddress")) { - return null; - } - - if (!isCallerSystem(getCallingAppId()) && !checkIfCallerIsForegroundUser()) { - Log.w(TAG, "getAddress(): not allowed for non-active and non system user"); - return null; - } - - if (mContext.checkCallingOrSelfPermission(Manifest.permission.LOCAL_MAC_ADDRESS) - != PackageManager.PERMISSION_GRANTED) { - return BluetoothAdapter.DEFAULT_MAC_ADDRESS; - } - + String getAddress(AttributionSource source) { mBluetoothLock.readLock().lock(); try { if (mBluetooth != null) { - return synchronousGetAddress(attributionSource); + return synchronousGetAddress(source); } } catch (RemoteException | TimeoutException e) { Log.e(TAG, @@ -2138,20 +1920,11 @@ public class BluetoothManagerService extends IBluetoothManager.Stub { return mAddress; } - public String getName(AttributionSource attributionSource) { - if (!checkConnectPermissionForDataDelivery(mContext, attributionSource, "getName")) { - return null; - } - - if (!isCallerSystem(getCallingAppId()) && !checkIfCallerIsForegroundUser()) { - Log.w(TAG, "getName(): not allowed for non-active and non system user"); - return null; - } - + String getName(AttributionSource source) { mBluetoothLock.readLock().lock(); try { if (mBluetooth != null) { - return synchronousGetName(attributionSource); + return synchronousGetName(source); } } catch (RemoteException | TimeoutException e) { Log.e(TAG, "getName(): Unable to retrieve name remotely. Returning cached name", e); @@ -2884,7 +2657,7 @@ public class BluetoothManagerService extends IBluetoothManager.Stub { } boolean doBind(Intent intent, ServiceConnection conn, int flags, UserHandle user) { - ComponentName comp = resolveSystemService(intent, mContext.getPackageManager(), 0); + ComponentName comp = resolveSystemService(intent); intent.setComponent(comp); if (comp == null || !mContext.bindServiceAsUser(intent, conn, flags, user)) { Log.e(TAG, "Fail to bind to: " + intent); @@ -2912,44 +2685,6 @@ public class BluetoothManagerService extends IBluetoothManager.Stub { } } - private static int getCallingAppId() { - return UserHandle.getAppId(Binder.getCallingUid()); - } - private static boolean isCallerSystem(int callingAppId) { - return callingAppId == Process.SYSTEM_UID; - } - private static boolean isCallerShell(int callingAppId) { - return callingAppId == Process.SHELL_UID; - } - private static boolean isCallerRoot(int callingAppId) { - return callingAppId == Process.ROOT_UID; - } - - private boolean checkIfCallerIsForegroundUser() { - int callingUid = Binder.getCallingUid(); - UserHandle callingUser = UserHandle.getUserHandleForUid(callingUid); - final long callingIdentity = Binder.clearCallingIdentity(); - UserManager userManager = mContext.getSystemService(UserManager.class); - UserHandle uh = userManager.getProfileParent(callingUser); - UserHandle parentUser = (uh != null) ? uh : USER_HANDLE_NULL; - int callingAppId = UserHandle.getAppId(callingUid); - boolean valid = false; - try { - UserHandle foregroundUser = UserHandle.of(ActivityManager.getCurrentUser()); - valid = (callingUser == foregroundUser) || parentUser == foregroundUser - || callingAppId == Process.NFC_UID || callingAppId == mSystemUiUid - || callingAppId == Process.SHELL_UID; - if (DBG && !valid) { - Log.d(TAG, "checkIfCallerIsForegroundUser: valid=" + valid + " callingUser=" - + callingUser + " parentUser=" + parentUser + " foregroundUser=" - + foregroundUser); - } - } finally { - Binder.restoreCallingIdentity(callingIdentity); - } - return valid; - } - private void sendBleStateChanged(int prevState, int newState) { if (DBG) { Log.d(TAG, @@ -3305,12 +3040,7 @@ public class BluetoothManagerService extends IBluetoothManager.Stub { return (mErrorRecoveryRetryCounter + 1) * SERVICE_RESTART_TIME_MS; } - @Override - public void dump(FileDescriptor fd, PrintWriter writer, String[] args) { - if ((mContext.checkCallingOrSelfPermission( - android.Manifest.permission.DUMP) != PackageManager.PERMISSION_GRANTED)) { - return; - } + void dump(FileDescriptor fd, PrintWriter writer, String[] args) { if ((args.length > 0) && args[0].startsWith("--proto")) { dumpProto(fd); return; @@ -3444,56 +3174,6 @@ public class BluetoothManagerService extends IBluetoothManager.Stub { } } - @SuppressLint("AndroidFrameworkRequiresPermission") - private static boolean checkPermissionForDataDelivery(Context context, String permission, - AttributionSource attributionSource, String message) { - PermissionManager pm = context.getSystemService(PermissionManager.class); - if (pm == null) { - return false; - } - AttributionSource currentAttribution = new AttributionSource - .Builder(context.getAttributionSource()) - .setNext(attributionSource) - .build(); - final int result = pm.checkPermissionForDataDeliveryFromDataSource(permission, - currentAttribution, message); - if (result == PERMISSION_GRANTED) { - return true; - } - - final String msg = "Need " + permission + " permission for " + attributionSource + ": " - + message; - if (result == PERMISSION_HARD_DENIED) { - throw new SecurityException(msg); - } else { - Log.w(TAG, msg); - return false; - } - } - - /** - * Returns true if the BLUETOOTH_CONNECT permission is granted for the calling app. Returns - * false if the result is a soft denial. Throws SecurityException if the result is a hard - * denial. - * - *

Should be used in situations where the app op should not be noted. - */ - @SuppressLint("AndroidFrameworkRequiresPermission") - @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT) - public static boolean checkConnectPermissionForDataDelivery( - Context context, AttributionSource attributionSource, String message) { - return checkPermissionForDataDelivery(context, BLUETOOTH_CONNECT, - attributionSource, message); - } - - @Override - public int handleShellCommand(@NonNull ParcelFileDescriptor in, - @NonNull ParcelFileDescriptor out, @NonNull ParcelFileDescriptor err, - @NonNull String[] args) { - return new BluetoothShellCommand(this, mContext).exec(this, in.getFileDescriptor(), - out.getFileDescriptor(), err.getFileDescriptor(), args); - } - // TODO(b/193460475): Remove when tooling supports SystemApi to public API. @SuppressLint("NewApi") static @NonNull Bundle getTempAllowlistBroadcastOptions() { @@ -3505,9 +3185,8 @@ public class BluetoothManagerService extends IBluetoothManager.Stub { return bOptions.toBundle(); } - private ComponentName resolveSystemService(@NonNull Intent intent, - @NonNull PackageManager pm, int flags) { - List results = pm.queryIntentServices(intent, flags); + private ComponentName resolveSystemService(@NonNull Intent intent) { + List results = mContext.getPackageManager().queryIntentServices(intent, 0); if (results == null) { return null; } @@ -3528,91 +3207,7 @@ public class BluetoothManagerService extends IBluetoothManager.Stub { return comp; } - private boolean isPrivileged(int pid, int uid) { - return (mContext.checkPermission(android.Manifest.permission.BLUETOOTH_PRIVILEGED, pid, uid) - == PackageManager.PERMISSION_GRANTED) - || (mContext.getPackageManager().checkSignatures(uid, Process.SYSTEM_UID) - == PackageManager.SIGNATURE_MATCH); - } - - private Pair getDeviceOwner() { - DevicePolicyManager devicePolicyManager = - mContext.getSystemService(DevicePolicyManager.class); - if (devicePolicyManager == null) return null; - long ident = Binder.clearCallingIdentity(); - UserHandle deviceOwnerUser = null; - ComponentName deviceOwnerComponent = null; - try { - deviceOwnerUser = devicePolicyManager.getDeviceOwnerUser(); - deviceOwnerComponent = devicePolicyManager.getDeviceOwnerComponentOnAnyUser(); - } finally { - Binder.restoreCallingIdentity(ident); - } - if (deviceOwnerUser == null || deviceOwnerComponent == null - || deviceOwnerComponent.getPackageName() == null) { - return null; - } - return new Pair<>(deviceOwnerUser, deviceOwnerComponent); - } - - private boolean isDeviceOwner(int uid, String packageName) { - if (packageName == null) { - Log.e(TAG, "isDeviceOwner: packageName is null, returning false"); - return false; - } - - Pair deviceOwner = getDeviceOwner(); - - // no device owner - if (deviceOwner == null) return false; - - return deviceOwner.first.equals(UserHandle.getUserHandleForUid(uid)) - && deviceOwner.second.getPackageName().equals(packageName); - } - - private boolean isProfileOwner(int uid, String packageName) { - Context userContext; - try { - userContext = mContext.createPackageContextAsUser(mContext.getPackageName(), 0, - UserHandle.getUserHandleForUid(uid)); - } catch (PackageManager.NameNotFoundException e) { - Log.e(TAG, "Unknown package name"); - return false; - } - if (userContext == null) { - Log.e(TAG, "Unable to retrieve user context for " + uid); - return false; - } - DevicePolicyManager devicePolicyManager = - userContext.getSystemService(DevicePolicyManager.class); - if (devicePolicyManager == null) { - Log.w(TAG, "Error retrieving DPM service"); - return false; - } - return devicePolicyManager.isProfileOwnerApp(packageName); - } - - public boolean isSystem(String packageName, int uid) { - long ident = Binder.clearCallingIdentity(); - try { - ApplicationInfo info = mContext.getPackageManager().getApplicationInfoAsUser( - packageName, 0, UserHandle.getUserHandleForUid(uid)); - return (info.flags & FLAGS_SYSTEM_APP) != 0; - } catch (PackageManager.NameNotFoundException e) { - return false; - } finally { - Binder.restoreCallingIdentity(ident); - } - } - - /** - * Sets Bluetooth HCI snoop log mode - */ - @RequiresPermission(android.Manifest.permission.BLUETOOTH_PRIVILEGED) - @Override - public int setBtHciSnoopLogMode(int mode) { - mContext.enforceCallingOrSelfPermission(BLUETOOTH_PRIVILEGED, - "Need BLUETOOTH_PRIVILEGED permission"); + int setBtHciSnoopLogMode(int mode) { final BluetoothProperties.snoop_log_mode_values snoopMode; switch (mode) { @@ -3638,14 +3233,7 @@ public class BluetoothManagerService extends IBluetoothManager.Stub { return BluetoothStatusCodes.SUCCESS; } - /** - * Gets Bluetooth HCI snoop log mode - */ - @RequiresPermission(android.Manifest.permission.BLUETOOTH_PRIVILEGED) - @Override - public int getBtHciSnoopLogMode() { - mContext.enforceCallingOrSelfPermission(BLUETOOTH_PRIVILEGED, - "Need BLUETOOTH_PRIVILEGED permission"); + int getBtHciSnoopLogMode() { BluetoothProperties.snoop_log_mode_values mode = BluetoothProperties.snoop_log_mode() .orElse(BluetoothProperties.snoop_log_mode_values.DISABLED); if (mode == BluetoothProperties.snoop_log_mode_values.FILTERED) { @@ -3694,4 +3282,3 @@ public class BluetoothManagerService extends IBluetoothManager.Stub { || pm.hasSystemFeature(PackageManager.FEATURE_LEANBACK); } } - diff --git a/service/src/com/android/server/bluetooth/BluetoothService.kt b/service/src/com/android/server/bluetooth/BluetoothService.kt index 10c822b4154..6af0e7df6a1 100644 --- a/service/src/com/android/server/bluetooth/BluetoothService.kt +++ b/service/src/com/android/server/bluetooth/BluetoothService.kt @@ -38,7 +38,7 @@ class BluetoothService(context: Context) : SystemService(context) { if (phase == SystemService.PHASE_SYSTEM_SERVICES_READY) { publishBinderService( BluetoothAdapter.BLUETOOTH_MANAGER_SERVICE, - mBluetoothManagerService + mBluetoothManagerService.getBinder() ) } } diff --git a/service/src/com/android/server/bluetooth/BluetoothServiceBinder.java b/service/src/com/android/server/bluetooth/BluetoothServiceBinder.java new file mode 100644 index 00000000000..8e514d0a27a --- /dev/null +++ b/service/src/com/android/server/bluetooth/BluetoothServiceBinder.java @@ -0,0 +1,371 @@ +/* + * Copyright 2023 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.server.bluetooth; + +import static android.Manifest.permission.BLUETOOTH_CONNECT; +import static android.Manifest.permission.BLUETOOTH_PRIVILEGED; +import static android.Manifest.permission.DUMP; +import static android.Manifest.permission.LOCAL_MAC_ADDRESS; +import static android.content.pm.PackageManager.PERMISSION_GRANTED; + +import static com.android.server.bluetooth.BtPermissionUtils.checkConnectPermissionForDataDelivery; +import static com.android.server.bluetooth.BtPermissionUtils.getCallingAppId; +import static com.android.server.bluetooth.BtPermissionUtils.isCallerSystem; + +import static java.util.Objects.requireNonNull; + +import android.annotation.NonNull; +import android.annotation.Nullable; +import android.annotation.RequiresPermission; +import android.app.AppOpsManager; +import android.bluetooth.BluetoothAdapter; +import android.bluetooth.IBluetooth; +import android.bluetooth.IBluetoothGatt; +import android.bluetooth.IBluetoothManager; +import android.bluetooth.IBluetoothManagerCallback; +import android.bluetooth.IBluetoothProfileServiceConnection; +import android.bluetooth.IBluetoothStateChangeCallback; +import android.content.AttributionSource; +import android.content.Context; +import android.os.IBinder; +import android.os.ParcelFileDescriptor; +import android.os.UserManager; +import android.permission.PermissionManager; +import android.util.Log; + +import java.io.FileDescriptor; +import java.io.PrintWriter; + +class BluetoothServiceBinder extends IBluetoothManager.Stub { + private static final String TAG = BluetoothServiceBinder.class.getSimpleName(); + private static final boolean DBG = Log.isLoggable(TAG, Log.DEBUG); + private static final boolean VDBG = Log.isLoggable(TAG, Log.VERBOSE); + + private final BluetoothManagerService mBluetoothManagerService; + private final Context mContext; + private final UserManager mUserManager; + private final AppOpsManager mAppOpsManager; + private final PermissionManager mPermissionManager; + private final BtPermissionUtils mPermissionUtils; + + BluetoothServiceBinder(BluetoothManagerService bms, Context ctx, UserManager userManager) { + mBluetoothManagerService = bms; + mContext = ctx; + mUserManager = userManager; + mAppOpsManager = + requireNonNull( + ctx.getSystemService(AppOpsManager.class), + "AppOpsManager system service cannot be null"); + mPermissionManager = + requireNonNull( + ctx.getSystemService(PermissionManager.class), + "PermissionManager system service cannot be null"); + mPermissionUtils = new BtPermissionUtils(ctx); + } + + @Override + @Nullable + public IBluetooth registerAdapter(@NonNull IBluetoothManagerCallback callback) { + requireNonNull(callback, "Callback cannot be null in registerAdapter"); + return mBluetoothManagerService.registerAdapter(callback); + } + + @Override + public void unregisterAdapter(@NonNull IBluetoothManagerCallback callback) { + requireNonNull(callback, "Callback cannot be null in unregisterAdapter"); + mBluetoothManagerService.unregisterAdapter(callback); + } + + @Override + public void registerStateChangeCallback(@NonNull IBluetoothStateChangeCallback callback) { + requireNonNull(callback, "Callback cannot be null in registerStateChangeCallback"); + mBluetoothManagerService.registerStateChangeCallback(callback); + } + + @Override + public void unregisterStateChangeCallback(@NonNull IBluetoothStateChangeCallback callback) { + requireNonNull(callback, "Callback cannot be null in unregisterStateChangeCallback"); + mBluetoothManagerService.unregisterStateChangeCallback(callback); + } + + @Override + public boolean enable(@NonNull AttributionSource source) { + requireNonNull(source, "AttributionSource cannot be null in enable"); + + final String errorMsg = + mPermissionUtils.callerCanToggle( + mContext, + source, + mUserManager, + mAppOpsManager, + mPermissionManager, + "enable", + true); + if (!errorMsg.isEmpty()) { + Log.d(TAG, "enable(): FAILED: " + errorMsg); + return false; + } + + return mBluetoothManagerService.enable(source.getPackageName()); + } + + @Override + public boolean enableNoAutoConnect(AttributionSource source) { + requireNonNull(source, "AttributionSource cannot be null in enableNoAutoConnect"); + + final String errorMsg = + mPermissionUtils.callerCanToggle( + mContext, + source, + mUserManager, + mAppOpsManager, + mPermissionManager, + "enableNoAutoConnect", + false); + if (!errorMsg.isEmpty()) { + Log.d(TAG, "enableNoAutoConnect(): FAILED: " + errorMsg); + return false; + } + + if (!mPermissionUtils.isCallerNfc(getCallingAppId())) { + throw new SecurityException("No permission to enable Bluetooth quietly"); + } + + return mBluetoothManagerService.enableNoAutoConnect(source.getPackageName()); + } + + @Override + public boolean disable(AttributionSource source, boolean persist) { + requireNonNull(source, "AttributionSource cannot be null in enableNoAutoConnect"); + + if (!persist) { + mPermissionUtils.enforcePrivileged(mContext); + } + + final String errorMsg = + mPermissionUtils.callerCanToggle( + mContext, + source, + mUserManager, + mAppOpsManager, + mPermissionManager, + "disable", + true); + if (!errorMsg.isEmpty()) { + Log.d(TAG, "disable(): FAILED: " + errorMsg); + return false; + } + + return mBluetoothManagerService.disable(source.getPackageName(), persist); + } + + @Override + public int getState() { + if (!isCallerSystem(getCallingAppId()) + && !mPermissionUtils.checkIfCallerIsForegroundUser(mUserManager)) { + Log.w(TAG, "getState(): UNAUTHORIZED. Report OFF for non-active and non system user"); + return BluetoothAdapter.STATE_OFF; + } + + return mBluetoothManagerService.getState(); + } + + @Override + public IBluetoothGatt getBluetoothGatt() { + return mBluetoothManagerService.getBluetoothGatt(); + } + + @Override + public boolean bindBluetoothProfileService( + int bluetoothProfile, String serviceName, IBluetoothProfileServiceConnection proxy) { + requireNonNull( + proxy, + "IBluetoothProfileServiceConnection cannot be null in bindBluetoothProfileService"); + + return mBluetoothManagerService.bindBluetoothProfileService( + bluetoothProfile, serviceName, proxy); + } + + @Override + public void unbindBluetoothProfileService( + int bluetoothProfile, IBluetoothProfileServiceConnection proxy) { + mBluetoothManagerService.unbindBluetoothProfileService(bluetoothProfile, proxy); + } + + @Override + @RequiresPermission(allOf = {BLUETOOTH_CONNECT, LOCAL_MAC_ADDRESS}) + public String getAddress(AttributionSource source) { + requireNonNull(source, "AttributionSource cannot be null in getAddress"); + + if (!checkConnectPermissionForDataDelivery( + mContext, mPermissionManager, source, "getAddress")) { + return null; + } + + if (!isCallerSystem(getCallingAppId()) + && !mPermissionUtils.checkIfCallerIsForegroundUser(mUserManager)) { + Log.w(TAG, "getAddress(): Not allowed for non-active and non system user"); + return null; + } + + if (mContext.checkCallingOrSelfPermission(LOCAL_MAC_ADDRESS) != PERMISSION_GRANTED) { + // TODO(b/280890575): Throws a SecurityException instead + Log.w(TAG, "getAddress(): Client does not have LOCAL_MAC_ADDRESS permission"); + return BluetoothAdapter.DEFAULT_MAC_ADDRESS; + } + + return mBluetoothManagerService.getAddress(source); + } + + @Override + @RequiresPermission(BLUETOOTH_CONNECT) + public String getName(AttributionSource source) { + requireNonNull(source, "AttributionSource cannot be null in getName"); + + if (!checkConnectPermissionForDataDelivery( + mContext, mPermissionManager, source, "getName")) { + return null; + } + + if (!isCallerSystem(getCallingAppId()) + && !mPermissionUtils.checkIfCallerIsForegroundUser(mUserManager)) { + Log.w(TAG, "getName(): not allowed for non-active and non system user"); + return null; + } + + return mBluetoothManagerService.getName(source); + } + + @Override + @RequiresPermission(allOf = {BLUETOOTH_CONNECT, BLUETOOTH_PRIVILEGED}) + public boolean onFactoryReset(AttributionSource source) { + requireNonNull(source, "AttributionSource cannot be null in onFactoryReset"); + + mPermissionUtils.enforcePrivileged(mContext); + + if (!checkConnectPermissionForDataDelivery( + mContext, mPermissionManager, source, "onFactoryReset")) { + return false; + } + + return mBluetoothManagerService.onFactoryReset(source); + } + + @Override + public boolean isBleScanAlwaysAvailable() { + return mBluetoothManagerService.isBleScanAlwaysAvailable(); + } + + @Override + @RequiresPermission(BLUETOOTH_CONNECT) + public boolean enableBle(AttributionSource source, IBinder token) { + requireNonNull(source, "AttributionSource cannot be null in enableBle"); + requireNonNull(token, "IBinder cannot be null in enableBle"); + + final String errorMsg = + mPermissionUtils.callerCanToggle( + mContext, + source, + mUserManager, + mAppOpsManager, + mPermissionManager, + "enableBle", + false); + if (!errorMsg.isEmpty()) { + Log.d(TAG, "enableBle(): FAILED: " + errorMsg); + return false; + } + + return mBluetoothManagerService.enableBle(source.getPackageName(), token); + } + + @Override + @RequiresPermission(BLUETOOTH_CONNECT) + public boolean disableBle(AttributionSource source, IBinder token) { + requireNonNull(source, "AttributionSource cannot be null in disableBle"); + requireNonNull(token, "IBinder cannot be null in disableBle"); + + final String errorMsg = + mPermissionUtils.callerCanToggle( + mContext, + source, + mUserManager, + mAppOpsManager, + mPermissionManager, + "disableBle", + false); + if (!errorMsg.isEmpty()) { + Log.d(TAG, "disableBle(): FAILED: " + errorMsg); + return false; + } + + return mBluetoothManagerService.disableBle(source, source.getPackageName(), token); + } + + @Override + public boolean isBleAppPresent() { + return mBluetoothManagerService.isBleAppPresent(); + } + + @Override + public boolean isHearingAidProfileSupported() { + return mBluetoothManagerService.isHearingAidProfileSupported(); + } + + @Override + @RequiresPermission(BLUETOOTH_PRIVILEGED) + public int setBtHciSnoopLogMode(int mode) { + mPermissionUtils.enforcePrivileged(mContext); + + return mBluetoothManagerService.setBtHciSnoopLogMode(mode); + } + + @Override + @RequiresPermission(BLUETOOTH_PRIVILEGED) + public int getBtHciSnoopLogMode() { + mPermissionUtils.enforcePrivileged(mContext); + + return mBluetoothManagerService.getBtHciSnoopLogMode(); + } + + @Override + public int handleShellCommand( + @NonNull ParcelFileDescriptor in, + @NonNull ParcelFileDescriptor out, + @NonNull ParcelFileDescriptor err, + @NonNull String[] args) { + return new BluetoothShellCommand(mBluetoothManagerService, mContext) + .exec( + this, + in.getFileDescriptor(), + out.getFileDescriptor(), + err.getFileDescriptor(), + args); + } + + @Override + @RequiresPermission(DUMP) + public void dump(FileDescriptor fd, PrintWriter writer, String[] args) { + if (mContext.checkCallingOrSelfPermission(DUMP) != PERMISSION_GRANTED) { + // TODO(b/280890575): Throws SecurityException instead + Log.w(TAG, "dump(): Client does not have DUMP permission"); + return; + } + + mBluetoothManagerService.dump(fd, writer, args); + } +} diff --git a/service/src/com/android/server/bluetooth/BluetoothShellCommand.java b/service/src/com/android/server/bluetooth/BluetoothShellCommand.java index c18208a9e5c..087000f89f8 100644 --- a/service/src/com/android/server/bluetooth/BluetoothShellCommand.java +++ b/service/src/com/android/server/bluetooth/BluetoothShellCommand.java @@ -75,7 +75,9 @@ class BluetoothShellCommand extends BasicShellCommandHandler { } @Override public int exec(String cmd) throws RemoteException { - return mManagerService.enable(AttributionSource.myAttributionSource()) ? 0 : -1; + return mManagerService.getBinder().enable(AttributionSource.myAttributionSource()) + ? 0 + : -1; } @Override public void onHelp(PrintWriter pw) { @@ -91,7 +93,11 @@ class BluetoothShellCommand extends BasicShellCommandHandler { } @Override public int exec(String cmd) throws RemoteException { - return mManagerService.disable(AttributionSource.myAttributionSource(), true) ? 0 : -1; + return mManagerService + .getBinder() + .disable(AttributionSource.myAttributionSource(), true) + ? 0 + : -1; } @Override public void onHelp(PrintWriter pw) { diff --git a/service/src/com/android/server/bluetooth/BtPermissionUtils.java b/service/src/com/android/server/bluetooth/BtPermissionUtils.java new file mode 100644 index 00000000000..f2bb13f5dba --- /dev/null +++ b/service/src/com/android/server/bluetooth/BtPermissionUtils.java @@ -0,0 +1,357 @@ +/* + * Copyright 2023 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.server.bluetooth; + +import static android.Manifest.permission.BLUETOOTH_CONNECT; +import static android.Manifest.permission.BLUETOOTH_PRIVILEGED; +import static android.content.pm.PackageManager.SIGNATURE_MATCH; +import static android.os.Process.SYSTEM_UID; +import static android.permission.PermissionManager.PERMISSION_GRANTED; +import static android.permission.PermissionManager.PERMISSION_HARD_DENIED; + +import static com.android.server.bluetooth.ChangeIds.RESTRICT_ENABLE_DISABLE; + +import android.annotation.RequiresPermission; +import android.annotation.SuppressLint; +import android.app.ActivityManager; +import android.app.AppOpsManager; +import android.app.admin.DevicePolicyManager; +import android.app.compat.CompatChanges; +import android.content.AttributionSource; +import android.content.ComponentName; +import android.content.Context; +import android.content.pm.ApplicationInfo; +import android.content.pm.PackageManager; +import android.os.Binder; +import android.os.Process; +import android.os.UserHandle; +import android.os.UserManager; +import android.permission.PermissionManager; +import android.util.Log; + +class BtPermissionUtils { + private static final String TAG = BtPermissionUtils.class.getSimpleName(); + + private static final int FLAGS_SYSTEM_APP = + ApplicationInfo.FLAG_SYSTEM | ApplicationInfo.FLAG_UPDATED_SYSTEM_APP; + + private final int mSystemUiUid; + + BtPermissionUtils(Context ctx) { + // Check if device is configured with no home screen, which implies no SystemUI. + int systemUiUid = -1; + try { + systemUiUid = + ctx.createContextAsUser(UserHandle.SYSTEM, 0) + .getPackageManager() + .getPackageUid( + "com.android.systemui", + PackageManager.PackageInfoFlags.of( + PackageManager.MATCH_SYSTEM_ONLY)); + Log.d(TAG, "Detected SystemUiUid: " + systemUiUid); + } catch (PackageManager.NameNotFoundException e) { + Log.w(TAG, "Unable to resolve SystemUI's UID."); + } + mSystemUiUid = systemUiUid; + } + + /** + * Returns true if the BLUETOOTH_CONNECT permission is granted for the calling app. Returns + * false if the result is a soft denial. Throws SecurityException if the result is a hard + * denial. + * + *

Should be used in situations where the app op should not be noted. + */ + @SuppressLint("AndroidFrameworkRequiresPermission") + @RequiresPermission(BLUETOOTH_CONNECT) + static boolean checkConnectPermissionForDataDelivery( + Context ctx, + PermissionManager permissionManager, + AttributionSource source, + String message) { + final String permission = BLUETOOTH_CONNECT; + AttributionSource currentSource = + new AttributionSource.Builder(ctx.getAttributionSource()).setNext(source).build(); + final int result = + permissionManager.checkPermissionForDataDeliveryFromDataSource( + permission, currentSource, message); + if (result == PERMISSION_GRANTED) { + return true; + } + + final String msg = "Need " + permission + " permission for " + source + ": " + message; + if (result == PERMISSION_HARD_DENIED) { + throw new SecurityException(msg); + } + Log.w(TAG, msg); + return false; + } + + /** + * Return an empty string if the current call is allowed to toggle bluetooth state + * + *

Return the error description if this caller is not allowed to toggle Bluetooth + */ + String callerCanToggle( + Context ctx, + AttributionSource source, + UserManager userManager, + AppOpsManager appOpsManager, + PermissionManager permissionManager, + String message, + boolean requireForeground) { + if (isBluetoothDisallowed(userManager)) { + return "Bluetooth is not allowed"; + } + + if (!checkBluetoothPermissions( + ctx, + source, + userManager, + appOpsManager, + permissionManager, + message, + requireForeground)) { + return "Missing Bluetooth permission"; + } + + if (requireForeground && !checkCompatChangeRestriction(source, ctx)) { + return "Caller does not match restriction criteria"; + } + + return ""; + } + + static void enforcePrivileged(Context ctx) { + ctx.enforceCallingOrSelfPermission( + BLUETOOTH_PRIVILEGED, "Need BLUETOOTH_PRIVILEGED permission"); + } + + static int getCallingAppId() { + return UserHandle.getAppId(Binder.getCallingUid()); + } + + static boolean isCallerSystem(int callingAppId) { + return callingAppId == Process.SYSTEM_UID; + } + + static boolean isCallerNfc(int callingAppId) { + return callingAppId == Process.NFC_UID; + } + + private static boolean isCallerShell(int callingAppId) { + return callingAppId == Process.SHELL_UID; + } + + private static boolean isCallerRoot(int callingAppId) { + return callingAppId == Process.ROOT_UID; + } + + private boolean isCallerSystemUi(int callingAppId) { + return callingAppId == mSystemUiUid; + } + + private static boolean isPrivileged(Context ctx, int pid, int uid) { + return (ctx.checkPermission(BLUETOOTH_PRIVILEGED, pid, uid) == PERMISSION_GRANTED) + || (ctx.getPackageManager().checkSignatures(uid, SYSTEM_UID) == SIGNATURE_MATCH); + } + + private static boolean isProfileOwner(Context ctx, int uid, String packageName) { + Context userContext; + try { + userContext = + ctx.createPackageContextAsUser( + ctx.getPackageName(), 0, UserHandle.getUserHandleForUid(uid)); + } catch (PackageManager.NameNotFoundException e) { + Log.e(TAG, "Unknown package name"); + return false; + } + if (userContext == null) { + Log.e(TAG, "Unable to retrieve user context for " + uid); + return false; + } + DevicePolicyManager devicePolicyManager = + userContext.getSystemService(DevicePolicyManager.class); + if (devicePolicyManager == null) { + Log.w(TAG, "isProfileOwner: Error retrieving DevicePolicyManager service"); + return false; + } + return devicePolicyManager.isProfileOwnerApp(packageName); + } + + private static boolean isDeviceOwner(Context ctx, int uid, String packageName) { + if (packageName == null) { + Log.e(TAG, "isDeviceOwner: packageName is null, returning false"); + return false; + } + + DevicePolicyManager devicePolicyManager = ctx.getSystemService(DevicePolicyManager.class); + if (devicePolicyManager == null) { + Log.w(TAG, "isDeviceOwner: Error retrieving DevicePolicyManager service"); + return false; + } + UserHandle deviceOwnerUser = null; + ComponentName deviceOwnerComponent = null; + long ident = Binder.clearCallingIdentity(); + try { + deviceOwnerUser = devicePolicyManager.getDeviceOwnerUser(); + deviceOwnerComponent = devicePolicyManager.getDeviceOwnerComponentOnAnyUser(); + } finally { + Binder.restoreCallingIdentity(ident); + } + if (deviceOwnerUser == null + || deviceOwnerComponent == null + || deviceOwnerComponent.getPackageName() == null) { + return false; + } + + return deviceOwnerUser.equals(UserHandle.getUserHandleForUid(uid)) + && deviceOwnerComponent.getPackageName().equals(packageName); + } + + private static boolean isSystem(Context ctx, String packageName, int uid) { + long ident = Binder.clearCallingIdentity(); + try { + ApplicationInfo info = + ctx.getPackageManager() + .getApplicationInfoAsUser( + packageName, 0, UserHandle.getUserHandleForUid(uid)); + return (info.flags & FLAGS_SYSTEM_APP) != 0; + } catch (PackageManager.NameNotFoundException e) { + return false; + } finally { + Binder.restoreCallingIdentity(ident); + } + } + + private static boolean isBluetoothDisallowed(UserManager userManager) { + final long callingIdentity = Binder.clearCallingIdentity(); + try { + return userManager.hasUserRestrictionForUser( + UserManager.DISALLOW_BLUETOOTH, UserHandle.SYSTEM); + } finally { + Binder.restoreCallingIdentity(callingIdentity); + } + } + + /** + * Check ifthe packageName belongs to calling uid + * + *

A null package belongs to any uid + */ + private static void checkPackage(AppOpsManager appOpsManager, String packageName) { + final int callingUid = Binder.getCallingUid(); + if (packageName == null) { + Log.w(TAG, "checkPackage(): called with null packageName from " + callingUid); + return; + } + + try { + appOpsManager.checkPackage(callingUid, packageName); + } catch (SecurityException e) { + Log.w(TAG, "checkPackage(): " + packageName + " does not belong to uid " + callingUid); + throw new SecurityException(e.getMessage()); + } + } + + boolean checkIfCallerIsForegroundUser(UserManager userManager) { + final int callingUid = Binder.getCallingUid(); + final UserHandle callingUser = UserHandle.getUserHandleForUid(callingUid); + final UserHandle foregroundUser; + final UserHandle parentUser; + final long callingIdentity = Binder.clearCallingIdentity(); + try { + // `getCurrentUser` need to be call by system server because it require one of + // INTERACT_ACROSS_USERS | INTERACT_ACROSS_USERS_FULL + foregroundUser = UserHandle.of(ActivityManager.getCurrentUser()); + // `getProfileParent` need to be call by system server because it require one of + // MANAGE_USERS | INTERACT_ACROSS_USER and + parentUser = userManager.getProfileParent(callingUser); + } finally { + Binder.restoreCallingIdentity(callingIdentity); + } + final int callingAppId = UserHandle.getAppId(callingUid); + + // TODO(b/280890575): Remove isCallerX() to only check isForegroundUser + // TODO(b/280890575): Update equality to use Objects.equals on UserHandle + + final boolean valid = + callingUser == foregroundUser + || parentUser == foregroundUser + || isCallerNfc(callingAppId) + || isCallerSystemUi(callingAppId) + || isCallerShell(callingAppId); + + if (!valid) { + Log.d( + TAG, + "checkIfCallerIsForegroundUser: REJECTED:" + + " callingUser=" + + callingUser + + " parentUser=" + + parentUser + + " foregroundUser=" + + foregroundUser + + " callingAppId=" + + callingAppId); + } + return valid; + } + + @RequiresPermission(BLUETOOTH_CONNECT) + private boolean checkBluetoothPermissions( + Context ctx, + AttributionSource source, + UserManager userManager, + AppOpsManager appOpsManager, + PermissionManager permissionManager, + String message, + boolean requireForeground) { + final int callingAppId = getCallingAppId(); + if (isCallerSystem(callingAppId)) return true; + if (isCallerShell(callingAppId)) return true; + if (isCallerRoot(callingAppId)) return true; + checkPackage(appOpsManager, source.getPackageName()); + + if (requireForeground && !checkIfCallerIsForegroundUser(userManager)) { + Log.w(TAG, "Not allowed for non-active and non system user"); + return false; + } + + if (!checkConnectPermissionForDataDelivery(ctx, permissionManager, source, message)) { + return false; + } + return true; + } + + /** Starting from T, enable/disable APIs are limited to system apps or device owners. */ + private static boolean checkCompatChangeRestriction(AttributionSource source, Context ctx) { + final String packageName = source.getPackageName(); + + final int callingUid = Binder.getCallingUid(); + final int callingPid = Binder.getCallingPid(); + if (CompatChanges.isChangeEnabled(RESTRICT_ENABLE_DISABLE, callingUid) + && !isPrivileged(ctx, callingPid, callingUid) + && !isSystem(ctx, packageName, callingUid) + && !isDeviceOwner(ctx, callingUid, packageName) + && !isProfileOwner(ctx, callingUid, packageName)) { + Log.e(TAG, "Caller is not one of: privileged | system | deviceOwner | profileOwner"); + return false; + } + return true; + } +} diff --git a/service/tests/Android.bp b/service/tests/Android.bp index ad3cbf5323a..53ba6b89980 100644 --- a/service/tests/Android.bp +++ b/service/tests/Android.bp @@ -32,7 +32,9 @@ android_test { "androidx.test.rules", "frameworks-base-testutils", "mockito-target-extended-minus-junit4", + "platform-compat-test-rules", "platform-test-annotations", + "service-bluetooth.change-ids", "truth-prebuilt", // Statically link service-bluetooth-pre-jarjar since we want to test the working copy of diff --git a/service/tests/src/com/android/server/bluetooth/BluetoothServiceBinderTest.java b/service/tests/src/com/android/server/bluetooth/BluetoothServiceBinderTest.java new file mode 100644 index 00000000000..b60b29cbd8f --- /dev/null +++ b/service/tests/src/com/android/server/bluetooth/BluetoothServiceBinderTest.java @@ -0,0 +1,481 @@ +/* + * Copyright 2023 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.server.bluetooth; + +import static android.Manifest.permission.BLUETOOTH_CONNECT; +import static android.Manifest.permission.BLUETOOTH_PRIVILEGED; +import static android.Manifest.permission.LOCAL_MAC_ADDRESS; +import static android.Manifest.permission.LOG_COMPAT_CHANGE; +import static android.Manifest.permission.READ_COMPAT_CHANGE_CONFIG; + +import static com.google.common.truth.Truth.assertThat; + +import static org.junit.Assert.assertThrows; +import static org.mockito.ArgumentMatchers.anyBoolean; +import static org.mockito.ArgumentMatchers.eq; +import static org.mockito.Mockito.any; +import static org.mockito.Mockito.anyInt; +import static org.mockito.Mockito.clearInvocations; +import static org.mockito.Mockito.doReturn; +import static org.mockito.Mockito.eq; +import static org.mockito.Mockito.lenient; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.mockingDetails; +import static org.mockito.Mockito.spy; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.verifyNoMoreInteractions; +import static org.mockito.quality.Strictness.STRICT_STUBS; + +import android.app.AppOpsManager; +import android.app.admin.DevicePolicyManager; +import android.bluetooth.IBluetoothManagerCallback; +import android.bluetooth.IBluetoothProfileServiceConnection; +import android.bluetooth.IBluetoothStateChangeCallback; +import android.compat.testing.PlatformCompatChangeRule; +import android.content.AttributionSource; +import android.content.Context; +import android.content.ContextWrapper; +import android.os.IBinder; +import android.os.Process; +import android.os.UserManager; + +import androidx.test.filters.SmallTest; +import androidx.test.platform.app.InstrumentationRegistry; +import androidx.test.runner.AndroidJUnit4; + +import libcore.junit.util.compat.CoreCompatChangeRule.DisableCompatChanges; +import libcore.junit.util.compat.CoreCompatChangeRule.EnableCompatChanges; + +import org.junit.After; +import org.junit.Before; +import org.junit.Rule; +import org.junit.Test; +import org.junit.function.ThrowingRunnable; +import org.junit.rules.TestRule; +import org.junit.runner.RunWith; +import org.mockito.Mock; +import org.mockito.MockitoAnnotations; +import org.mockito.junit.MockitoJUnit; +import org.mockito.junit.MockitoRule; + +import java.util.function.BooleanSupplier; + +@SmallTest +@RunWith(AndroidJUnit4.class) +public class BluetoothServiceBinderTest { + private static final String TAG = BluetoothServiceBinderTest.class.getSimpleName(); + + @Rule public MockitoRule mockito = MockitoJUnit.rule().strictness(STRICT_STUBS); + + @Rule public TestRule compatChangeRule = new PlatformCompatChangeRule(); + + @Mock private BluetoothManagerService mManagerService; + @Mock private UserManager mUserManager; + @Mock private AppOpsManager mAppOpsManager; + @Mock private DevicePolicyManager mDevicePolicyManager; + + private Context mContext = + spy( + new ContextWrapper( + InstrumentationRegistry.getInstrumentation().getTargetContext())); + + private final AttributionSource mSource = + spy(new AttributionSource.Builder(Process.myUid()).build()); + + private BluetoothServiceBinder mBinder; + + @Before + public void setUp() throws Exception { + MockitoAnnotations.initMocks(this); + + lenient().doReturn(TAG).when(mSource).getPackageName(); + + InstrumentationRegistry.getInstrumentation() + .getUiAutomation() + .adoptShellPermissionIdentity(LOG_COMPAT_CHANGE, READ_COMPAT_CHANGE_CONFIG); + + final String appops = mContext.getSystemServiceName(AppOpsManager.class); + final String devicePolicy = mContext.getSystemServiceName(DevicePolicyManager.class); + doReturn(mAppOpsManager).when(mContext).getSystemService(eq(appops)); + doReturn(mDevicePolicyManager).when(mContext).getSystemService(eq(devicePolicy)); + + mBinder = new BluetoothServiceBinder(mManagerService, mContext, mUserManager); + } + + @After + public void tearDown() { + InstrumentationRegistry.getInstrumentation() + .getUiAutomation() + .dropShellPermissionIdentity(); + // Do not call verifyMock here. If the test fails the initial error will be lost + } + + @Test + public void registerAdapter() { + assertThrows(NullPointerException.class, () -> mBinder.registerAdapter(null)); + mBinder.registerAdapter(mock(IBluetoothManagerCallback.class)); + verify(mManagerService).registerAdapter(any()); + verifyMock(); + } + + @Test + public void unregisterAdapter() { + assertThrows(NullPointerException.class, () -> mBinder.unregisterAdapter(null)); + mBinder.unregisterAdapter(mock(IBluetoothManagerCallback.class)); + verify(mManagerService).unregisterAdapter(any()); + verifyMock(); + } + + @Test + public void registerStateChangeCallback() { + assertThrows(NullPointerException.class, () -> mBinder.registerStateChangeCallback(null)); + mBinder.registerStateChangeCallback(mock(IBluetoothStateChangeCallback.class)); + verify(mManagerService).registerStateChangeCallback(any()); + verifyMock(); + } + + @Test + public void unregisterStateChangeCallback() { + assertThrows(NullPointerException.class, () -> mBinder.unregisterStateChangeCallback(null)); + mBinder.unregisterStateChangeCallback(mock(IBluetoothStateChangeCallback.class)); + verify(mManagerService).unregisterStateChangeCallback(any()); + verifyMock(); + } + + @Test + @DisableCompatChanges({ChangeIds.RESTRICT_ENABLE_DISABLE}) + public void enableNoRestrictEnable() { + assertThrows(NullPointerException.class, () -> mBinder.enable(null)); + + checkDisabled(() -> mBinder.enable(mSource)); + checkHardDenied(() -> mBinder.enable(mSource), true); + doReturn(true).when(mManagerService).enable(any()); + checkGranted(() -> mBinder.enable(mSource), true); + verify(mUserManager).getProfileParent(any()); + verify(mManagerService).enable(eq(TAG)); + verifyMock(); + } + + @Test + @EnableCompatChanges({ChangeIds.RESTRICT_ENABLE_DISABLE}) + public void enableWithRestrictEnable() { + assertThrows(NullPointerException.class, () -> mBinder.enable(null)); + + checkDisabled(() -> mBinder.enable(mSource)); + checkHardDenied(() -> mBinder.enable(mSource), true); + checkGranted(() -> mBinder.enable(mSource), false); + verify(mUserManager).getProfileParent(any()); + verifyMock(); + + // TODO(b/280518177): add more test around compatChange + } + + @Test + public void enableNoAutoConnect() { + assertThrows(NullPointerException.class, () -> mBinder.enableNoAutoConnect(null)); + + checkDisabled(() -> mBinder.enableNoAutoConnect(mSource)); + checkHardDenied(() -> mBinder.enableNoAutoConnect(mSource), false); + + // enableNoAutoConnect is only available for Nfc and will fail otherwise + assertThrows(SecurityException.class, () -> mBinder.enableNoAutoConnect(mSource)); + + verify(mUserManager).hasUserRestrictionForUser(eq(UserManager.DISALLOW_BLUETOOTH), any()); + verify(mAppOpsManager).checkPackage(anyInt(), eq(TAG)); + verifyMock(); + + // TODO(b/280518177): add test that simulate NFC caller to have a successful case + } + + @Test + @DisableCompatChanges({ChangeIds.RESTRICT_ENABLE_DISABLE}) + public void disableNoRestrictEnable() { + assertThrows(NullPointerException.class, () -> mBinder.disable(null, true)); + + assertThrows(SecurityException.class, () -> mBinder.disable(mSource, false)); + + checkDisabled(() -> mBinder.disable(mSource, true)); + checkHardDenied(() -> mBinder.disable(mSource, true), true); + doReturn(true).when(mManagerService).disable(any(), anyBoolean()); + checkGranted(() -> mBinder.disable(mSource, true), true); + verify(mUserManager).getProfileParent(any()); + verify(mManagerService).disable(eq(TAG), anyBoolean()); + verifyMock(); + } + + @Test + @EnableCompatChanges({ChangeIds.RESTRICT_ENABLE_DISABLE}) + public void disableWithRestrictEnable() { + assertThrows(NullPointerException.class, () -> mBinder.disable(null, true)); + + assertThrows(SecurityException.class, () -> mBinder.disable(mSource, false)); + + checkDisabled(() -> mBinder.disable(mSource, true)); + checkHardDenied(() -> mBinder.disable(mSource, true), true); + checkGranted(() -> mBinder.disable(mSource, true), false); + verify(mUserManager).getProfileParent(any()); + verifyMock(); + + // TODO(b/280518177): add more test around compatChange + } + + @Test + public void getState() { + // TODO(b/280518177): add more test from not System / ... + // TODO(b/280518177): add more test when caller is not in foreground + + mBinder.getState(); + verify(mManagerService).getState(); + verify(mUserManager).getProfileParent(any()); + verifyMock(); + } + + @Test + public void getBluetoothGatt() { + // No permission needed for this call + mBinder.getBluetoothGatt(); + verify(mManagerService).getBluetoothGatt(); + verifyMock(); + } + + @Test + public void bindBluetoothProfileService() { + assertThrows( + NullPointerException.class, + () -> mBinder.bindBluetoothProfileService(0, "foo", null)); + // No permission needed for this call + + mBinder.bindBluetoothProfileService( + 0, "foo", mock(IBluetoothProfileServiceConnection.class)); + verify(mManagerService).bindBluetoothProfileService(anyInt(), any(), any()); + verifyMock(); + } + + @Test + public void unbindBluetoothProfileService() { + // No permission needed for this call + mBinder.unbindBluetoothProfileService(0, null); + verify(mManagerService).unbindBluetoothProfileService(anyInt(), any()); + verifyMock(); + } + + @Test + public void getAddress() { + assertThrows(NullPointerException.class, () -> mBinder.getAddress(null)); + + assertThrows(SecurityException.class, () -> mBinder.getAddress(mSource)); + InstrumentationRegistry.getInstrumentation() + .getUiAutomation() + .adoptShellPermissionIdentity(BLUETOOTH_CONNECT); + + // TODO(b/280518177): Throws SecurityException and remove DEFAULT_MAC_ADDRESS + // assertThrows(SecurityException.class, () -> mBinder.getAddress(mSource)); + assertThat(mBinder.getAddress(mSource)).isEqualTo("02:00:00:00:00:00"); + verifyMockForCheckIfCallerIsForegroundUser(); + + InstrumentationRegistry.getInstrumentation() + .getUiAutomation() + .adoptShellPermissionIdentity(BLUETOOTH_CONNECT, LOCAL_MAC_ADDRESS); + + // TODO(b/280518177): add more test from not System / ... + // TODO(b/280518177): add more test when caller is not in foreground + + doReturn("foo").when(mManagerService).getAddress(any()); + assertThat(mBinder.getAddress(mSource)).isEqualTo("foo"); + + verify(mManagerService).getAddress(any()); + verifyMockForCheckIfCallerIsForegroundUser(); + } + + @Test + public void getName() { + assertThrows(NullPointerException.class, () -> mBinder.getName(null)); + + assertThrows(SecurityException.class, () -> mBinder.getName(mSource)); + InstrumentationRegistry.getInstrumentation() + .getUiAutomation() + .adoptShellPermissionIdentity(BLUETOOTH_CONNECT); + + // TODO(b/280518177): add more test from not System / ... + // TODO(b/280518177): add more test when caller is not in foreground + + doReturn("foo").when(mManagerService).getName(any()); + assertThat(mBinder.getName(mSource)).isEqualTo("foo"); + verify(mManagerService).getName(any()); + verifyMockForCheckIfCallerIsForegroundUser(); + } + + @Test + public void onFactoryReset() { + assertThrows(NullPointerException.class, () -> mBinder.onFactoryReset(null)); + + assertThrows(SecurityException.class, () -> mBinder.onFactoryReset(mSource)); + InstrumentationRegistry.getInstrumentation() + .getUiAutomation() + .adoptShellPermissionIdentity(BLUETOOTH_PRIVILEGED); + + assertThrows(SecurityException.class, () -> mBinder.onFactoryReset(mSource)); + InstrumentationRegistry.getInstrumentation() + .getUiAutomation() + .adoptShellPermissionIdentity(BLUETOOTH_PRIVILEGED, BLUETOOTH_CONNECT); + + assertThat(mBinder.onFactoryReset(mSource)).isFalse(); + verify(mManagerService).onFactoryReset(any()); + verifyMock(); + } + + @Test + public void isBleScanAlwaysAvailable() { + // No permission needed for this call + mBinder.isBleScanAlwaysAvailable(); + verify(mManagerService).isBleScanAlwaysAvailable(); + verifyMock(); + } + + @Test + public void enableBle() { + IBinder token = mock(IBinder.class); + assertThrows(NullPointerException.class, () -> mBinder.enableBle(null, token)); + assertThrows(NullPointerException.class, () -> mBinder.enableBle(mSource, null)); + + checkDisabled(() -> mBinder.enableBle(mSource, token)); + checkHardDenied(() -> mBinder.enableBle(mSource, token), false); + doReturn(true).when(mManagerService).enableBle(eq(TAG), eq(token)); + checkGranted(() -> mBinder.enableBle(mSource, token), true); + verify(mManagerService).enableBle(eq(TAG), eq(token)); + verifyMock(); + } + + @Test + public void disableBle() { + IBinder token = mock(IBinder.class); + assertThrows(NullPointerException.class, () -> mBinder.disableBle(null, token)); + assertThrows(NullPointerException.class, () -> mBinder.disableBle(mSource, null)); + + checkDisabled(() -> mBinder.disableBle(mSource, token)); + checkHardDenied(() -> mBinder.disableBle(mSource, token), false); + doReturn(true).when(mManagerService).disableBle(eq(mSource), eq(TAG), eq(token)); + checkGranted(() -> mBinder.disableBle(mSource, token), true); + verify(mManagerService).disableBle(eq(mSource), eq(TAG), eq(token)); + verifyMock(); + } + + @Test + public void isBleAppPresent() { + // No permission needed for this call + mBinder.isBleAppPresent(); + verify(mManagerService).isBleAppPresent(); + verifyMock(); + } + + @Test + public void isHearingAidProfileSupported() { + // No permission needed for this call + mBinder.isHearingAidProfileSupported(); + verify(mManagerService).isHearingAidProfileSupported(); + verifyMock(); + } + + @Test + public void setBtHciSnoopLogMode() { + assertThrows(SecurityException.class, () -> mBinder.setBtHciSnoopLogMode(0)); + + InstrumentationRegistry.getInstrumentation() + .getUiAutomation() + .adoptShellPermissionIdentity(BLUETOOTH_PRIVILEGED); + assertThat(mBinder.setBtHciSnoopLogMode(0)).isEqualTo(0); + verify(mManagerService).setBtHciSnoopLogMode(anyInt()); + verifyMock(); + } + + @Test + public void getBtHciSnoopLogMode() { + assertThrows(SecurityException.class, () -> mBinder.getBtHciSnoopLogMode()); + + InstrumentationRegistry.getInstrumentation() + .getUiAutomation() + .adoptShellPermissionIdentity(BLUETOOTH_PRIVILEGED); + assertThat(mBinder.getBtHciSnoopLogMode()).isEqualTo(0); + verify(mManagerService).getBtHciSnoopLogMode(); + verifyMock(); + } + + // TODO(b/280518177): Add test for `handleShellCommand` and `dump` + + // ********************************************************************************************* + // Utility method used in tests + + private void verifyAndClearMock(Object o) { + assertThat(mockingDetails(o).isMock() || mockingDetails(o).isSpy()).isTrue(); + verifyNoMoreInteractions(o); + clearInvocations(o); + } + + private void verifyMock() { + verifyAndClearMock(mManagerService); + verifyAndClearMock(mUserManager); + verifyAndClearMock(mAppOpsManager); + verifyAndClearMock(mDevicePolicyManager); + } + + private void verifyMockForCheckIfCallerIsForegroundUser() { + verify(mUserManager).getProfileParent(any()); + verifyMock(); + } + + private void checkDisabled(BooleanSupplier binderCall) { + doReturn(true) + .when(mUserManager) + .hasUserRestrictionForUser(eq(UserManager.DISALLOW_BLUETOOTH), any()); + + assertThat(binderCall.getAsBoolean()).isFalse(); + + verify(mUserManager).hasUserRestrictionForUser(eq(UserManager.DISALLOW_BLUETOOTH), any()); + verifyMock(); + } + + private void checkHardDenied(ThrowingRunnable binderCall, boolean requireForeground) { + doReturn(false) + .when(mUserManager) + .hasUserRestrictionForUser(eq(UserManager.DISALLOW_BLUETOOTH), any()); + + assertThrows(SecurityException.class, binderCall); + + verify(mUserManager).hasUserRestrictionForUser(eq(UserManager.DISALLOW_BLUETOOTH), any()); + if (requireForeground) { + verify(mUserManager).getProfileParent(any()); + } + verify(mAppOpsManager).checkPackage(anyInt(), eq(TAG)); + verifyMock(); + } + + private void checkGranted(BooleanSupplier binderCall, boolean expectedResult) { + InstrumentationRegistry.getInstrumentation() + .getUiAutomation() + .adoptShellPermissionIdentity( + LOG_COMPAT_CHANGE, READ_COMPAT_CHANGE_CONFIG, BLUETOOTH_CONNECT); + + assertThat(binderCall.getAsBoolean()).isEqualTo(expectedResult); + + verify(mUserManager).hasUserRestrictionForUser(eq(UserManager.DISALLOW_BLUETOOTH), any()); + verify(mAppOpsManager).checkPackage(anyInt(), eq(TAG)); + if (!expectedResult) { + verify(mDevicePolicyManager).getDeviceOwnerUser(); + verify(mDevicePolicyManager).getDeviceOwnerComponentOnAnyUser(); + } + } +} diff --git a/service/tests/src/com/android/server/bluetooth/BluetoothShellCommandTest.java b/service/tests/src/com/android/server/bluetooth/BluetoothShellCommandTest.java index db14999e47d..cd093bba92e 100644 --- a/service/tests/src/com/android/server/bluetooth/BluetoothShellCommandTest.java +++ b/service/tests/src/com/android/server/bluetooth/BluetoothShellCommandTest.java @@ -21,10 +21,12 @@ import static com.google.common.truth.Truth.assertThat; import static org.junit.Assert.assertThrows; import static org.mockito.ArgumentMatchers.anyBoolean; import static org.mockito.Mockito.any; +import static org.mockito.Mockito.doReturn; import static org.mockito.Mockito.eq; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.spy; import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.verifyNoMoreInteractions; import static org.mockito.Mockito.when; import android.bluetooth.BluetoothAdapter; @@ -39,6 +41,7 @@ import com.android.server.bluetooth.BluetoothShellCommand.BluetoothCommand; import com.google.common.truth.Expect; +import org.junit.After; import org.junit.Before; import org.junit.Rule; import org.junit.Test; @@ -57,6 +60,8 @@ public class BluetoothShellCommandTest { @Mock BluetoothManagerService mManagerService; + @Mock BluetoothServiceBinder mBinder; + @Mock Context mContext; @@ -65,12 +70,20 @@ public class BluetoothShellCommandTest { @Before public void setUp() throws Exception { MockitoAnnotations.initMocks(this); + doReturn(mBinder).when(mManagerService).getBinder(); + mShellCommand = new BluetoothShellCommand(mManagerService, mContext); mShellCommand.init( mock(Binder.class), mock(FileDescriptor.class), mock(FileDescriptor.class), mock(FileDescriptor.class), new String[0], -1); } + @After + public void tearDown() { + verifyNoMoreInteractions(mBinder); + // verifyNoMoreInteractions(mManagerService); // TODO(b/280518177): Apply after cleanup + } + @Test public void enableCommand() throws Exception { BluetoothCommand enableCmd = mShellCommand.new Enable(); @@ -79,8 +92,9 @@ public class BluetoothShellCommandTest { assertThat(enableCmd.getName()).isEqualTo(cmdName); assertThat(enableCmd.isMatch(cmdName)).isTrue(); assertThat(enableCmd.isPrivileged()).isFalse(); - when(mManagerService.enable(any())).thenReturn(true); + when(mBinder.enable(any())).thenReturn(true); assertThat(enableCmd.exec(cmdName)).isEqualTo(0); + verify(mBinder).enable(any()); } @Test @@ -91,8 +105,9 @@ public class BluetoothShellCommandTest { assertThat(disableCmd.getName()).isEqualTo(cmdName); assertThat(disableCmd.isMatch(cmdName)).isTrue(); assertThat(disableCmd.isPrivileged()).isFalse(); - when(mManagerService.disable(any(), anyBoolean())).thenReturn(true); + when(mBinder.disable(any(), anyBoolean())).thenReturn(true); assertThat(disableCmd.exec(cmdName)).isEqualTo(0); + verify(mBinder).disable(any(), anyBoolean()); } @Test @@ -147,6 +162,7 @@ public class BluetoothShellCommandTest { mShellCommand.onCommand("enable"); verify(enableCmd).exec(eq("enable")); + verify(mBinder).enable(any()); } @Test -- GitLab From bd1a60dc61b58cedc9d346e4f091dc6934f88281 Mon Sep 17 00:00:00 2001 From: Fahad Afroze Date: Fri, 12 May 2023 10:07:49 +0000 Subject: [PATCH 0065/2405] [PTS-Bot] Added 2 PAN test cases. PAN/PANU/IP/APP/BV-03-I ICS: TSPC_PAN_4_3 or TSPC_PAN_4_9 PAN/PANU/IP/DNS/BV-01-I ICS: TSPC_PAN_4_5 or TSPC_PAN_4_10 Bug: 274788536 Test: atest pts-bot:PAN -v Change-Id: I1d727e55868baf8589f55e10bc562a65f0d84f5f --- android/pandora/mmi2grpc/mmi2grpc/pan.py | 31 +++++++++++++++++++ .../server/configs/pts_bot_tests_config.json | 6 ++++ .../com/android/pandora/AndroidInternal.kt | 11 +++++++ .../pandora_experimental/_android.proto | 7 +++++ 4 files changed, 55 insertions(+) diff --git a/android/pandora/mmi2grpc/mmi2grpc/pan.py b/android/pandora/mmi2grpc/mmi2grpc/pan.py index 973b3f9edaf..542d292dc54 100644 --- a/android/pandora/mmi2grpc/mmi2grpc/pan.py +++ b/android/pandora/mmi2grpc/mmi2grpc/pan.py @@ -20,6 +20,10 @@ from mmi2grpc._proxy import ProfileProxy from pandora.host_grpc import Host from pandora_experimental.pan_grpc import PAN +from pandora_experimental._android_grpc import Android + +# IP address of PTS +TSPX_PTS_IP_ADDRESS = "192.168.168.100" class PANProxy(ProfileProxy): @@ -28,6 +32,7 @@ class PANProxy(ProfileProxy): super().__init__(channel) self.host = Host(channel) self.pan = PAN(channel) + self._android = Android(channel) def TSC_BNEP_mmi_iut_accept_transport(self, pts_addr: bytes, **kwargs): """ @@ -226,3 +231,29 @@ class PANProxy(ProfileProxy): """ return "OK" + + @assert_description + def TSC_PAN_mmi_iut_icmp_echo_request(self, **kwargs): + """ + Take action to send ICMP echo request + """ + + self._android.SendPing(ip_address=TSPX_PTS_IP_ADDRESS) + + return "OK" + + @assert_description + def TSC_PAN_mmi_iut_receive_icmp_echo_reply(self, **kwargs): + """ + Has the IUT received the ICMP echo reply from PTS? + """ + + return "OK" + + @assert_description + def TSC_PAN_mmi_iut_send_dns_request(self, **kwargs): + """ + Take action to send DNS request + """ + + return "OK" diff --git a/android/pandora/server/configs/pts_bot_tests_config.json b/android/pandora/server/configs/pts_bot_tests_config.json index c57df434181..f4b58efcdcd 100644 --- a/android/pandora/server/configs/pts_bot_tests_config.json +++ b/android/pandora/server/configs/pts_bot_tests_config.json @@ -551,8 +551,10 @@ "PAN/GN/MISC/UUID/BV-01-C", "PAN/GN/MISC/UUID/BV-02-C", "PAN/NAP/SDP/BV-01-C", + "PAN/PANU/IP/APP/BV-03-I", "PAN/PANU/IP/APP/BV-05-I", "PAN/PANU/IP/DHCP/BV-03-I", + "PAN/PANU/IP/DNS/BV-01-I", "PBAP/PSE/GOEP/BC/BV-03-I", "PBAP/PSE/GOEP/CON/BV-02-C", "PBAP/PSE/GOEP/ROB/BV-01-C", @@ -1855,7 +1857,11 @@ "TSPC_PAN_2_18": true, "TSPC_PAN_4_1": true, "TSPC_PAN_4_2": true, + "TSPC_PAN_4_3": true, "TSPC_PAN_4_4": true, + "TSPC_PAN_4_5": true, + "TSPC_PAN_4_9": true, + "TSPC_PAN_4_10": true, "TSPC_PBAP_1_2": true, "TSPC_PBAP_9_1": true, "TSPC_PBAP_9_2": true, diff --git a/android/pandora/server/src/com/android/pandora/AndroidInternal.kt b/android/pandora/server/src/com/android/pandora/AndroidInternal.kt index b45454912f6..6f2fd329e5c 100644 --- a/android/pandora/server/src/com/android/pandora/AndroidInternal.kt +++ b/android/pandora/server/src/com/android/pandora/AndroidInternal.kt @@ -149,6 +149,17 @@ class AndroidInternal(val context: Context) : AndroidImplBase(), Closeable { } } + override fun sendPing( + request: SendPingRequest, + responseObserver: StreamObserver + ) { + grpcUnary(scope, responseObserver) { + val pingStatus = + Runtime.getRuntime().exec("ping -I bt-pan -c 1 ${request.ipAddress}").waitFor() + Empty.getDefaultInstance() + } + } + suspend private fun waitAndSelectBluetoothDevice() { var selectJob = scope.async { diff --git a/pandora/interfaces/pandora_experimental/_android.proto b/pandora/interfaces/pandora_experimental/_android.proto index feaa3b6b399..4c495cad25a 100644 --- a/pandora/interfaces/pandora_experimental/_android.proto +++ b/pandora/interfaces/pandora_experimental/_android.proto @@ -22,6 +22,8 @@ service Android { rpc AcceptIncomingFile(google.protobuf.Empty) returns (google.protobuf.Empty); // Send file rpc SendFile(google.protobuf.Empty) returns (google.protobuf.Empty); + // Send ping + rpc SendPing(SendPingRequest) returns (google.protobuf.Empty); } message LogRequest { @@ -48,4 +50,9 @@ message SetAccessPermissionRequest { message InternalConnectionRef { bytes address = 1; int32 transport = 2; +} + +// Request for the `SendPing` rpc. +message SendPingRequest { + string ip_address = 1; } \ No newline at end of file -- GitLab From c2556c653abf7e5b812a10266a9297af2f2d30a7 Mon Sep 17 00:00:00 2001 From: Jeremy Wu Date: Tue, 16 May 2023 06:35:10 +0000 Subject: [PATCH 0066/2405] Floss: add a member to store codec in esco_param In anticipation of having LC3 and mSBC both qualifying for the "transparent" coding format, we need an extra member to store which of them is the underlying codec for various operations. In this CL, we add a new member `coding_format` to store that. Bug: 269970706 Tag: #floss Test: Build and verify Change-Id: Id4dc424b6917cd884e1ded0d38ca6f34d5cff604 --- system/device/include/esco_parameters.h | 2 ++ system/device/src/esco_parameters.cc | 7 +++++++ 2 files changed, 9 insertions(+) diff --git a/system/device/include/esco_parameters.h b/system/device/include/esco_parameters.h index ed206b857c4..9096796f656 100644 --- a/system/device/include/esco_parameters.h +++ b/system/device/include/esco_parameters.h @@ -137,6 +137,8 @@ typedef struct { esco_packet_types_t packet_types; /* Packet Types */ esco_retransmission_effort_t retransmission_effort; /* 0x00-0x02, 0xFF don't care */ + esco_coding_format_t + coding_format; /* Extra field to store codec when TX/RX is transparent */ } enh_esco_params_t; // Get the enhanced eSCO configuration parameters for the provided |codec| diff --git a/system/device/src/esco_parameters.cc b/system/device/src/esco_parameters.cc index 48607e6d54a..861dfd90ccd 100644 --- a/system/device/src/esco_parameters.cc +++ b/system/device/src/esco_parameters.cc @@ -57,6 +57,7 @@ static const enh_esco_params_t default_esco_parameters[ESCO_NUM_CODECS] = { .packet_types = (ESCO_PKT_TYPES_MASK_HV1 | ESCO_PKT_TYPES_MASK_HV2 | ESCO_PKT_TYPES_MASK_HV3), .retransmission_effort = ESCO_RETRANSMISSION_OFF, + .coding_format = ESCO_CODING_FORMAT_CVSD, }, // CVSD S3 { @@ -96,6 +97,7 @@ static const enh_esco_params_t default_esco_parameters[ESCO_NUM_CODECS] = { ESCO_PKT_TYPES_MASK_NO_3_EV3 | ESCO_PKT_TYPES_MASK_NO_2_EV5 | ESCO_PKT_TYPES_MASK_NO_3_EV5), .retransmission_effort = ESCO_RETRANSMISSION_POWER, + .coding_format = ESCO_CODING_FORMAT_CVSD, }, // CVSD S4 { @@ -135,6 +137,7 @@ static const enh_esco_params_t default_esco_parameters[ESCO_NUM_CODECS] = { ESCO_PKT_TYPES_MASK_NO_3_EV3 | ESCO_PKT_TYPES_MASK_NO_2_EV5 | ESCO_PKT_TYPES_MASK_NO_3_EV5), .retransmission_effort = ESCO_RETRANSMISSION_QUALITY, + .coding_format = ESCO_CODING_FORMAT_CVSD, }, // mSBC T1 { @@ -172,6 +175,7 @@ static const enh_esco_params_t default_esco_parameters[ESCO_NUM_CODECS] = { ESCO_PKT_TYPES_MASK_NO_2_EV5 | ESCO_PKT_TYPES_MASK_NO_3_EV5 | ESCO_PKT_TYPES_MASK_NO_2_EV3), .retransmission_effort = ESCO_RETRANSMISSION_QUALITY, + .coding_format = ESCO_CODING_FORMAT_MSBC, }, // mSBC T2 { @@ -208,6 +212,7 @@ static const enh_esco_params_t default_esco_parameters[ESCO_NUM_CODECS] = { (ESCO_PKT_TYPES_MASK_EV3 | ESCO_PKT_TYPES_MASK_NO_3_EV3 | ESCO_PKT_TYPES_MASK_NO_2_EV5 | ESCO_PKT_TYPES_MASK_NO_3_EV5), .retransmission_effort = ESCO_RETRANSMISSION_QUALITY, + .coding_format = ESCO_CODING_FORMAT_MSBC, }, // LC3 T1 { @@ -245,6 +250,7 @@ static const enh_esco_params_t default_esco_parameters[ESCO_NUM_CODECS] = { ESCO_PKT_TYPES_MASK_NO_2_EV5 | ESCO_PKT_TYPES_MASK_NO_3_EV5 | ESCO_PKT_TYPES_MASK_NO_2_EV3), .retransmission_effort = ESCO_RETRANSMISSION_QUALITY, + .coding_format = ESCO_CODING_FORMAT_LC3, }, // LC3 T2 { @@ -281,6 +287,7 @@ static const enh_esco_params_t default_esco_parameters[ESCO_NUM_CODECS] = { (ESCO_PKT_TYPES_MASK_NO_3_EV3 | ESCO_PKT_TYPES_MASK_NO_2_EV5 | ESCO_PKT_TYPES_MASK_NO_3_EV5), .retransmission_effort = ESCO_RETRANSMISSION_QUALITY, + .coding_format = ESCO_CODING_FORMAT_LC3, }, }; -- GitLab From c6eda2c03201abd7afdb58fb53569f75179a582d Mon Sep 17 00:00:00 2001 From: Martin Geisler Date: Mon, 20 Mar 2023 11:51:27 +0100 Subject: [PATCH 0067/2405] pdl: Generate snapshots using prettyplease MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The prettyplease library has been explicitly designed to be used for programmatic formatting of Rust code. It is faster and simpler to use than calling ‘rustfmt’. Because ‘prettyplease’ sometimes uses a slightly different formatting compared to ‘rustfmt’, I’m adding a ‘#![rustfmt::skip]’ like to the top of every auto-generated file. Tag: #refactor Bug: 274187738 Test: atest pdl_tests pdl_rust_generator_tests_{le,be} Change-Id: Ifd74db6c6bd06b020960d586ca803a26a4603c2d --- tools/pdl/Android.bp | 9 +- tools/pdl/Cargo.toml | 1 + tools/pdl/src/backends/rust.rs | 4 +- tools/pdl/src/backends/rust/preamble.rs | 30 +++-- tools/pdl/src/test_utils.rs | 52 +------ .../custom_field_declaration_big_endian.rs | 30 ++--- .../custom_field_declaration_little_endian.rs | 30 ++--- .../generated/enum_declaration_big_endian.rs | 27 ++-- .../enum_declaration_little_endian.rs | 27 ++-- ...packet_decl_24bit_enum_array_big_endian.rs | 31 ++--- ...ket_decl_24bit_enum_array_little_endian.rs | 31 ++--- .../packet_decl_24bit_enum_big_endian.rs | 31 ++--- .../packet_decl_24bit_enum_little_endian.rs | 31 ++--- ...cket_decl_24bit_scalar_array_big_endian.rs | 23 ++-- ...t_decl_24bit_scalar_array_little_endian.rs | 23 ++-- .../packet_decl_24bit_scalar_big_endian.rs | 23 ++-- .../packet_decl_24bit_scalar_little_endian.rs | 23 ++-- ...packet_decl_64bit_enum_array_big_endian.rs | 37 +++-- ...ket_decl_64bit_enum_array_little_endian.rs | 31 ++--- .../packet_decl_64bit_enum_big_endian.rs | 28 ++-- .../packet_decl_64bit_enum_little_endian.rs | 31 ++--- ...cket_decl_64bit_scalar_array_big_endian.rs | 23 ++-- ...t_decl_64bit_scalar_array_little_endian.rs | 23 ++-- .../packet_decl_64bit_scalar_big_endian.rs | 23 ++-- .../packet_decl_64bit_scalar_little_endian.rs | 23 ++-- .../packet_decl_8bit_enum_array_big_endian.rs | 37 +++-- ...cket_decl_8bit_enum_array_little_endian.rs | 37 +++-- .../packet_decl_8bit_enum_big_endian.rs | 28 ++-- .../packet_decl_8bit_enum_little_endian.rs | 28 ++-- ...acket_decl_8bit_scalar_array_big_endian.rs | 23 ++-- ...et_decl_8bit_scalar_array_little_endian.rs | 23 ++-- .../packet_decl_8bit_scalar_big_endian.rs | 23 ++-- .../packet_decl_8bit_scalar_little_endian.rs | 23 ++-- ...ket_decl_array_dynamic_count_big_endian.rs | 32 ++--- ..._decl_array_dynamic_count_little_endian.rs | 32 ++--- ...cket_decl_array_dynamic_size_big_endian.rs | 42 +++--- ...t_decl_array_dynamic_size_little_endian.rs | 42 +++--- ..._element_width_dynamic_count_big_endian.rs | 38 +++--- ...ement_width_dynamic_count_little_endian.rs | 38 +++--- ...n_element_width_dynamic_size_big_endian.rs | 34 +++-- ...lement_width_dynamic_size_little_endian.rs | 34 +++-- ...cket_decl_array_with_padding_big_endian.rs | 33 ++--- ...t_decl_array_with_padding_little_endian.rs | 33 ++--- .../packet_decl_child_packets_big_endian.rs | 64 ++++----- ...packet_decl_child_packets_little_endian.rs | 64 ++++----- .../packet_decl_complex_scalars_big_endian.rs | 33 ++--- ...cket_decl_complex_scalars_little_endian.rs | 33 ++--- .../packet_decl_custom_field_big_endian.rs | 31 ++--- .../packet_decl_custom_field_little_endian.rs | 31 ++--- .../generated/packet_decl_empty_big_endian.rs | 23 ++-- .../packet_decl_empty_little_endian.rs | 23 ++-- ...packet_decl_fixed_enum_field_big_endian.rs | 28 ++-- ...ket_decl_fixed_enum_field_little_endian.rs | 28 ++-- ...cket_decl_fixed_scalar_field_big_endian.rs | 27 ++-- ...t_decl_fixed_scalar_field_little_endian.rs | 27 ++-- .../packet_decl_grand_children_big_endian.rs | 127 +++++++++--------- ...acket_decl_grand_children_little_endian.rs | 127 +++++++++--------- ...acket_decl_mask_scalar_value_big_endian.rs | 29 ++-- ...et_decl_mask_scalar_value_little_endian.rs | 29 ++-- ...ket_decl_mixed_scalars_enums_big_endian.rs | 49 ++++--- ..._decl_mixed_scalars_enums_little_endian.rs | 49 ++++--- ...l_payload_field_unknown_size_big_endian.rs | 27 ++-- ...ayload_field_unknown_size_little_endian.rs | 27 ++-- ..._field_unknown_size_terminal_big_endian.rs | 27 ++-- ...eld_unknown_size_terminal_little_endian.rs | 27 ++-- ..._payload_field_variable_size_big_endian.rs | 34 +++-- ...yload_field_variable_size_little_endian.rs | 34 +++-- .../packet_decl_reserved_field_big_endian.rs | 23 ++-- ...acket_decl_reserved_field_little_endian.rs | 23 ++-- .../packet_decl_simple_scalars_big_endian.rs | 29 ++-- ...acket_decl_simple_scalars_little_endian.rs | 29 ++-- tools/pdl/tests/generated/preamble.rs | 22 ++- .../struct_decl_complex_scalars_big_endian.rs | 23 ++-- ...ruct_decl_complex_scalars_little_endian.rs | 23 ++-- tools/pdl/tests/generated_files_compile.sh | 4 +- 75 files changed, 1095 insertions(+), 1304 deletions(-) diff --git a/tools/pdl/Android.bp b/tools/pdl/Android.bp index 5bd51d77a93..df4fd25fbaf 100644 --- a/tools/pdl/Android.bp +++ b/tools/pdl/Android.bp @@ -15,6 +15,7 @@ rust_defaults { "libcodespan_reporting", "libheck", "libpest", + "libprettyplease", "libproc_macro2", "libquote", "libserde", @@ -121,15 +122,7 @@ rust_test_host { "libpaste", ], test_suites: ["general-tests"], - enabled: false, // rustfmt is only available on x86. - arch: { - x86_64: { - enabled: true, - }, - }, data: [ - ":rustfmt", - ":rustfmt.toml", ":pdl_generated_files", ], } diff --git a/tools/pdl/Cargo.toml b/tools/pdl/Cargo.toml index d8da5ff2556..a74c8515e89 100644 --- a/tools/pdl/Cargo.toml +++ b/tools/pdl/Cargo.toml @@ -19,6 +19,7 @@ quote = "1.0.21" serde_json = "1.0.86" argh = "0.1.7" syn = "1.0.102" +prettyplease = "0.1.25" [dependencies.serde] version = "1.0.145" diff --git a/tools/pdl/src/backends/rust.rs b/tools/pdl/src/backends/rust.rs index d7e355b427b..c9101521cb0 100644 --- a/tools/pdl/src/backends/rust.rs +++ b/tools/pdl/src/backends/rust.rs @@ -1012,7 +1012,7 @@ mod tests { use crate::analyzer; use crate::ast; use crate::parser::parse_inline; - use crate::test_utils::{assert_snapshot_eq, rustfmt}; + use crate::test_utils::{assert_snapshot_eq, format_rust}; use paste::paste; /// Parse a string fragment as a PDL file. @@ -1095,7 +1095,7 @@ mod tests { let actual_code = generate(&db, &file); assert_snapshot_eq( &format!("tests/generated/{name}_{endianness}.rs"), - &rustfmt(&actual_code), + &format_rust(&actual_code), ); } } diff --git a/tools/pdl/src/backends/rust/preamble.rs b/tools/pdl/src/backends/rust/preamble.rs index 9b23ede5527..afd84da84a6 100644 --- a/tools/pdl/src/backends/rust/preamble.rs +++ b/tools/pdl/src/backends/rust/preamble.rs @@ -19,7 +19,6 @@ use crate::quote_block; /// Generate the file preamble. pub fn generate(path: &Path) -> String { let mut code = String::new(); - let filename = path.file_name().unwrap().to_str().expect("non UTF-8 filename"); // TODO(mgeisler): Make the generated code free from warnings. // // The code either needs @@ -34,22 +33,35 @@ pub fn generate(path: &Path) -> String { // to the generated code. We cannot add the module-level attribute // here because of how the generated code is used with include! in // lmp/src/packets.rs. - code.push_str(&format!("// @generated rust packets from {filename}\n\n")); - + let filename = path.file_name().unwrap().to_str().expect("non UTF-8 filename"); + let module_doc_string = format!(" @generated rust packets from {filename}."); + // TODO(mgeisler): the doc comment below should be an outer + // comment (#![doc = ...]). However, people include the generated + // code in the middle of another module via include_str!: + // + // fn before() {} + // include_str!("generated.rs") + // fn after() {} + // + // It is illegal to have a //! comment in the middle of a file. We + // should refactor such usages to instead look like this: + // + // fn before() {} + // mod foo { include_str!("generated.rs") } + // use foo::*; + // fn after() {} code.push_str("e_block! { + #[doc = #module_doc_string] + use bytes::{Buf, BufMut, Bytes, BytesMut}; use std::convert::{TryFrom, TryInto}; use std::cell::Cell; use std::fmt; use std::sync::Arc; use thiserror::Error; - }); - code.push_str("e_block! { type Result = std::result::Result; - }); - code.push_str("e_block! { /// Private prevents users from creating arbitrary scalar values /// in situations where the value needs to be validated. /// Users can freely deref the value, but only the backend @@ -100,11 +112,11 @@ pub fn generate(path: &Path) -> String { #[cfg(test)] mod tests { use super::*; - use crate::test_utils::{assert_snapshot_eq, rustfmt}; + use crate::test_utils::{assert_snapshot_eq, format_rust}; #[test] fn test_generate_preamble() { let actual_code = generate(Path::new("some/path/foo.pdl")); - assert_snapshot_eq("tests/generated/preamble.rs", &rustfmt(&actual_code)); + assert_snapshot_eq("tests/generated/preamble.rs", &format_rust(&actual_code)); } } diff --git a/tools/pdl/src/test_utils.rs b/tools/pdl/src/test_utils.rs index 7e618f647eb..13a45fd4fa8 100644 --- a/tools/pdl/src/test_utils.rs +++ b/tools/pdl/src/test_utils.rs @@ -22,54 +22,14 @@ use std::fs; use std::io::Write; use std::path::Path; -use std::process::{Command, Stdio}; +use std::process::Command; use tempfile::NamedTempFile; -/// Search for a binary in `$PATH` or as a sibling to the current -/// executable (typically the test binary). -pub fn find_binary(name: &str) -> Result { - let mut current_exe = std::env::current_exe().unwrap(); - current_exe.pop(); - let paths = std::env::var_os("PATH").unwrap(); - for mut path in std::iter::once(current_exe.clone()).chain(std::env::split_paths(&paths)) { - path.push(name); - if path.exists() { - return Ok(path); - } - } - - Err(format!( - "could not find '{}' in the directory of the binary ({}) or in $PATH ({})", - name, - current_exe.to_string_lossy(), - paths.to_string_lossy(), - )) -} - -/// Run `input` through `rustfmt`. -/// -/// # Panics -/// -/// Panics if `rustfmt` cannot be found in the same directory as the -/// test executable or if it returns a non-zero exit code. -pub fn rustfmt(input: &str) -> String { - let rustfmt_path = find_binary("rustfmt").expect("cannot find rustfmt"); - let mut rustfmt = Command::new(&rustfmt_path) - .stdin(Stdio::piped()) - .stdout(Stdio::piped()) - .spawn() - .unwrap_or_else(|_| panic!("failed to start {:?}", &rustfmt_path)); - - let mut stdin = rustfmt.stdin.take().unwrap(); - // Owned copy which we can move into the writing thread. - let input = String::from(input); - std::thread::spawn(move || { - stdin.write_all(input.as_bytes()).expect("could not write to stdin"); - }); - - let output = rustfmt.wait_with_output().expect("error executing rustfmt"); - assert!(output.status.success(), "rustfmt failed: {}", output.status); - String::from_utf8(output.stdout).expect("rustfmt output was not UTF-8") +/// Format Rust code in `input`. +pub fn format_rust(input: &str) -> String { + let syntax_tree = syn::parse_file(input).expect("Could not parse {input:#?} as Rust code"); + let formatted = prettyplease::unparse(&syntax_tree); + format!("#![rustfmt::skip]\n{formatted}") } /// Find the unified diff between two strings using `diff`. diff --git a/tools/pdl/tests/generated/custom_field_declaration_big_endian.rs b/tools/pdl/tests/generated/custom_field_declaration_big_endian.rs index 3576f1f1ea5..31fa6036c15 100644 --- a/tools/pdl/tests/generated/custom_field_declaration_big_endian.rs +++ b/tools/pdl/tests/generated/custom_field_declaration_big_endian.rs @@ -1,18 +1,16 @@ -// @generated rust packets from test - +#![rustfmt::skip] +/// @generated rust packets from test. use bytes::{Buf, BufMut, Bytes, BytesMut}; -use std::cell::Cell; use std::convert::{TryFrom, TryInto}; +use std::cell::Cell; use std::fmt; use std::sync::Arc; use thiserror::Error; - type Result = std::result::Result; - -#[doc = r" Private prevents users from creating arbitrary scalar values"] -#[doc = r" in situations where the value needs to be validated."] -#[doc = r" Users can freely deref the value, but only the backend"] -#[doc = r" may create it."] +/// Private prevents users from creating arbitrary scalar values +/// in situations where the value needs to be validated. +/// Users can freely deref the value, but only the backend +/// may create it. #[derive(Debug, Clone, Copy, Hash, PartialEq, Eq, PartialOrd, Ord)] pub struct Private(T); impl std::ops::Deref for Private { @@ -21,7 +19,6 @@ impl std::ops::Deref for Private { &self.0 } } - #[derive(Debug, Error)] pub enum Error { #[error("Packet parsing failed")] @@ -32,7 +29,9 @@ pub enum Error { InvalidFixedValue { expected: u64, actual: u64 }, #[error("when parsing {obj} needed length of {wanted} but got {got}")] InvalidLengthError { obj: String, wanted: usize, got: usize }, - #[error("array size ({array} bytes) is not a multiple of the element size ({element} bytes)")] + #[error( + "array size ({array} bytes) is not a multiple of the element size ({element} bytes)" + )] InvalidArraySize { array: usize, element: usize }, #[error("Due to size restrictions a struct could not be parsed.")] ImpossibleStructError, @@ -41,12 +40,10 @@ pub enum Error { #[error("expected child {expected}, got {actual}")] InvalidChildError { expected: &'static str, actual: String }, } - pub trait Packet { fn to_bytes(self) -> Bytes; fn to_vec(self) -> Vec; } - #[derive(Debug, Clone, Copy, Hash, Eq, PartialEq)] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] #[cfg_attr(feature = "serde", serde(from = "u32", into = "u32"))] @@ -66,7 +63,6 @@ impl From for ExactSize { ExactSize(value) } } - #[derive(Debug, Clone, Copy, Hash, Eq, PartialEq)] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] #[cfg_attr(feature = "serde", serde(try_from = "u32", into = "u32"))] @@ -84,10 +80,6 @@ impl From for u32 { impl TryFrom for TruncatedSize { type Error = u32; fn try_from(value: u32) -> std::result::Result { - if value > 0xff_ffff { - Err(value) - } else { - Ok(TruncatedSize(value)) - } + if value > 0xff_ffff { Err(value) } else { Ok(TruncatedSize(value)) } } } diff --git a/tools/pdl/tests/generated/custom_field_declaration_little_endian.rs b/tools/pdl/tests/generated/custom_field_declaration_little_endian.rs index 3576f1f1ea5..31fa6036c15 100644 --- a/tools/pdl/tests/generated/custom_field_declaration_little_endian.rs +++ b/tools/pdl/tests/generated/custom_field_declaration_little_endian.rs @@ -1,18 +1,16 @@ -// @generated rust packets from test - +#![rustfmt::skip] +/// @generated rust packets from test. use bytes::{Buf, BufMut, Bytes, BytesMut}; -use std::cell::Cell; use std::convert::{TryFrom, TryInto}; +use std::cell::Cell; use std::fmt; use std::sync::Arc; use thiserror::Error; - type Result = std::result::Result; - -#[doc = r" Private prevents users from creating arbitrary scalar values"] -#[doc = r" in situations where the value needs to be validated."] -#[doc = r" Users can freely deref the value, but only the backend"] -#[doc = r" may create it."] +/// Private prevents users from creating arbitrary scalar values +/// in situations where the value needs to be validated. +/// Users can freely deref the value, but only the backend +/// may create it. #[derive(Debug, Clone, Copy, Hash, PartialEq, Eq, PartialOrd, Ord)] pub struct Private(T); impl std::ops::Deref for Private { @@ -21,7 +19,6 @@ impl std::ops::Deref for Private { &self.0 } } - #[derive(Debug, Error)] pub enum Error { #[error("Packet parsing failed")] @@ -32,7 +29,9 @@ pub enum Error { InvalidFixedValue { expected: u64, actual: u64 }, #[error("when parsing {obj} needed length of {wanted} but got {got}")] InvalidLengthError { obj: String, wanted: usize, got: usize }, - #[error("array size ({array} bytes) is not a multiple of the element size ({element} bytes)")] + #[error( + "array size ({array} bytes) is not a multiple of the element size ({element} bytes)" + )] InvalidArraySize { array: usize, element: usize }, #[error("Due to size restrictions a struct could not be parsed.")] ImpossibleStructError, @@ -41,12 +40,10 @@ pub enum Error { #[error("expected child {expected}, got {actual}")] InvalidChildError { expected: &'static str, actual: String }, } - pub trait Packet { fn to_bytes(self) -> Bytes; fn to_vec(self) -> Vec; } - #[derive(Debug, Clone, Copy, Hash, Eq, PartialEq)] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] #[cfg_attr(feature = "serde", serde(from = "u32", into = "u32"))] @@ -66,7 +63,6 @@ impl From for ExactSize { ExactSize(value) } } - #[derive(Debug, Clone, Copy, Hash, Eq, PartialEq)] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] #[cfg_attr(feature = "serde", serde(try_from = "u32", into = "u32"))] @@ -84,10 +80,6 @@ impl From for u32 { impl TryFrom for TruncatedSize { type Error = u32; fn try_from(value: u32) -> std::result::Result { - if value > 0xff_ffff { - Err(value) - } else { - Ok(TruncatedSize(value)) - } + if value > 0xff_ffff { Err(value) } else { Ok(TruncatedSize(value)) } } } diff --git a/tools/pdl/tests/generated/enum_declaration_big_endian.rs b/tools/pdl/tests/generated/enum_declaration_big_endian.rs index f598c3408c0..87b5d0eec5c 100644 --- a/tools/pdl/tests/generated/enum_declaration_big_endian.rs +++ b/tools/pdl/tests/generated/enum_declaration_big_endian.rs @@ -1,18 +1,16 @@ -// @generated rust packets from test - +#![rustfmt::skip] +/// @generated rust packets from test. use bytes::{Buf, BufMut, Bytes, BytesMut}; -use std::cell::Cell; use std::convert::{TryFrom, TryInto}; +use std::cell::Cell; use std::fmt; use std::sync::Arc; use thiserror::Error; - type Result = std::result::Result; - -#[doc = r" Private prevents users from creating arbitrary scalar values"] -#[doc = r" in situations where the value needs to be validated."] -#[doc = r" Users can freely deref the value, but only the backend"] -#[doc = r" may create it."] +/// Private prevents users from creating arbitrary scalar values +/// in situations where the value needs to be validated. +/// Users can freely deref the value, but only the backend +/// may create it. #[derive(Debug, Clone, Copy, Hash, PartialEq, Eq, PartialOrd, Ord)] pub struct Private(T); impl std::ops::Deref for Private { @@ -21,7 +19,6 @@ impl std::ops::Deref for Private { &self.0 } } - #[derive(Debug, Error)] pub enum Error { #[error("Packet parsing failed")] @@ -32,7 +29,9 @@ pub enum Error { InvalidFixedValue { expected: u64, actual: u64 }, #[error("when parsing {obj} needed length of {wanted} but got {got}")] InvalidLengthError { obj: String, wanted: usize, got: usize }, - #[error("array size ({array} bytes) is not a multiple of the element size ({element} bytes)")] + #[error( + "array size ({array} bytes) is not a multiple of the element size ({element} bytes)" + )] InvalidArraySize { array: usize, element: usize }, #[error("Due to size restrictions a struct could not be parsed.")] ImpossibleStructError, @@ -41,12 +40,10 @@ pub enum Error { #[error("expected child {expected}, got {actual}")] InvalidChildError { expected: &'static str, actual: String }, } - pub trait Packet { fn to_bytes(self) -> Bytes; fn to_vec(self) -> Vec; } - #[repr(u64)] #[derive(Debug, Clone, Copy, Hash, Eq, PartialEq)] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] @@ -113,7 +110,6 @@ impl From for u64 { u8::from(value) as Self } } - #[derive(Debug, Clone, Copy, Hash, Eq, PartialEq)] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] #[cfg_attr(feature = "serde", serde(try_from = "u8", into = "u8"))] @@ -185,7 +181,6 @@ impl From for u64 { u8::from(value) as Self } } - #[repr(u64)] #[derive(Debug, Clone, Copy, Hash, Eq, PartialEq)] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] @@ -270,7 +265,6 @@ impl From for u64 { u8::from(value) as Self } } - #[derive(Debug, Clone, Copy, Hash, Eq, PartialEq)] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] #[cfg_attr(feature = "serde", serde(try_from = "u8", into = "u8"))] @@ -342,7 +336,6 @@ impl From for u64 { u8::from(value) as Self } } - #[derive(Debug, Clone, Copy, Hash, Eq, PartialEq)] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] #[cfg_attr(feature = "serde", serde(try_from = "u8", into = "u8"))] diff --git a/tools/pdl/tests/generated/enum_declaration_little_endian.rs b/tools/pdl/tests/generated/enum_declaration_little_endian.rs index f598c3408c0..87b5d0eec5c 100644 --- a/tools/pdl/tests/generated/enum_declaration_little_endian.rs +++ b/tools/pdl/tests/generated/enum_declaration_little_endian.rs @@ -1,18 +1,16 @@ -// @generated rust packets from test - +#![rustfmt::skip] +/// @generated rust packets from test. use bytes::{Buf, BufMut, Bytes, BytesMut}; -use std::cell::Cell; use std::convert::{TryFrom, TryInto}; +use std::cell::Cell; use std::fmt; use std::sync::Arc; use thiserror::Error; - type Result = std::result::Result; - -#[doc = r" Private prevents users from creating arbitrary scalar values"] -#[doc = r" in situations where the value needs to be validated."] -#[doc = r" Users can freely deref the value, but only the backend"] -#[doc = r" may create it."] +/// Private prevents users from creating arbitrary scalar values +/// in situations where the value needs to be validated. +/// Users can freely deref the value, but only the backend +/// may create it. #[derive(Debug, Clone, Copy, Hash, PartialEq, Eq, PartialOrd, Ord)] pub struct Private(T); impl std::ops::Deref for Private { @@ -21,7 +19,6 @@ impl std::ops::Deref for Private { &self.0 } } - #[derive(Debug, Error)] pub enum Error { #[error("Packet parsing failed")] @@ -32,7 +29,9 @@ pub enum Error { InvalidFixedValue { expected: u64, actual: u64 }, #[error("when parsing {obj} needed length of {wanted} but got {got}")] InvalidLengthError { obj: String, wanted: usize, got: usize }, - #[error("array size ({array} bytes) is not a multiple of the element size ({element} bytes)")] + #[error( + "array size ({array} bytes) is not a multiple of the element size ({element} bytes)" + )] InvalidArraySize { array: usize, element: usize }, #[error("Due to size restrictions a struct could not be parsed.")] ImpossibleStructError, @@ -41,12 +40,10 @@ pub enum Error { #[error("expected child {expected}, got {actual}")] InvalidChildError { expected: &'static str, actual: String }, } - pub trait Packet { fn to_bytes(self) -> Bytes; fn to_vec(self) -> Vec; } - #[repr(u64)] #[derive(Debug, Clone, Copy, Hash, Eq, PartialEq)] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] @@ -113,7 +110,6 @@ impl From for u64 { u8::from(value) as Self } } - #[derive(Debug, Clone, Copy, Hash, Eq, PartialEq)] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] #[cfg_attr(feature = "serde", serde(try_from = "u8", into = "u8"))] @@ -185,7 +181,6 @@ impl From for u64 { u8::from(value) as Self } } - #[repr(u64)] #[derive(Debug, Clone, Copy, Hash, Eq, PartialEq)] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] @@ -270,7 +265,6 @@ impl From for u64 { u8::from(value) as Self } } - #[derive(Debug, Clone, Copy, Hash, Eq, PartialEq)] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] #[cfg_attr(feature = "serde", serde(try_from = "u8", into = "u8"))] @@ -342,7 +336,6 @@ impl From for u64 { u8::from(value) as Self } } - #[derive(Debug, Clone, Copy, Hash, Eq, PartialEq)] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] #[cfg_attr(feature = "serde", serde(try_from = "u8", into = "u8"))] diff --git a/tools/pdl/tests/generated/packet_decl_24bit_enum_array_big_endian.rs b/tools/pdl/tests/generated/packet_decl_24bit_enum_array_big_endian.rs index 77b7af35271..bd352ef126a 100644 --- a/tools/pdl/tests/generated/packet_decl_24bit_enum_array_big_endian.rs +++ b/tools/pdl/tests/generated/packet_decl_24bit_enum_array_big_endian.rs @@ -1,18 +1,16 @@ -// @generated rust packets from test - +#![rustfmt::skip] +/// @generated rust packets from test. use bytes::{Buf, BufMut, Bytes, BytesMut}; -use std::cell::Cell; use std::convert::{TryFrom, TryInto}; +use std::cell::Cell; use std::fmt; use std::sync::Arc; use thiserror::Error; - type Result = std::result::Result; - -#[doc = r" Private prevents users from creating arbitrary scalar values"] -#[doc = r" in situations where the value needs to be validated."] -#[doc = r" Users can freely deref the value, but only the backend"] -#[doc = r" may create it."] +/// Private prevents users from creating arbitrary scalar values +/// in situations where the value needs to be validated. +/// Users can freely deref the value, but only the backend +/// may create it. #[derive(Debug, Clone, Copy, Hash, PartialEq, Eq, PartialOrd, Ord)] pub struct Private(T); impl std::ops::Deref for Private { @@ -21,7 +19,6 @@ impl std::ops::Deref for Private { &self.0 } } - #[derive(Debug, Error)] pub enum Error { #[error("Packet parsing failed")] @@ -32,7 +29,9 @@ pub enum Error { InvalidFixedValue { expected: u64, actual: u64 }, #[error("when parsing {obj} needed length of {wanted} but got {got}")] InvalidLengthError { obj: String, wanted: usize, got: usize }, - #[error("array size ({array} bytes) is not a multiple of the element size ({element} bytes)")] + #[error( + "array size ({array} bytes) is not a multiple of the element size ({element} bytes)" + )] InvalidArraySize { array: usize, element: usize }, #[error("Due to size restrictions a struct could not be parsed.")] ImpossibleStructError, @@ -41,12 +40,10 @@ pub enum Error { #[error("expected child {expected}, got {actual}")] InvalidChildError { expected: &'static str, actual: String }, } - pub trait Packet { fn to_bytes(self) -> Bytes; fn to_vec(self) -> Vec; } - #[repr(u64)] #[derive(Debug, Clone, Copy, Hash, Eq, PartialEq)] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] @@ -93,7 +90,6 @@ impl From for u64 { u32::from(value) as Self } } - #[derive(Debug, Clone, PartialEq, Eq)] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] pub struct BarData { @@ -129,14 +125,13 @@ impl BarData { } let x = (0..5) .map(|_| { - Foo::try_from(bytes.get_mut().get_uint(3) as u32).map_err(|_| { - Error::InvalidEnumValueError { + Foo::try_from(bytes.get_mut().get_uint(3) as u32) + .map_err(|_| Error::InvalidEnumValueError { obj: "Bar".to_string(), field: String::new(), value: 0, type_: "Foo".to_string(), - } - }) + }) }) .collect::>>()? .try_into() diff --git a/tools/pdl/tests/generated/packet_decl_24bit_enum_array_little_endian.rs b/tools/pdl/tests/generated/packet_decl_24bit_enum_array_little_endian.rs index 74498b4a5eb..5027984e5b6 100644 --- a/tools/pdl/tests/generated/packet_decl_24bit_enum_array_little_endian.rs +++ b/tools/pdl/tests/generated/packet_decl_24bit_enum_array_little_endian.rs @@ -1,18 +1,16 @@ -// @generated rust packets from test - +#![rustfmt::skip] +/// @generated rust packets from test. use bytes::{Buf, BufMut, Bytes, BytesMut}; -use std::cell::Cell; use std::convert::{TryFrom, TryInto}; +use std::cell::Cell; use std::fmt; use std::sync::Arc; use thiserror::Error; - type Result = std::result::Result; - -#[doc = r" Private prevents users from creating arbitrary scalar values"] -#[doc = r" in situations where the value needs to be validated."] -#[doc = r" Users can freely deref the value, but only the backend"] -#[doc = r" may create it."] +/// Private prevents users from creating arbitrary scalar values +/// in situations where the value needs to be validated. +/// Users can freely deref the value, but only the backend +/// may create it. #[derive(Debug, Clone, Copy, Hash, PartialEq, Eq, PartialOrd, Ord)] pub struct Private(T); impl std::ops::Deref for Private { @@ -21,7 +19,6 @@ impl std::ops::Deref for Private { &self.0 } } - #[derive(Debug, Error)] pub enum Error { #[error("Packet parsing failed")] @@ -32,7 +29,9 @@ pub enum Error { InvalidFixedValue { expected: u64, actual: u64 }, #[error("when parsing {obj} needed length of {wanted} but got {got}")] InvalidLengthError { obj: String, wanted: usize, got: usize }, - #[error("array size ({array} bytes) is not a multiple of the element size ({element} bytes)")] + #[error( + "array size ({array} bytes) is not a multiple of the element size ({element} bytes)" + )] InvalidArraySize { array: usize, element: usize }, #[error("Due to size restrictions a struct could not be parsed.")] ImpossibleStructError, @@ -41,12 +40,10 @@ pub enum Error { #[error("expected child {expected}, got {actual}")] InvalidChildError { expected: &'static str, actual: String }, } - pub trait Packet { fn to_bytes(self) -> Bytes; fn to_vec(self) -> Vec; } - #[repr(u64)] #[derive(Debug, Clone, Copy, Hash, Eq, PartialEq)] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] @@ -93,7 +90,6 @@ impl From for u64 { u32::from(value) as Self } } - #[derive(Debug, Clone, PartialEq, Eq)] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] pub struct BarData { @@ -129,14 +125,13 @@ impl BarData { } let x = (0..5) .map(|_| { - Foo::try_from(bytes.get_mut().get_uint_le(3) as u32).map_err(|_| { - Error::InvalidEnumValueError { + Foo::try_from(bytes.get_mut().get_uint_le(3) as u32) + .map_err(|_| Error::InvalidEnumValueError { obj: "Bar".to_string(), field: String::new(), value: 0, type_: "Foo".to_string(), - } - }) + }) }) .collect::>>()? .try_into() diff --git a/tools/pdl/tests/generated/packet_decl_24bit_enum_big_endian.rs b/tools/pdl/tests/generated/packet_decl_24bit_enum_big_endian.rs index 1a7ae4c6bc9..d2b63bebab9 100644 --- a/tools/pdl/tests/generated/packet_decl_24bit_enum_big_endian.rs +++ b/tools/pdl/tests/generated/packet_decl_24bit_enum_big_endian.rs @@ -1,18 +1,16 @@ -// @generated rust packets from test - +#![rustfmt::skip] +/// @generated rust packets from test. use bytes::{Buf, BufMut, Bytes, BytesMut}; -use std::cell::Cell; use std::convert::{TryFrom, TryInto}; +use std::cell::Cell; use std::fmt; use std::sync::Arc; use thiserror::Error; - type Result = std::result::Result; - -#[doc = r" Private prevents users from creating arbitrary scalar values"] -#[doc = r" in situations where the value needs to be validated."] -#[doc = r" Users can freely deref the value, but only the backend"] -#[doc = r" may create it."] +/// Private prevents users from creating arbitrary scalar values +/// in situations where the value needs to be validated. +/// Users can freely deref the value, but only the backend +/// may create it. #[derive(Debug, Clone, Copy, Hash, PartialEq, Eq, PartialOrd, Ord)] pub struct Private(T); impl std::ops::Deref for Private { @@ -21,7 +19,6 @@ impl std::ops::Deref for Private { &self.0 } } - #[derive(Debug, Error)] pub enum Error { #[error("Packet parsing failed")] @@ -32,7 +29,9 @@ pub enum Error { InvalidFixedValue { expected: u64, actual: u64 }, #[error("when parsing {obj} needed length of {wanted} but got {got}")] InvalidLengthError { obj: String, wanted: usize, got: usize }, - #[error("array size ({array} bytes) is not a multiple of the element size ({element} bytes)")] + #[error( + "array size ({array} bytes) is not a multiple of the element size ({element} bytes)" + )] InvalidArraySize { array: usize, element: usize }, #[error("Due to size restrictions a struct could not be parsed.")] ImpossibleStructError, @@ -41,12 +40,10 @@ pub enum Error { #[error("expected child {expected}, got {actual}")] InvalidChildError { expected: &'static str, actual: String }, } - pub trait Packet { fn to_bytes(self) -> Bytes; fn to_vec(self) -> Vec; } - #[repr(u64)] #[derive(Debug, Clone, Copy, Hash, Eq, PartialEq)] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] @@ -93,7 +90,6 @@ impl From for u64 { u32::from(value) as Self } } - #[derive(Debug, Clone, PartialEq, Eq)] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] pub struct BarData { @@ -127,14 +123,13 @@ impl BarData { got: bytes.get().remaining(), }); } - let x = Foo::try_from(bytes.get_mut().get_uint(3) as u32).map_err(|_| { - Error::InvalidEnumValueError { + let x = Foo::try_from(bytes.get_mut().get_uint(3) as u32) + .map_err(|_| Error::InvalidEnumValueError { obj: "Bar".to_string(), field: "x".to_string(), value: bytes.get_mut().get_uint(3) as u32 as u64, type_: "Foo".to_string(), - } - })?; + })?; Ok(Self { x }) } fn write_to(&self, buffer: &mut BytesMut) { diff --git a/tools/pdl/tests/generated/packet_decl_24bit_enum_little_endian.rs b/tools/pdl/tests/generated/packet_decl_24bit_enum_little_endian.rs index 1edc62686cf..40f98945b0d 100644 --- a/tools/pdl/tests/generated/packet_decl_24bit_enum_little_endian.rs +++ b/tools/pdl/tests/generated/packet_decl_24bit_enum_little_endian.rs @@ -1,18 +1,16 @@ -// @generated rust packets from test - +#![rustfmt::skip] +/// @generated rust packets from test. use bytes::{Buf, BufMut, Bytes, BytesMut}; -use std::cell::Cell; use std::convert::{TryFrom, TryInto}; +use std::cell::Cell; use std::fmt; use std::sync::Arc; use thiserror::Error; - type Result = std::result::Result; - -#[doc = r" Private prevents users from creating arbitrary scalar values"] -#[doc = r" in situations where the value needs to be validated."] -#[doc = r" Users can freely deref the value, but only the backend"] -#[doc = r" may create it."] +/// Private prevents users from creating arbitrary scalar values +/// in situations where the value needs to be validated. +/// Users can freely deref the value, but only the backend +/// may create it. #[derive(Debug, Clone, Copy, Hash, PartialEq, Eq, PartialOrd, Ord)] pub struct Private(T); impl std::ops::Deref for Private { @@ -21,7 +19,6 @@ impl std::ops::Deref for Private { &self.0 } } - #[derive(Debug, Error)] pub enum Error { #[error("Packet parsing failed")] @@ -32,7 +29,9 @@ pub enum Error { InvalidFixedValue { expected: u64, actual: u64 }, #[error("when parsing {obj} needed length of {wanted} but got {got}")] InvalidLengthError { obj: String, wanted: usize, got: usize }, - #[error("array size ({array} bytes) is not a multiple of the element size ({element} bytes)")] + #[error( + "array size ({array} bytes) is not a multiple of the element size ({element} bytes)" + )] InvalidArraySize { array: usize, element: usize }, #[error("Due to size restrictions a struct could not be parsed.")] ImpossibleStructError, @@ -41,12 +40,10 @@ pub enum Error { #[error("expected child {expected}, got {actual}")] InvalidChildError { expected: &'static str, actual: String }, } - pub trait Packet { fn to_bytes(self) -> Bytes; fn to_vec(self) -> Vec; } - #[repr(u64)] #[derive(Debug, Clone, Copy, Hash, Eq, PartialEq)] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] @@ -93,7 +90,6 @@ impl From for u64 { u32::from(value) as Self } } - #[derive(Debug, Clone, PartialEq, Eq)] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] pub struct BarData { @@ -127,14 +123,13 @@ impl BarData { got: bytes.get().remaining(), }); } - let x = Foo::try_from(bytes.get_mut().get_uint_le(3) as u32).map_err(|_| { - Error::InvalidEnumValueError { + let x = Foo::try_from(bytes.get_mut().get_uint_le(3) as u32) + .map_err(|_| Error::InvalidEnumValueError { obj: "Bar".to_string(), field: "x".to_string(), value: bytes.get_mut().get_uint_le(3) as u32 as u64, type_: "Foo".to_string(), - } - })?; + })?; Ok(Self { x }) } fn write_to(&self, buffer: &mut BytesMut) { diff --git a/tools/pdl/tests/generated/packet_decl_24bit_scalar_array_big_endian.rs b/tools/pdl/tests/generated/packet_decl_24bit_scalar_array_big_endian.rs index 2289d06265d..eaa75379059 100644 --- a/tools/pdl/tests/generated/packet_decl_24bit_scalar_array_big_endian.rs +++ b/tools/pdl/tests/generated/packet_decl_24bit_scalar_array_big_endian.rs @@ -1,18 +1,16 @@ -// @generated rust packets from test - +#![rustfmt::skip] +/// @generated rust packets from test. use bytes::{Buf, BufMut, Bytes, BytesMut}; -use std::cell::Cell; use std::convert::{TryFrom, TryInto}; +use std::cell::Cell; use std::fmt; use std::sync::Arc; use thiserror::Error; - type Result = std::result::Result; - -#[doc = r" Private prevents users from creating arbitrary scalar values"] -#[doc = r" in situations where the value needs to be validated."] -#[doc = r" Users can freely deref the value, but only the backend"] -#[doc = r" may create it."] +/// Private prevents users from creating arbitrary scalar values +/// in situations where the value needs to be validated. +/// Users can freely deref the value, but only the backend +/// may create it. #[derive(Debug, Clone, Copy, Hash, PartialEq, Eq, PartialOrd, Ord)] pub struct Private(T); impl std::ops::Deref for Private { @@ -21,7 +19,6 @@ impl std::ops::Deref for Private { &self.0 } } - #[derive(Debug, Error)] pub enum Error { #[error("Packet parsing failed")] @@ -32,7 +29,9 @@ pub enum Error { InvalidFixedValue { expected: u64, actual: u64 }, #[error("when parsing {obj} needed length of {wanted} but got {got}")] InvalidLengthError { obj: String, wanted: usize, got: usize }, - #[error("array size ({array} bytes) is not a multiple of the element size ({element} bytes)")] + #[error( + "array size ({array} bytes) is not a multiple of the element size ({element} bytes)" + )] InvalidArraySize { array: usize, element: usize }, #[error("Due to size restrictions a struct could not be parsed.")] ImpossibleStructError, @@ -41,12 +40,10 @@ pub enum Error { #[error("expected child {expected}, got {actual}")] InvalidChildError { expected: &'static str, actual: String }, } - pub trait Packet { fn to_bytes(self) -> Bytes; fn to_vec(self) -> Vec; } - #[derive(Debug, Clone, PartialEq, Eq)] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] pub struct FooData { diff --git a/tools/pdl/tests/generated/packet_decl_24bit_scalar_array_little_endian.rs b/tools/pdl/tests/generated/packet_decl_24bit_scalar_array_little_endian.rs index 8cf1ec587f1..f9878462a9d 100644 --- a/tools/pdl/tests/generated/packet_decl_24bit_scalar_array_little_endian.rs +++ b/tools/pdl/tests/generated/packet_decl_24bit_scalar_array_little_endian.rs @@ -1,18 +1,16 @@ -// @generated rust packets from test - +#![rustfmt::skip] +/// @generated rust packets from test. use bytes::{Buf, BufMut, Bytes, BytesMut}; -use std::cell::Cell; use std::convert::{TryFrom, TryInto}; +use std::cell::Cell; use std::fmt; use std::sync::Arc; use thiserror::Error; - type Result = std::result::Result; - -#[doc = r" Private prevents users from creating arbitrary scalar values"] -#[doc = r" in situations where the value needs to be validated."] -#[doc = r" Users can freely deref the value, but only the backend"] -#[doc = r" may create it."] +/// Private prevents users from creating arbitrary scalar values +/// in situations where the value needs to be validated. +/// Users can freely deref the value, but only the backend +/// may create it. #[derive(Debug, Clone, Copy, Hash, PartialEq, Eq, PartialOrd, Ord)] pub struct Private(T); impl std::ops::Deref for Private { @@ -21,7 +19,6 @@ impl std::ops::Deref for Private { &self.0 } } - #[derive(Debug, Error)] pub enum Error { #[error("Packet parsing failed")] @@ -32,7 +29,9 @@ pub enum Error { InvalidFixedValue { expected: u64, actual: u64 }, #[error("when parsing {obj} needed length of {wanted} but got {got}")] InvalidLengthError { obj: String, wanted: usize, got: usize }, - #[error("array size ({array} bytes) is not a multiple of the element size ({element} bytes)")] + #[error( + "array size ({array} bytes) is not a multiple of the element size ({element} bytes)" + )] InvalidArraySize { array: usize, element: usize }, #[error("Due to size restrictions a struct could not be parsed.")] ImpossibleStructError, @@ -41,12 +40,10 @@ pub enum Error { #[error("expected child {expected}, got {actual}")] InvalidChildError { expected: &'static str, actual: String }, } - pub trait Packet { fn to_bytes(self) -> Bytes; fn to_vec(self) -> Vec; } - #[derive(Debug, Clone, PartialEq, Eq)] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] pub struct FooData { diff --git a/tools/pdl/tests/generated/packet_decl_24bit_scalar_big_endian.rs b/tools/pdl/tests/generated/packet_decl_24bit_scalar_big_endian.rs index 4782eabd3c2..e5aa0e26924 100644 --- a/tools/pdl/tests/generated/packet_decl_24bit_scalar_big_endian.rs +++ b/tools/pdl/tests/generated/packet_decl_24bit_scalar_big_endian.rs @@ -1,18 +1,16 @@ -// @generated rust packets from test - +#![rustfmt::skip] +/// @generated rust packets from test. use bytes::{Buf, BufMut, Bytes, BytesMut}; -use std::cell::Cell; use std::convert::{TryFrom, TryInto}; +use std::cell::Cell; use std::fmt; use std::sync::Arc; use thiserror::Error; - type Result = std::result::Result; - -#[doc = r" Private prevents users from creating arbitrary scalar values"] -#[doc = r" in situations where the value needs to be validated."] -#[doc = r" Users can freely deref the value, but only the backend"] -#[doc = r" may create it."] +/// Private prevents users from creating arbitrary scalar values +/// in situations where the value needs to be validated. +/// Users can freely deref the value, but only the backend +/// may create it. #[derive(Debug, Clone, Copy, Hash, PartialEq, Eq, PartialOrd, Ord)] pub struct Private(T); impl std::ops::Deref for Private { @@ -21,7 +19,6 @@ impl std::ops::Deref for Private { &self.0 } } - #[derive(Debug, Error)] pub enum Error { #[error("Packet parsing failed")] @@ -32,7 +29,9 @@ pub enum Error { InvalidFixedValue { expected: u64, actual: u64 }, #[error("when parsing {obj} needed length of {wanted} but got {got}")] InvalidLengthError { obj: String, wanted: usize, got: usize }, - #[error("array size ({array} bytes) is not a multiple of the element size ({element} bytes)")] + #[error( + "array size ({array} bytes) is not a multiple of the element size ({element} bytes)" + )] InvalidArraySize { array: usize, element: usize }, #[error("Due to size restrictions a struct could not be parsed.")] ImpossibleStructError, @@ -41,12 +40,10 @@ pub enum Error { #[error("expected child {expected}, got {actual}")] InvalidChildError { expected: &'static str, actual: String }, } - pub trait Packet { fn to_bytes(self) -> Bytes; fn to_vec(self) -> Vec; } - #[derive(Debug, Clone, PartialEq, Eq)] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] pub struct FooData { diff --git a/tools/pdl/tests/generated/packet_decl_24bit_scalar_little_endian.rs b/tools/pdl/tests/generated/packet_decl_24bit_scalar_little_endian.rs index a0f1c58e0d8..c9a65ed19b3 100644 --- a/tools/pdl/tests/generated/packet_decl_24bit_scalar_little_endian.rs +++ b/tools/pdl/tests/generated/packet_decl_24bit_scalar_little_endian.rs @@ -1,18 +1,16 @@ -// @generated rust packets from test - +#![rustfmt::skip] +/// @generated rust packets from test. use bytes::{Buf, BufMut, Bytes, BytesMut}; -use std::cell::Cell; use std::convert::{TryFrom, TryInto}; +use std::cell::Cell; use std::fmt; use std::sync::Arc; use thiserror::Error; - type Result = std::result::Result; - -#[doc = r" Private prevents users from creating arbitrary scalar values"] -#[doc = r" in situations where the value needs to be validated."] -#[doc = r" Users can freely deref the value, but only the backend"] -#[doc = r" may create it."] +/// Private prevents users from creating arbitrary scalar values +/// in situations where the value needs to be validated. +/// Users can freely deref the value, but only the backend +/// may create it. #[derive(Debug, Clone, Copy, Hash, PartialEq, Eq, PartialOrd, Ord)] pub struct Private(T); impl std::ops::Deref for Private { @@ -21,7 +19,6 @@ impl std::ops::Deref for Private { &self.0 } } - #[derive(Debug, Error)] pub enum Error { #[error("Packet parsing failed")] @@ -32,7 +29,9 @@ pub enum Error { InvalidFixedValue { expected: u64, actual: u64 }, #[error("when parsing {obj} needed length of {wanted} but got {got}")] InvalidLengthError { obj: String, wanted: usize, got: usize }, - #[error("array size ({array} bytes) is not a multiple of the element size ({element} bytes)")] + #[error( + "array size ({array} bytes) is not a multiple of the element size ({element} bytes)" + )] InvalidArraySize { array: usize, element: usize }, #[error("Due to size restrictions a struct could not be parsed.")] ImpossibleStructError, @@ -41,12 +40,10 @@ pub enum Error { #[error("expected child {expected}, got {actual}")] InvalidChildError { expected: &'static str, actual: String }, } - pub trait Packet { fn to_bytes(self) -> Bytes; fn to_vec(self) -> Vec; } - #[derive(Debug, Clone, PartialEq, Eq)] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] pub struct FooData { diff --git a/tools/pdl/tests/generated/packet_decl_64bit_enum_array_big_endian.rs b/tools/pdl/tests/generated/packet_decl_64bit_enum_array_big_endian.rs index c7ebf8b7795..69409017367 100644 --- a/tools/pdl/tests/generated/packet_decl_64bit_enum_array_big_endian.rs +++ b/tools/pdl/tests/generated/packet_decl_64bit_enum_array_big_endian.rs @@ -1,18 +1,16 @@ -// @generated rust packets from test - +#![rustfmt::skip] +/// @generated rust packets from test. use bytes::{Buf, BufMut, Bytes, BytesMut}; -use std::cell::Cell; use std::convert::{TryFrom, TryInto}; +use std::cell::Cell; use std::fmt; use std::sync::Arc; use thiserror::Error; - type Result = std::result::Result; - -#[doc = r" Private prevents users from creating arbitrary scalar values"] -#[doc = r" in situations where the value needs to be validated."] -#[doc = r" Users can freely deref the value, but only the backend"] -#[doc = r" may create it."] +/// Private prevents users from creating arbitrary scalar values +/// in situations where the value needs to be validated. +/// Users can freely deref the value, but only the backend +/// may create it. #[derive(Debug, Clone, Copy, Hash, PartialEq, Eq, PartialOrd, Ord)] pub struct Private(T); impl std::ops::Deref for Private { @@ -21,7 +19,6 @@ impl std::ops::Deref for Private { &self.0 } } - #[derive(Debug, Error)] pub enum Error { #[error("Packet parsing failed")] @@ -32,7 +29,9 @@ pub enum Error { InvalidFixedValue { expected: u64, actual: u64 }, #[error("when parsing {obj} needed length of {wanted} but got {got}")] InvalidLengthError { obj: String, wanted: usize, got: usize }, - #[error("array size ({array} bytes) is not a multiple of the element size ({element} bytes)")] + #[error( + "array size ({array} bytes) is not a multiple of the element size ({element} bytes)" + )] InvalidArraySize { array: usize, element: usize }, #[error("Due to size restrictions a struct could not be parsed.")] ImpossibleStructError, @@ -41,12 +40,10 @@ pub enum Error { #[error("expected child {expected}, got {actual}")] InvalidChildError { expected: &'static str, actual: String }, } - pub trait Packet { fn to_bytes(self) -> Bytes; fn to_vec(self) -> Vec; } - #[repr(u64)] #[derive(Debug, Clone, Copy, Hash, Eq, PartialEq)] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] @@ -78,7 +75,6 @@ impl From for u64 { (&value).into() } } - #[derive(Debug, Clone, PartialEq, Eq)] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] pub struct BarData { @@ -114,12 +110,13 @@ impl BarData { } let x = (0..7) .map(|_| { - Foo::try_from(bytes.get_mut().get_u64()).map_err(|_| Error::InvalidEnumValueError { - obj: "Bar".to_string(), - field: String::new(), - value: 0, - type_: "Foo".to_string(), - }) + Foo::try_from(bytes.get_mut().get_u64()) + .map_err(|_| Error::InvalidEnumValueError { + obj: "Bar".to_string(), + field: String::new(), + value: 0, + type_: "Foo".to_string(), + }) }) .collect::>>()? .try_into() diff --git a/tools/pdl/tests/generated/packet_decl_64bit_enum_array_little_endian.rs b/tools/pdl/tests/generated/packet_decl_64bit_enum_array_little_endian.rs index d8d0d72110f..a7008b37d02 100644 --- a/tools/pdl/tests/generated/packet_decl_64bit_enum_array_little_endian.rs +++ b/tools/pdl/tests/generated/packet_decl_64bit_enum_array_little_endian.rs @@ -1,18 +1,16 @@ -// @generated rust packets from test - +#![rustfmt::skip] +/// @generated rust packets from test. use bytes::{Buf, BufMut, Bytes, BytesMut}; -use std::cell::Cell; use std::convert::{TryFrom, TryInto}; +use std::cell::Cell; use std::fmt; use std::sync::Arc; use thiserror::Error; - type Result = std::result::Result; - -#[doc = r" Private prevents users from creating arbitrary scalar values"] -#[doc = r" in situations where the value needs to be validated."] -#[doc = r" Users can freely deref the value, but only the backend"] -#[doc = r" may create it."] +/// Private prevents users from creating arbitrary scalar values +/// in situations where the value needs to be validated. +/// Users can freely deref the value, but only the backend +/// may create it. #[derive(Debug, Clone, Copy, Hash, PartialEq, Eq, PartialOrd, Ord)] pub struct Private(T); impl std::ops::Deref for Private { @@ -21,7 +19,6 @@ impl std::ops::Deref for Private { &self.0 } } - #[derive(Debug, Error)] pub enum Error { #[error("Packet parsing failed")] @@ -32,7 +29,9 @@ pub enum Error { InvalidFixedValue { expected: u64, actual: u64 }, #[error("when parsing {obj} needed length of {wanted} but got {got}")] InvalidLengthError { obj: String, wanted: usize, got: usize }, - #[error("array size ({array} bytes) is not a multiple of the element size ({element} bytes)")] + #[error( + "array size ({array} bytes) is not a multiple of the element size ({element} bytes)" + )] InvalidArraySize { array: usize, element: usize }, #[error("Due to size restrictions a struct could not be parsed.")] ImpossibleStructError, @@ -41,12 +40,10 @@ pub enum Error { #[error("expected child {expected}, got {actual}")] InvalidChildError { expected: &'static str, actual: String }, } - pub trait Packet { fn to_bytes(self) -> Bytes; fn to_vec(self) -> Vec; } - #[repr(u64)] #[derive(Debug, Clone, Copy, Hash, Eq, PartialEq)] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] @@ -78,7 +75,6 @@ impl From for u64 { (&value).into() } } - #[derive(Debug, Clone, PartialEq, Eq)] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] pub struct BarData { @@ -114,14 +110,13 @@ impl BarData { } let x = (0..7) .map(|_| { - Foo::try_from(bytes.get_mut().get_u64_le()).map_err(|_| { - Error::InvalidEnumValueError { + Foo::try_from(bytes.get_mut().get_u64_le()) + .map_err(|_| Error::InvalidEnumValueError { obj: "Bar".to_string(), field: String::new(), value: 0, type_: "Foo".to_string(), - } - }) + }) }) .collect::>>()? .try_into() diff --git a/tools/pdl/tests/generated/packet_decl_64bit_enum_big_endian.rs b/tools/pdl/tests/generated/packet_decl_64bit_enum_big_endian.rs index 0dd9553ae73..a8f182c32ee 100644 --- a/tools/pdl/tests/generated/packet_decl_64bit_enum_big_endian.rs +++ b/tools/pdl/tests/generated/packet_decl_64bit_enum_big_endian.rs @@ -1,18 +1,16 @@ -// @generated rust packets from test - +#![rustfmt::skip] +/// @generated rust packets from test. use bytes::{Buf, BufMut, Bytes, BytesMut}; -use std::cell::Cell; use std::convert::{TryFrom, TryInto}; +use std::cell::Cell; use std::fmt; use std::sync::Arc; use thiserror::Error; - type Result = std::result::Result; - -#[doc = r" Private prevents users from creating arbitrary scalar values"] -#[doc = r" in situations where the value needs to be validated."] -#[doc = r" Users can freely deref the value, but only the backend"] -#[doc = r" may create it."] +/// Private prevents users from creating arbitrary scalar values +/// in situations where the value needs to be validated. +/// Users can freely deref the value, but only the backend +/// may create it. #[derive(Debug, Clone, Copy, Hash, PartialEq, Eq, PartialOrd, Ord)] pub struct Private(T); impl std::ops::Deref for Private { @@ -21,7 +19,6 @@ impl std::ops::Deref for Private { &self.0 } } - #[derive(Debug, Error)] pub enum Error { #[error("Packet parsing failed")] @@ -32,7 +29,9 @@ pub enum Error { InvalidFixedValue { expected: u64, actual: u64 }, #[error("when parsing {obj} needed length of {wanted} but got {got}")] InvalidLengthError { obj: String, wanted: usize, got: usize }, - #[error("array size ({array} bytes) is not a multiple of the element size ({element} bytes)")] + #[error( + "array size ({array} bytes) is not a multiple of the element size ({element} bytes)" + )] InvalidArraySize { array: usize, element: usize }, #[error("Due to size restrictions a struct could not be parsed.")] ImpossibleStructError, @@ -41,12 +40,10 @@ pub enum Error { #[error("expected child {expected}, got {actual}")] InvalidChildError { expected: &'static str, actual: String }, } - pub trait Packet { fn to_bytes(self) -> Bytes; fn to_vec(self) -> Vec; } - #[repr(u64)] #[derive(Debug, Clone, Copy, Hash, Eq, PartialEq)] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] @@ -78,7 +75,6 @@ impl From for u64 { (&value).into() } } - #[derive(Debug, Clone, PartialEq, Eq)] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] pub struct BarData { @@ -112,8 +108,8 @@ impl BarData { got: bytes.get().remaining(), }); } - let x = - Foo::try_from(bytes.get_mut().get_u64()).map_err(|_| Error::InvalidEnumValueError { + let x = Foo::try_from(bytes.get_mut().get_u64()) + .map_err(|_| Error::InvalidEnumValueError { obj: "Bar".to_string(), field: "x".to_string(), value: bytes.get_mut().get_u64() as u64, diff --git a/tools/pdl/tests/generated/packet_decl_64bit_enum_little_endian.rs b/tools/pdl/tests/generated/packet_decl_64bit_enum_little_endian.rs index b9182cc2888..8fa8467f9ef 100644 --- a/tools/pdl/tests/generated/packet_decl_64bit_enum_little_endian.rs +++ b/tools/pdl/tests/generated/packet_decl_64bit_enum_little_endian.rs @@ -1,18 +1,16 @@ -// @generated rust packets from test - +#![rustfmt::skip] +/// @generated rust packets from test. use bytes::{Buf, BufMut, Bytes, BytesMut}; -use std::cell::Cell; use std::convert::{TryFrom, TryInto}; +use std::cell::Cell; use std::fmt; use std::sync::Arc; use thiserror::Error; - type Result = std::result::Result; - -#[doc = r" Private prevents users from creating arbitrary scalar values"] -#[doc = r" in situations where the value needs to be validated."] -#[doc = r" Users can freely deref the value, but only the backend"] -#[doc = r" may create it."] +/// Private prevents users from creating arbitrary scalar values +/// in situations where the value needs to be validated. +/// Users can freely deref the value, but only the backend +/// may create it. #[derive(Debug, Clone, Copy, Hash, PartialEq, Eq, PartialOrd, Ord)] pub struct Private(T); impl std::ops::Deref for Private { @@ -21,7 +19,6 @@ impl std::ops::Deref for Private { &self.0 } } - #[derive(Debug, Error)] pub enum Error { #[error("Packet parsing failed")] @@ -32,7 +29,9 @@ pub enum Error { InvalidFixedValue { expected: u64, actual: u64 }, #[error("when parsing {obj} needed length of {wanted} but got {got}")] InvalidLengthError { obj: String, wanted: usize, got: usize }, - #[error("array size ({array} bytes) is not a multiple of the element size ({element} bytes)")] + #[error( + "array size ({array} bytes) is not a multiple of the element size ({element} bytes)" + )] InvalidArraySize { array: usize, element: usize }, #[error("Due to size restrictions a struct could not be parsed.")] ImpossibleStructError, @@ -41,12 +40,10 @@ pub enum Error { #[error("expected child {expected}, got {actual}")] InvalidChildError { expected: &'static str, actual: String }, } - pub trait Packet { fn to_bytes(self) -> Bytes; fn to_vec(self) -> Vec; } - #[repr(u64)] #[derive(Debug, Clone, Copy, Hash, Eq, PartialEq)] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] @@ -78,7 +75,6 @@ impl From for u64 { (&value).into() } } - #[derive(Debug, Clone, PartialEq, Eq)] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] pub struct BarData { @@ -112,14 +108,13 @@ impl BarData { got: bytes.get().remaining(), }); } - let x = Foo::try_from(bytes.get_mut().get_u64_le()).map_err(|_| { - Error::InvalidEnumValueError { + let x = Foo::try_from(bytes.get_mut().get_u64_le()) + .map_err(|_| Error::InvalidEnumValueError { obj: "Bar".to_string(), field: "x".to_string(), value: bytes.get_mut().get_u64_le() as u64, type_: "Foo".to_string(), - } - })?; + })?; Ok(Self { x }) } fn write_to(&self, buffer: &mut BytesMut) { diff --git a/tools/pdl/tests/generated/packet_decl_64bit_scalar_array_big_endian.rs b/tools/pdl/tests/generated/packet_decl_64bit_scalar_array_big_endian.rs index b62eb41fa72..d162424f3c1 100644 --- a/tools/pdl/tests/generated/packet_decl_64bit_scalar_array_big_endian.rs +++ b/tools/pdl/tests/generated/packet_decl_64bit_scalar_array_big_endian.rs @@ -1,18 +1,16 @@ -// @generated rust packets from test - +#![rustfmt::skip] +/// @generated rust packets from test. use bytes::{Buf, BufMut, Bytes, BytesMut}; -use std::cell::Cell; use std::convert::{TryFrom, TryInto}; +use std::cell::Cell; use std::fmt; use std::sync::Arc; use thiserror::Error; - type Result = std::result::Result; - -#[doc = r" Private prevents users from creating arbitrary scalar values"] -#[doc = r" in situations where the value needs to be validated."] -#[doc = r" Users can freely deref the value, but only the backend"] -#[doc = r" may create it."] +/// Private prevents users from creating arbitrary scalar values +/// in situations where the value needs to be validated. +/// Users can freely deref the value, but only the backend +/// may create it. #[derive(Debug, Clone, Copy, Hash, PartialEq, Eq, PartialOrd, Ord)] pub struct Private(T); impl std::ops::Deref for Private { @@ -21,7 +19,6 @@ impl std::ops::Deref for Private { &self.0 } } - #[derive(Debug, Error)] pub enum Error { #[error("Packet parsing failed")] @@ -32,7 +29,9 @@ pub enum Error { InvalidFixedValue { expected: u64, actual: u64 }, #[error("when parsing {obj} needed length of {wanted} but got {got}")] InvalidLengthError { obj: String, wanted: usize, got: usize }, - #[error("array size ({array} bytes) is not a multiple of the element size ({element} bytes)")] + #[error( + "array size ({array} bytes) is not a multiple of the element size ({element} bytes)" + )] InvalidArraySize { array: usize, element: usize }, #[error("Due to size restrictions a struct could not be parsed.")] ImpossibleStructError, @@ -41,12 +40,10 @@ pub enum Error { #[error("expected child {expected}, got {actual}")] InvalidChildError { expected: &'static str, actual: String }, } - pub trait Packet { fn to_bytes(self) -> Bytes; fn to_vec(self) -> Vec; } - #[derive(Debug, Clone, PartialEq, Eq)] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] pub struct FooData { diff --git a/tools/pdl/tests/generated/packet_decl_64bit_scalar_array_little_endian.rs b/tools/pdl/tests/generated/packet_decl_64bit_scalar_array_little_endian.rs index 0aee553e95d..5d8c77ee746 100644 --- a/tools/pdl/tests/generated/packet_decl_64bit_scalar_array_little_endian.rs +++ b/tools/pdl/tests/generated/packet_decl_64bit_scalar_array_little_endian.rs @@ -1,18 +1,16 @@ -// @generated rust packets from test - +#![rustfmt::skip] +/// @generated rust packets from test. use bytes::{Buf, BufMut, Bytes, BytesMut}; -use std::cell::Cell; use std::convert::{TryFrom, TryInto}; +use std::cell::Cell; use std::fmt; use std::sync::Arc; use thiserror::Error; - type Result = std::result::Result; - -#[doc = r" Private prevents users from creating arbitrary scalar values"] -#[doc = r" in situations where the value needs to be validated."] -#[doc = r" Users can freely deref the value, but only the backend"] -#[doc = r" may create it."] +/// Private prevents users from creating arbitrary scalar values +/// in situations where the value needs to be validated. +/// Users can freely deref the value, but only the backend +/// may create it. #[derive(Debug, Clone, Copy, Hash, PartialEq, Eq, PartialOrd, Ord)] pub struct Private(T); impl std::ops::Deref for Private { @@ -21,7 +19,6 @@ impl std::ops::Deref for Private { &self.0 } } - #[derive(Debug, Error)] pub enum Error { #[error("Packet parsing failed")] @@ -32,7 +29,9 @@ pub enum Error { InvalidFixedValue { expected: u64, actual: u64 }, #[error("when parsing {obj} needed length of {wanted} but got {got}")] InvalidLengthError { obj: String, wanted: usize, got: usize }, - #[error("array size ({array} bytes) is not a multiple of the element size ({element} bytes)")] + #[error( + "array size ({array} bytes) is not a multiple of the element size ({element} bytes)" + )] InvalidArraySize { array: usize, element: usize }, #[error("Due to size restrictions a struct could not be parsed.")] ImpossibleStructError, @@ -41,12 +40,10 @@ pub enum Error { #[error("expected child {expected}, got {actual}")] InvalidChildError { expected: &'static str, actual: String }, } - pub trait Packet { fn to_bytes(self) -> Bytes; fn to_vec(self) -> Vec; } - #[derive(Debug, Clone, PartialEq, Eq)] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] pub struct FooData { diff --git a/tools/pdl/tests/generated/packet_decl_64bit_scalar_big_endian.rs b/tools/pdl/tests/generated/packet_decl_64bit_scalar_big_endian.rs index bf640019c1f..176a4af46d8 100644 --- a/tools/pdl/tests/generated/packet_decl_64bit_scalar_big_endian.rs +++ b/tools/pdl/tests/generated/packet_decl_64bit_scalar_big_endian.rs @@ -1,18 +1,16 @@ -// @generated rust packets from test - +#![rustfmt::skip] +/// @generated rust packets from test. use bytes::{Buf, BufMut, Bytes, BytesMut}; -use std::cell::Cell; use std::convert::{TryFrom, TryInto}; +use std::cell::Cell; use std::fmt; use std::sync::Arc; use thiserror::Error; - type Result = std::result::Result; - -#[doc = r" Private prevents users from creating arbitrary scalar values"] -#[doc = r" in situations where the value needs to be validated."] -#[doc = r" Users can freely deref the value, but only the backend"] -#[doc = r" may create it."] +/// Private prevents users from creating arbitrary scalar values +/// in situations where the value needs to be validated. +/// Users can freely deref the value, but only the backend +/// may create it. #[derive(Debug, Clone, Copy, Hash, PartialEq, Eq, PartialOrd, Ord)] pub struct Private(T); impl std::ops::Deref for Private { @@ -21,7 +19,6 @@ impl std::ops::Deref for Private { &self.0 } } - #[derive(Debug, Error)] pub enum Error { #[error("Packet parsing failed")] @@ -32,7 +29,9 @@ pub enum Error { InvalidFixedValue { expected: u64, actual: u64 }, #[error("when parsing {obj} needed length of {wanted} but got {got}")] InvalidLengthError { obj: String, wanted: usize, got: usize }, - #[error("array size ({array} bytes) is not a multiple of the element size ({element} bytes)")] + #[error( + "array size ({array} bytes) is not a multiple of the element size ({element} bytes)" + )] InvalidArraySize { array: usize, element: usize }, #[error("Due to size restrictions a struct could not be parsed.")] ImpossibleStructError, @@ -41,12 +40,10 @@ pub enum Error { #[error("expected child {expected}, got {actual}")] InvalidChildError { expected: &'static str, actual: String }, } - pub trait Packet { fn to_bytes(self) -> Bytes; fn to_vec(self) -> Vec; } - #[derive(Debug, Clone, PartialEq, Eq)] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] pub struct FooData { diff --git a/tools/pdl/tests/generated/packet_decl_64bit_scalar_little_endian.rs b/tools/pdl/tests/generated/packet_decl_64bit_scalar_little_endian.rs index 63d838a41fe..3f26f6c3f69 100644 --- a/tools/pdl/tests/generated/packet_decl_64bit_scalar_little_endian.rs +++ b/tools/pdl/tests/generated/packet_decl_64bit_scalar_little_endian.rs @@ -1,18 +1,16 @@ -// @generated rust packets from test - +#![rustfmt::skip] +/// @generated rust packets from test. use bytes::{Buf, BufMut, Bytes, BytesMut}; -use std::cell::Cell; use std::convert::{TryFrom, TryInto}; +use std::cell::Cell; use std::fmt; use std::sync::Arc; use thiserror::Error; - type Result = std::result::Result; - -#[doc = r" Private prevents users from creating arbitrary scalar values"] -#[doc = r" in situations where the value needs to be validated."] -#[doc = r" Users can freely deref the value, but only the backend"] -#[doc = r" may create it."] +/// Private prevents users from creating arbitrary scalar values +/// in situations where the value needs to be validated. +/// Users can freely deref the value, but only the backend +/// may create it. #[derive(Debug, Clone, Copy, Hash, PartialEq, Eq, PartialOrd, Ord)] pub struct Private(T); impl std::ops::Deref for Private { @@ -21,7 +19,6 @@ impl std::ops::Deref for Private { &self.0 } } - #[derive(Debug, Error)] pub enum Error { #[error("Packet parsing failed")] @@ -32,7 +29,9 @@ pub enum Error { InvalidFixedValue { expected: u64, actual: u64 }, #[error("when parsing {obj} needed length of {wanted} but got {got}")] InvalidLengthError { obj: String, wanted: usize, got: usize }, - #[error("array size ({array} bytes) is not a multiple of the element size ({element} bytes)")] + #[error( + "array size ({array} bytes) is not a multiple of the element size ({element} bytes)" + )] InvalidArraySize { array: usize, element: usize }, #[error("Due to size restrictions a struct could not be parsed.")] ImpossibleStructError, @@ -41,12 +40,10 @@ pub enum Error { #[error("expected child {expected}, got {actual}")] InvalidChildError { expected: &'static str, actual: String }, } - pub trait Packet { fn to_bytes(self) -> Bytes; fn to_vec(self) -> Vec; } - #[derive(Debug, Clone, PartialEq, Eq)] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] pub struct FooData { diff --git a/tools/pdl/tests/generated/packet_decl_8bit_enum_array_big_endian.rs b/tools/pdl/tests/generated/packet_decl_8bit_enum_array_big_endian.rs index bf243090fbe..ef47d85b1f1 100644 --- a/tools/pdl/tests/generated/packet_decl_8bit_enum_array_big_endian.rs +++ b/tools/pdl/tests/generated/packet_decl_8bit_enum_array_big_endian.rs @@ -1,18 +1,16 @@ -// @generated rust packets from test - +#![rustfmt::skip] +/// @generated rust packets from test. use bytes::{Buf, BufMut, Bytes, BytesMut}; -use std::cell::Cell; use std::convert::{TryFrom, TryInto}; +use std::cell::Cell; use std::fmt; use std::sync::Arc; use thiserror::Error; - type Result = std::result::Result; - -#[doc = r" Private prevents users from creating arbitrary scalar values"] -#[doc = r" in situations where the value needs to be validated."] -#[doc = r" Users can freely deref the value, but only the backend"] -#[doc = r" may create it."] +/// Private prevents users from creating arbitrary scalar values +/// in situations where the value needs to be validated. +/// Users can freely deref the value, but only the backend +/// may create it. #[derive(Debug, Clone, Copy, Hash, PartialEq, Eq, PartialOrd, Ord)] pub struct Private(T); impl std::ops::Deref for Private { @@ -21,7 +19,6 @@ impl std::ops::Deref for Private { &self.0 } } - #[derive(Debug, Error)] pub enum Error { #[error("Packet parsing failed")] @@ -32,7 +29,9 @@ pub enum Error { InvalidFixedValue { expected: u64, actual: u64 }, #[error("when parsing {obj} needed length of {wanted} but got {got}")] InvalidLengthError { obj: String, wanted: usize, got: usize }, - #[error("array size ({array} bytes) is not a multiple of the element size ({element} bytes)")] + #[error( + "array size ({array} bytes) is not a multiple of the element size ({element} bytes)" + )] InvalidArraySize { array: usize, element: usize }, #[error("Due to size restrictions a struct could not be parsed.")] ImpossibleStructError, @@ -41,12 +40,10 @@ pub enum Error { #[error("expected child {expected}, got {actual}")] InvalidChildError { expected: &'static str, actual: String }, } - pub trait Packet { fn to_bytes(self) -> Bytes; fn to_vec(self) -> Vec; } - #[repr(u64)] #[derive(Debug, Clone, Copy, Hash, Eq, PartialEq)] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] @@ -108,7 +105,6 @@ impl From for u64 { u8::from(value) as Self } } - #[derive(Debug, Clone, PartialEq, Eq)] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] pub struct BarData { @@ -144,12 +140,13 @@ impl BarData { } let x = (0..3) .map(|_| { - Foo::try_from(bytes.get_mut().get_u8()).map_err(|_| Error::InvalidEnumValueError { - obj: "Bar".to_string(), - field: String::new(), - value: 0, - type_: "Foo".to_string(), - }) + Foo::try_from(bytes.get_mut().get_u8()) + .map_err(|_| Error::InvalidEnumValueError { + obj: "Bar".to_string(), + field: String::new(), + value: 0, + type_: "Foo".to_string(), + }) }) .collect::>>()? .try_into() diff --git a/tools/pdl/tests/generated/packet_decl_8bit_enum_array_little_endian.rs b/tools/pdl/tests/generated/packet_decl_8bit_enum_array_little_endian.rs index bf243090fbe..ef47d85b1f1 100644 --- a/tools/pdl/tests/generated/packet_decl_8bit_enum_array_little_endian.rs +++ b/tools/pdl/tests/generated/packet_decl_8bit_enum_array_little_endian.rs @@ -1,18 +1,16 @@ -// @generated rust packets from test - +#![rustfmt::skip] +/// @generated rust packets from test. use bytes::{Buf, BufMut, Bytes, BytesMut}; -use std::cell::Cell; use std::convert::{TryFrom, TryInto}; +use std::cell::Cell; use std::fmt; use std::sync::Arc; use thiserror::Error; - type Result = std::result::Result; - -#[doc = r" Private prevents users from creating arbitrary scalar values"] -#[doc = r" in situations where the value needs to be validated."] -#[doc = r" Users can freely deref the value, but only the backend"] -#[doc = r" may create it."] +/// Private prevents users from creating arbitrary scalar values +/// in situations where the value needs to be validated. +/// Users can freely deref the value, but only the backend +/// may create it. #[derive(Debug, Clone, Copy, Hash, PartialEq, Eq, PartialOrd, Ord)] pub struct Private(T); impl std::ops::Deref for Private { @@ -21,7 +19,6 @@ impl std::ops::Deref for Private { &self.0 } } - #[derive(Debug, Error)] pub enum Error { #[error("Packet parsing failed")] @@ -32,7 +29,9 @@ pub enum Error { InvalidFixedValue { expected: u64, actual: u64 }, #[error("when parsing {obj} needed length of {wanted} but got {got}")] InvalidLengthError { obj: String, wanted: usize, got: usize }, - #[error("array size ({array} bytes) is not a multiple of the element size ({element} bytes)")] + #[error( + "array size ({array} bytes) is not a multiple of the element size ({element} bytes)" + )] InvalidArraySize { array: usize, element: usize }, #[error("Due to size restrictions a struct could not be parsed.")] ImpossibleStructError, @@ -41,12 +40,10 @@ pub enum Error { #[error("expected child {expected}, got {actual}")] InvalidChildError { expected: &'static str, actual: String }, } - pub trait Packet { fn to_bytes(self) -> Bytes; fn to_vec(self) -> Vec; } - #[repr(u64)] #[derive(Debug, Clone, Copy, Hash, Eq, PartialEq)] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] @@ -108,7 +105,6 @@ impl From for u64 { u8::from(value) as Self } } - #[derive(Debug, Clone, PartialEq, Eq)] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] pub struct BarData { @@ -144,12 +140,13 @@ impl BarData { } let x = (0..3) .map(|_| { - Foo::try_from(bytes.get_mut().get_u8()).map_err(|_| Error::InvalidEnumValueError { - obj: "Bar".to_string(), - field: String::new(), - value: 0, - type_: "Foo".to_string(), - }) + Foo::try_from(bytes.get_mut().get_u8()) + .map_err(|_| Error::InvalidEnumValueError { + obj: "Bar".to_string(), + field: String::new(), + value: 0, + type_: "Foo".to_string(), + }) }) .collect::>>()? .try_into() diff --git a/tools/pdl/tests/generated/packet_decl_8bit_enum_big_endian.rs b/tools/pdl/tests/generated/packet_decl_8bit_enum_big_endian.rs index 60976c9607f..b3c497967f6 100644 --- a/tools/pdl/tests/generated/packet_decl_8bit_enum_big_endian.rs +++ b/tools/pdl/tests/generated/packet_decl_8bit_enum_big_endian.rs @@ -1,18 +1,16 @@ -// @generated rust packets from test - +#![rustfmt::skip] +/// @generated rust packets from test. use bytes::{Buf, BufMut, Bytes, BytesMut}; -use std::cell::Cell; use std::convert::{TryFrom, TryInto}; +use std::cell::Cell; use std::fmt; use std::sync::Arc; use thiserror::Error; - type Result = std::result::Result; - -#[doc = r" Private prevents users from creating arbitrary scalar values"] -#[doc = r" in situations where the value needs to be validated."] -#[doc = r" Users can freely deref the value, but only the backend"] -#[doc = r" may create it."] +/// Private prevents users from creating arbitrary scalar values +/// in situations where the value needs to be validated. +/// Users can freely deref the value, but only the backend +/// may create it. #[derive(Debug, Clone, Copy, Hash, PartialEq, Eq, PartialOrd, Ord)] pub struct Private(T); impl std::ops::Deref for Private { @@ -21,7 +19,6 @@ impl std::ops::Deref for Private { &self.0 } } - #[derive(Debug, Error)] pub enum Error { #[error("Packet parsing failed")] @@ -32,7 +29,9 @@ pub enum Error { InvalidFixedValue { expected: u64, actual: u64 }, #[error("when parsing {obj} needed length of {wanted} but got {got}")] InvalidLengthError { obj: String, wanted: usize, got: usize }, - #[error("array size ({array} bytes) is not a multiple of the element size ({element} bytes)")] + #[error( + "array size ({array} bytes) is not a multiple of the element size ({element} bytes)" + )] InvalidArraySize { array: usize, element: usize }, #[error("Due to size restrictions a struct could not be parsed.")] ImpossibleStructError, @@ -41,12 +40,10 @@ pub enum Error { #[error("expected child {expected}, got {actual}")] InvalidChildError { expected: &'static str, actual: String }, } - pub trait Packet { fn to_bytes(self) -> Bytes; fn to_vec(self) -> Vec; } - #[repr(u64)] #[derive(Debug, Clone, Copy, Hash, Eq, PartialEq)] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] @@ -108,7 +105,6 @@ impl From for u64 { u8::from(value) as Self } } - #[derive(Debug, Clone, PartialEq, Eq)] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] pub struct BarData { @@ -142,8 +138,8 @@ impl BarData { got: bytes.get().remaining(), }); } - let x = - Foo::try_from(bytes.get_mut().get_u8()).map_err(|_| Error::InvalidEnumValueError { + let x = Foo::try_from(bytes.get_mut().get_u8()) + .map_err(|_| Error::InvalidEnumValueError { obj: "Bar".to_string(), field: "x".to_string(), value: bytes.get_mut().get_u8() as u64, diff --git a/tools/pdl/tests/generated/packet_decl_8bit_enum_little_endian.rs b/tools/pdl/tests/generated/packet_decl_8bit_enum_little_endian.rs index 60976c9607f..b3c497967f6 100644 --- a/tools/pdl/tests/generated/packet_decl_8bit_enum_little_endian.rs +++ b/tools/pdl/tests/generated/packet_decl_8bit_enum_little_endian.rs @@ -1,18 +1,16 @@ -// @generated rust packets from test - +#![rustfmt::skip] +/// @generated rust packets from test. use bytes::{Buf, BufMut, Bytes, BytesMut}; -use std::cell::Cell; use std::convert::{TryFrom, TryInto}; +use std::cell::Cell; use std::fmt; use std::sync::Arc; use thiserror::Error; - type Result = std::result::Result; - -#[doc = r" Private prevents users from creating arbitrary scalar values"] -#[doc = r" in situations where the value needs to be validated."] -#[doc = r" Users can freely deref the value, but only the backend"] -#[doc = r" may create it."] +/// Private prevents users from creating arbitrary scalar values +/// in situations where the value needs to be validated. +/// Users can freely deref the value, but only the backend +/// may create it. #[derive(Debug, Clone, Copy, Hash, PartialEq, Eq, PartialOrd, Ord)] pub struct Private(T); impl std::ops::Deref for Private { @@ -21,7 +19,6 @@ impl std::ops::Deref for Private { &self.0 } } - #[derive(Debug, Error)] pub enum Error { #[error("Packet parsing failed")] @@ -32,7 +29,9 @@ pub enum Error { InvalidFixedValue { expected: u64, actual: u64 }, #[error("when parsing {obj} needed length of {wanted} but got {got}")] InvalidLengthError { obj: String, wanted: usize, got: usize }, - #[error("array size ({array} bytes) is not a multiple of the element size ({element} bytes)")] + #[error( + "array size ({array} bytes) is not a multiple of the element size ({element} bytes)" + )] InvalidArraySize { array: usize, element: usize }, #[error("Due to size restrictions a struct could not be parsed.")] ImpossibleStructError, @@ -41,12 +40,10 @@ pub enum Error { #[error("expected child {expected}, got {actual}")] InvalidChildError { expected: &'static str, actual: String }, } - pub trait Packet { fn to_bytes(self) -> Bytes; fn to_vec(self) -> Vec; } - #[repr(u64)] #[derive(Debug, Clone, Copy, Hash, Eq, PartialEq)] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] @@ -108,7 +105,6 @@ impl From for u64 { u8::from(value) as Self } } - #[derive(Debug, Clone, PartialEq, Eq)] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] pub struct BarData { @@ -142,8 +138,8 @@ impl BarData { got: bytes.get().remaining(), }); } - let x = - Foo::try_from(bytes.get_mut().get_u8()).map_err(|_| Error::InvalidEnumValueError { + let x = Foo::try_from(bytes.get_mut().get_u8()) + .map_err(|_| Error::InvalidEnumValueError { obj: "Bar".to_string(), field: "x".to_string(), value: bytes.get_mut().get_u8() as u64, diff --git a/tools/pdl/tests/generated/packet_decl_8bit_scalar_array_big_endian.rs b/tools/pdl/tests/generated/packet_decl_8bit_scalar_array_big_endian.rs index 8a0c287cc12..a1915a28648 100644 --- a/tools/pdl/tests/generated/packet_decl_8bit_scalar_array_big_endian.rs +++ b/tools/pdl/tests/generated/packet_decl_8bit_scalar_array_big_endian.rs @@ -1,18 +1,16 @@ -// @generated rust packets from test - +#![rustfmt::skip] +/// @generated rust packets from test. use bytes::{Buf, BufMut, Bytes, BytesMut}; -use std::cell::Cell; use std::convert::{TryFrom, TryInto}; +use std::cell::Cell; use std::fmt; use std::sync::Arc; use thiserror::Error; - type Result = std::result::Result; - -#[doc = r" Private prevents users from creating arbitrary scalar values"] -#[doc = r" in situations where the value needs to be validated."] -#[doc = r" Users can freely deref the value, but only the backend"] -#[doc = r" may create it."] +/// Private prevents users from creating arbitrary scalar values +/// in situations where the value needs to be validated. +/// Users can freely deref the value, but only the backend +/// may create it. #[derive(Debug, Clone, Copy, Hash, PartialEq, Eq, PartialOrd, Ord)] pub struct Private(T); impl std::ops::Deref for Private { @@ -21,7 +19,6 @@ impl std::ops::Deref for Private { &self.0 } } - #[derive(Debug, Error)] pub enum Error { #[error("Packet parsing failed")] @@ -32,7 +29,9 @@ pub enum Error { InvalidFixedValue { expected: u64, actual: u64 }, #[error("when parsing {obj} needed length of {wanted} but got {got}")] InvalidLengthError { obj: String, wanted: usize, got: usize }, - #[error("array size ({array} bytes) is not a multiple of the element size ({element} bytes)")] + #[error( + "array size ({array} bytes) is not a multiple of the element size ({element} bytes)" + )] InvalidArraySize { array: usize, element: usize }, #[error("Due to size restrictions a struct could not be parsed.")] ImpossibleStructError, @@ -41,12 +40,10 @@ pub enum Error { #[error("expected child {expected}, got {actual}")] InvalidChildError { expected: &'static str, actual: String }, } - pub trait Packet { fn to_bytes(self) -> Bytes; fn to_vec(self) -> Vec; } - #[derive(Debug, Clone, PartialEq, Eq)] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] pub struct FooData { diff --git a/tools/pdl/tests/generated/packet_decl_8bit_scalar_array_little_endian.rs b/tools/pdl/tests/generated/packet_decl_8bit_scalar_array_little_endian.rs index 8a0c287cc12..a1915a28648 100644 --- a/tools/pdl/tests/generated/packet_decl_8bit_scalar_array_little_endian.rs +++ b/tools/pdl/tests/generated/packet_decl_8bit_scalar_array_little_endian.rs @@ -1,18 +1,16 @@ -// @generated rust packets from test - +#![rustfmt::skip] +/// @generated rust packets from test. use bytes::{Buf, BufMut, Bytes, BytesMut}; -use std::cell::Cell; use std::convert::{TryFrom, TryInto}; +use std::cell::Cell; use std::fmt; use std::sync::Arc; use thiserror::Error; - type Result = std::result::Result; - -#[doc = r" Private prevents users from creating arbitrary scalar values"] -#[doc = r" in situations where the value needs to be validated."] -#[doc = r" Users can freely deref the value, but only the backend"] -#[doc = r" may create it."] +/// Private prevents users from creating arbitrary scalar values +/// in situations where the value needs to be validated. +/// Users can freely deref the value, but only the backend +/// may create it. #[derive(Debug, Clone, Copy, Hash, PartialEq, Eq, PartialOrd, Ord)] pub struct Private(T); impl std::ops::Deref for Private { @@ -21,7 +19,6 @@ impl std::ops::Deref for Private { &self.0 } } - #[derive(Debug, Error)] pub enum Error { #[error("Packet parsing failed")] @@ -32,7 +29,9 @@ pub enum Error { InvalidFixedValue { expected: u64, actual: u64 }, #[error("when parsing {obj} needed length of {wanted} but got {got}")] InvalidLengthError { obj: String, wanted: usize, got: usize }, - #[error("array size ({array} bytes) is not a multiple of the element size ({element} bytes)")] + #[error( + "array size ({array} bytes) is not a multiple of the element size ({element} bytes)" + )] InvalidArraySize { array: usize, element: usize }, #[error("Due to size restrictions a struct could not be parsed.")] ImpossibleStructError, @@ -41,12 +40,10 @@ pub enum Error { #[error("expected child {expected}, got {actual}")] InvalidChildError { expected: &'static str, actual: String }, } - pub trait Packet { fn to_bytes(self) -> Bytes; fn to_vec(self) -> Vec; } - #[derive(Debug, Clone, PartialEq, Eq)] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] pub struct FooData { diff --git a/tools/pdl/tests/generated/packet_decl_8bit_scalar_big_endian.rs b/tools/pdl/tests/generated/packet_decl_8bit_scalar_big_endian.rs index 103eeb32ddf..ae3515a5114 100644 --- a/tools/pdl/tests/generated/packet_decl_8bit_scalar_big_endian.rs +++ b/tools/pdl/tests/generated/packet_decl_8bit_scalar_big_endian.rs @@ -1,18 +1,16 @@ -// @generated rust packets from test - +#![rustfmt::skip] +/// @generated rust packets from test. use bytes::{Buf, BufMut, Bytes, BytesMut}; -use std::cell::Cell; use std::convert::{TryFrom, TryInto}; +use std::cell::Cell; use std::fmt; use std::sync::Arc; use thiserror::Error; - type Result = std::result::Result; - -#[doc = r" Private prevents users from creating arbitrary scalar values"] -#[doc = r" in situations where the value needs to be validated."] -#[doc = r" Users can freely deref the value, but only the backend"] -#[doc = r" may create it."] +/// Private prevents users from creating arbitrary scalar values +/// in situations where the value needs to be validated. +/// Users can freely deref the value, but only the backend +/// may create it. #[derive(Debug, Clone, Copy, Hash, PartialEq, Eq, PartialOrd, Ord)] pub struct Private(T); impl std::ops::Deref for Private { @@ -21,7 +19,6 @@ impl std::ops::Deref for Private { &self.0 } } - #[derive(Debug, Error)] pub enum Error { #[error("Packet parsing failed")] @@ -32,7 +29,9 @@ pub enum Error { InvalidFixedValue { expected: u64, actual: u64 }, #[error("when parsing {obj} needed length of {wanted} but got {got}")] InvalidLengthError { obj: String, wanted: usize, got: usize }, - #[error("array size ({array} bytes) is not a multiple of the element size ({element} bytes)")] + #[error( + "array size ({array} bytes) is not a multiple of the element size ({element} bytes)" + )] InvalidArraySize { array: usize, element: usize }, #[error("Due to size restrictions a struct could not be parsed.")] ImpossibleStructError, @@ -41,12 +40,10 @@ pub enum Error { #[error("expected child {expected}, got {actual}")] InvalidChildError { expected: &'static str, actual: String }, } - pub trait Packet { fn to_bytes(self) -> Bytes; fn to_vec(self) -> Vec; } - #[derive(Debug, Clone, PartialEq, Eq)] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] pub struct FooData { diff --git a/tools/pdl/tests/generated/packet_decl_8bit_scalar_little_endian.rs b/tools/pdl/tests/generated/packet_decl_8bit_scalar_little_endian.rs index 103eeb32ddf..ae3515a5114 100644 --- a/tools/pdl/tests/generated/packet_decl_8bit_scalar_little_endian.rs +++ b/tools/pdl/tests/generated/packet_decl_8bit_scalar_little_endian.rs @@ -1,18 +1,16 @@ -// @generated rust packets from test - +#![rustfmt::skip] +/// @generated rust packets from test. use bytes::{Buf, BufMut, Bytes, BytesMut}; -use std::cell::Cell; use std::convert::{TryFrom, TryInto}; +use std::cell::Cell; use std::fmt; use std::sync::Arc; use thiserror::Error; - type Result = std::result::Result; - -#[doc = r" Private prevents users from creating arbitrary scalar values"] -#[doc = r" in situations where the value needs to be validated."] -#[doc = r" Users can freely deref the value, but only the backend"] -#[doc = r" may create it."] +/// Private prevents users from creating arbitrary scalar values +/// in situations where the value needs to be validated. +/// Users can freely deref the value, but only the backend +/// may create it. #[derive(Debug, Clone, Copy, Hash, PartialEq, Eq, PartialOrd, Ord)] pub struct Private(T); impl std::ops::Deref for Private { @@ -21,7 +19,6 @@ impl std::ops::Deref for Private { &self.0 } } - #[derive(Debug, Error)] pub enum Error { #[error("Packet parsing failed")] @@ -32,7 +29,9 @@ pub enum Error { InvalidFixedValue { expected: u64, actual: u64 }, #[error("when parsing {obj} needed length of {wanted} but got {got}")] InvalidLengthError { obj: String, wanted: usize, got: usize }, - #[error("array size ({array} bytes) is not a multiple of the element size ({element} bytes)")] + #[error( + "array size ({array} bytes) is not a multiple of the element size ({element} bytes)" + )] InvalidArraySize { array: usize, element: usize }, #[error("Due to size restrictions a struct could not be parsed.")] ImpossibleStructError, @@ -41,12 +40,10 @@ pub enum Error { #[error("expected child {expected}, got {actual}")] InvalidChildError { expected: &'static str, actual: String }, } - pub trait Packet { fn to_bytes(self) -> Bytes; fn to_vec(self) -> Vec; } - #[derive(Debug, Clone, PartialEq, Eq)] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] pub struct FooData { diff --git a/tools/pdl/tests/generated/packet_decl_array_dynamic_count_big_endian.rs b/tools/pdl/tests/generated/packet_decl_array_dynamic_count_big_endian.rs index 3628db4666f..c9a5e221a8c 100644 --- a/tools/pdl/tests/generated/packet_decl_array_dynamic_count_big_endian.rs +++ b/tools/pdl/tests/generated/packet_decl_array_dynamic_count_big_endian.rs @@ -1,18 +1,16 @@ -// @generated rust packets from test - +#![rustfmt::skip] +/// @generated rust packets from test. use bytes::{Buf, BufMut, Bytes, BytesMut}; -use std::cell::Cell; use std::convert::{TryFrom, TryInto}; +use std::cell::Cell; use std::fmt; use std::sync::Arc; use thiserror::Error; - type Result = std::result::Result; - -#[doc = r" Private prevents users from creating arbitrary scalar values"] -#[doc = r" in situations where the value needs to be validated."] -#[doc = r" Users can freely deref the value, but only the backend"] -#[doc = r" may create it."] +/// Private prevents users from creating arbitrary scalar values +/// in situations where the value needs to be validated. +/// Users can freely deref the value, but only the backend +/// may create it. #[derive(Debug, Clone, Copy, Hash, PartialEq, Eq, PartialOrd, Ord)] pub struct Private(T); impl std::ops::Deref for Private { @@ -21,7 +19,6 @@ impl std::ops::Deref for Private { &self.0 } } - #[derive(Debug, Error)] pub enum Error { #[error("Packet parsing failed")] @@ -32,7 +29,9 @@ pub enum Error { InvalidFixedValue { expected: u64, actual: u64 }, #[error("when parsing {obj} needed length of {wanted} but got {got}")] InvalidLengthError { obj: String, wanted: usize, got: usize }, - #[error("array size ({array} bytes) is not a multiple of the element size ({element} bytes)")] + #[error( + "array size ({array} bytes) is not a multiple of the element size ({element} bytes)" + )] InvalidArraySize { array: usize, element: usize }, #[error("Due to size restrictions a struct could not be parsed.")] ImpossibleStructError, @@ -41,12 +40,10 @@ pub enum Error { #[error("expected child {expected}, got {actual}")] InvalidChildError { expected: &'static str, actual: String }, } - pub trait Packet { fn to_bytes(self) -> Bytes; fn to_vec(self) -> Vec; } - #[derive(Debug, Clone, PartialEq, Eq)] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] pub struct FooData { @@ -102,7 +99,9 @@ impl FooData { panic!("Invalid length for {}::{}: {} > {}", "Foo", "x", self.x.len(), 0x1f); } if self.padding > 0x7 { - panic!("Invalid value for {}::{}: {} > {}", "Foo", "padding", self.padding, 0x7); + panic!( + "Invalid value for {}::{}: {} > {}", "Foo", "padding", self.padding, 0x7 + ); } let value = self.x.len() as u8 | (self.padding << 5); buffer.put_u8(value); @@ -165,7 +164,10 @@ impl Foo { } impl FooBuilder { pub fn build(self) -> Foo { - let foo = Arc::new(FooData { padding: self.padding, x: self.x }); + let foo = Arc::new(FooData { + padding: self.padding, + x: self.x, + }); Foo::new(foo).unwrap() } } diff --git a/tools/pdl/tests/generated/packet_decl_array_dynamic_count_little_endian.rs b/tools/pdl/tests/generated/packet_decl_array_dynamic_count_little_endian.rs index ef8c84955d9..7a9f27fbf79 100644 --- a/tools/pdl/tests/generated/packet_decl_array_dynamic_count_little_endian.rs +++ b/tools/pdl/tests/generated/packet_decl_array_dynamic_count_little_endian.rs @@ -1,18 +1,16 @@ -// @generated rust packets from test - +#![rustfmt::skip] +/// @generated rust packets from test. use bytes::{Buf, BufMut, Bytes, BytesMut}; -use std::cell::Cell; use std::convert::{TryFrom, TryInto}; +use std::cell::Cell; use std::fmt; use std::sync::Arc; use thiserror::Error; - type Result = std::result::Result; - -#[doc = r" Private prevents users from creating arbitrary scalar values"] -#[doc = r" in situations where the value needs to be validated."] -#[doc = r" Users can freely deref the value, but only the backend"] -#[doc = r" may create it."] +/// Private prevents users from creating arbitrary scalar values +/// in situations where the value needs to be validated. +/// Users can freely deref the value, but only the backend +/// may create it. #[derive(Debug, Clone, Copy, Hash, PartialEq, Eq, PartialOrd, Ord)] pub struct Private(T); impl std::ops::Deref for Private { @@ -21,7 +19,6 @@ impl std::ops::Deref for Private { &self.0 } } - #[derive(Debug, Error)] pub enum Error { #[error("Packet parsing failed")] @@ -32,7 +29,9 @@ pub enum Error { InvalidFixedValue { expected: u64, actual: u64 }, #[error("when parsing {obj} needed length of {wanted} but got {got}")] InvalidLengthError { obj: String, wanted: usize, got: usize }, - #[error("array size ({array} bytes) is not a multiple of the element size ({element} bytes)")] + #[error( + "array size ({array} bytes) is not a multiple of the element size ({element} bytes)" + )] InvalidArraySize { array: usize, element: usize }, #[error("Due to size restrictions a struct could not be parsed.")] ImpossibleStructError, @@ -41,12 +40,10 @@ pub enum Error { #[error("expected child {expected}, got {actual}")] InvalidChildError { expected: &'static str, actual: String }, } - pub trait Packet { fn to_bytes(self) -> Bytes; fn to_vec(self) -> Vec; } - #[derive(Debug, Clone, PartialEq, Eq)] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] pub struct FooData { @@ -102,7 +99,9 @@ impl FooData { panic!("Invalid length for {}::{}: {} > {}", "Foo", "x", self.x.len(), 0x1f); } if self.padding > 0x7 { - panic!("Invalid value for {}::{}: {} > {}", "Foo", "padding", self.padding, 0x7); + panic!( + "Invalid value for {}::{}: {} > {}", "Foo", "padding", self.padding, 0x7 + ); } let value = self.x.len() as u8 | (self.padding << 5); buffer.put_u8(value); @@ -165,7 +164,10 @@ impl Foo { } impl FooBuilder { pub fn build(self) -> Foo { - let foo = Arc::new(FooData { padding: self.padding, x: self.x }); + let foo = Arc::new(FooData { + padding: self.padding, + x: self.x, + }); Foo::new(foo).unwrap() } } diff --git a/tools/pdl/tests/generated/packet_decl_array_dynamic_size_big_endian.rs b/tools/pdl/tests/generated/packet_decl_array_dynamic_size_big_endian.rs index 7148196e291..ec487365ea7 100644 --- a/tools/pdl/tests/generated/packet_decl_array_dynamic_size_big_endian.rs +++ b/tools/pdl/tests/generated/packet_decl_array_dynamic_size_big_endian.rs @@ -1,18 +1,16 @@ -// @generated rust packets from test - +#![rustfmt::skip] +/// @generated rust packets from test. use bytes::{Buf, BufMut, Bytes, BytesMut}; -use std::cell::Cell; use std::convert::{TryFrom, TryInto}; +use std::cell::Cell; use std::fmt; use std::sync::Arc; use thiserror::Error; - type Result = std::result::Result; - -#[doc = r" Private prevents users from creating arbitrary scalar values"] -#[doc = r" in situations where the value needs to be validated."] -#[doc = r" Users can freely deref the value, but only the backend"] -#[doc = r" may create it."] +/// Private prevents users from creating arbitrary scalar values +/// in situations where the value needs to be validated. +/// Users can freely deref the value, but only the backend +/// may create it. #[derive(Debug, Clone, Copy, Hash, PartialEq, Eq, PartialOrd, Ord)] pub struct Private(T); impl std::ops::Deref for Private { @@ -21,7 +19,6 @@ impl std::ops::Deref for Private { &self.0 } } - #[derive(Debug, Error)] pub enum Error { #[error("Packet parsing failed")] @@ -32,7 +29,9 @@ pub enum Error { InvalidFixedValue { expected: u64, actual: u64 }, #[error("when parsing {obj} needed length of {wanted} but got {got}")] InvalidLengthError { obj: String, wanted: usize, got: usize }, - #[error("array size ({array} bytes) is not a multiple of the element size ({element} bytes)")] + #[error( + "array size ({array} bytes) is not a multiple of the element size ({element} bytes)" + )] InvalidArraySize { array: usize, element: usize }, #[error("Due to size restrictions a struct could not be parsed.")] ImpossibleStructError, @@ -41,12 +40,10 @@ pub enum Error { #[error("expected child {expected}, got {actual}")] InvalidChildError { expected: &'static str, actual: String }, } - pub trait Packet { fn to_bytes(self) -> Bytes; fn to_vec(self) -> Vec; } - #[derive(Debug, Clone, PartialEq, Eq)] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] pub struct FooData { @@ -93,7 +90,10 @@ impl FooData { }); } if x_size % 3 != 0 { - return Err(Error::InvalidArraySize { array: x_size, element: 3 }); + return Err(Error::InvalidArraySize { + array: x_size, + element: 3, + }); } let x_count = x_size / 3; let mut x = Vec::with_capacity(x_count); @@ -104,10 +104,15 @@ impl FooData { } fn write_to(&self, buffer: &mut BytesMut) { if (self.x.len() * 3) > 0x1f { - panic!("Invalid length for {}::{}: {} > {}", "Foo", "x", (self.x.len() * 3), 0x1f); + panic!( + "Invalid length for {}::{}: {} > {}", "Foo", "x", (self.x.len() * 3), + 0x1f + ); } if self.padding > 0x7 { - panic!("Invalid value for {}::{}: {} > {}", "Foo", "padding", self.padding, 0x7); + panic!( + "Invalid value for {}::{}: {} > {}", "Foo", "padding", self.padding, 0x7 + ); } let value = (self.x.len() * 3) as u8 | (self.padding << 5); buffer.put_u8(value); @@ -170,7 +175,10 @@ impl Foo { } impl FooBuilder { pub fn build(self) -> Foo { - let foo = Arc::new(FooData { padding: self.padding, x: self.x }); + let foo = Arc::new(FooData { + padding: self.padding, + x: self.x, + }); Foo::new(foo).unwrap() } } diff --git a/tools/pdl/tests/generated/packet_decl_array_dynamic_size_little_endian.rs b/tools/pdl/tests/generated/packet_decl_array_dynamic_size_little_endian.rs index 6645cf2f411..cec18ee62c4 100644 --- a/tools/pdl/tests/generated/packet_decl_array_dynamic_size_little_endian.rs +++ b/tools/pdl/tests/generated/packet_decl_array_dynamic_size_little_endian.rs @@ -1,18 +1,16 @@ -// @generated rust packets from test - +#![rustfmt::skip] +/// @generated rust packets from test. use bytes::{Buf, BufMut, Bytes, BytesMut}; -use std::cell::Cell; use std::convert::{TryFrom, TryInto}; +use std::cell::Cell; use std::fmt; use std::sync::Arc; use thiserror::Error; - type Result = std::result::Result; - -#[doc = r" Private prevents users from creating arbitrary scalar values"] -#[doc = r" in situations where the value needs to be validated."] -#[doc = r" Users can freely deref the value, but only the backend"] -#[doc = r" may create it."] +/// Private prevents users from creating arbitrary scalar values +/// in situations where the value needs to be validated. +/// Users can freely deref the value, but only the backend +/// may create it. #[derive(Debug, Clone, Copy, Hash, PartialEq, Eq, PartialOrd, Ord)] pub struct Private(T); impl std::ops::Deref for Private { @@ -21,7 +19,6 @@ impl std::ops::Deref for Private { &self.0 } } - #[derive(Debug, Error)] pub enum Error { #[error("Packet parsing failed")] @@ -32,7 +29,9 @@ pub enum Error { InvalidFixedValue { expected: u64, actual: u64 }, #[error("when parsing {obj} needed length of {wanted} but got {got}")] InvalidLengthError { obj: String, wanted: usize, got: usize }, - #[error("array size ({array} bytes) is not a multiple of the element size ({element} bytes)")] + #[error( + "array size ({array} bytes) is not a multiple of the element size ({element} bytes)" + )] InvalidArraySize { array: usize, element: usize }, #[error("Due to size restrictions a struct could not be parsed.")] ImpossibleStructError, @@ -41,12 +40,10 @@ pub enum Error { #[error("expected child {expected}, got {actual}")] InvalidChildError { expected: &'static str, actual: String }, } - pub trait Packet { fn to_bytes(self) -> Bytes; fn to_vec(self) -> Vec; } - #[derive(Debug, Clone, PartialEq, Eq)] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] pub struct FooData { @@ -93,7 +90,10 @@ impl FooData { }); } if x_size % 3 != 0 { - return Err(Error::InvalidArraySize { array: x_size, element: 3 }); + return Err(Error::InvalidArraySize { + array: x_size, + element: 3, + }); } let x_count = x_size / 3; let mut x = Vec::with_capacity(x_count); @@ -104,10 +104,15 @@ impl FooData { } fn write_to(&self, buffer: &mut BytesMut) { if (self.x.len() * 3) > 0x1f { - panic!("Invalid length for {}::{}: {} > {}", "Foo", "x", (self.x.len() * 3), 0x1f); + panic!( + "Invalid length for {}::{}: {} > {}", "Foo", "x", (self.x.len() * 3), + 0x1f + ); } if self.padding > 0x7 { - panic!("Invalid value for {}::{}: {} > {}", "Foo", "padding", self.padding, 0x7); + panic!( + "Invalid value for {}::{}: {} > {}", "Foo", "padding", self.padding, 0x7 + ); } let value = (self.x.len() * 3) as u8 | (self.padding << 5); buffer.put_u8(value); @@ -170,7 +175,10 @@ impl Foo { } impl FooBuilder { pub fn build(self) -> Foo { - let foo = Arc::new(FooData { padding: self.padding, x: self.x }); + let foo = Arc::new(FooData { + padding: self.padding, + x: self.x, + }); Foo::new(foo).unwrap() } } diff --git a/tools/pdl/tests/generated/packet_decl_array_unknown_element_width_dynamic_count_big_endian.rs b/tools/pdl/tests/generated/packet_decl_array_unknown_element_width_dynamic_count_big_endian.rs index e1a54c7f82c..b57eb296653 100644 --- a/tools/pdl/tests/generated/packet_decl_array_unknown_element_width_dynamic_count_big_endian.rs +++ b/tools/pdl/tests/generated/packet_decl_array_unknown_element_width_dynamic_count_big_endian.rs @@ -1,18 +1,16 @@ -// @generated rust packets from test - +#![rustfmt::skip] +/// @generated rust packets from test. use bytes::{Buf, BufMut, Bytes, BytesMut}; -use std::cell::Cell; use std::convert::{TryFrom, TryInto}; +use std::cell::Cell; use std::fmt; use std::sync::Arc; use thiserror::Error; - type Result = std::result::Result; - -#[doc = r" Private prevents users from creating arbitrary scalar values"] -#[doc = r" in situations where the value needs to be validated."] -#[doc = r" Users can freely deref the value, but only the backend"] -#[doc = r" may create it."] +/// Private prevents users from creating arbitrary scalar values +/// in situations where the value needs to be validated. +/// Users can freely deref the value, but only the backend +/// may create it. #[derive(Debug, Clone, Copy, Hash, PartialEq, Eq, PartialOrd, Ord)] pub struct Private(T); impl std::ops::Deref for Private { @@ -21,7 +19,6 @@ impl std::ops::Deref for Private { &self.0 } } - #[derive(Debug, Error)] pub enum Error { #[error("Packet parsing failed")] @@ -32,7 +29,9 @@ pub enum Error { InvalidFixedValue { expected: u64, actual: u64 }, #[error("when parsing {obj} needed length of {wanted} but got {got}")] InvalidLengthError { obj: String, wanted: usize, got: usize }, - #[error("array size ({array} bytes) is not a multiple of the element size ({element} bytes)")] + #[error( + "array size ({array} bytes) is not a multiple of the element size ({element} bytes)" + )] InvalidArraySize { array: usize, element: usize }, #[error("Due to size restrictions a struct could not be parsed.")] ImpossibleStructError, @@ -41,12 +40,10 @@ pub enum Error { #[error("expected child {expected}, got {actual}")] InvalidChildError { expected: &'static str, actual: String }, } - pub trait Packet { fn to_bytes(self) -> Bytes; fn to_vec(self) -> Vec; } - #[derive(Debug, Clone, PartialEq, Eq)] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] pub struct Foo { @@ -85,10 +82,7 @@ impl Foo { fn write_to(&self, buffer: &mut BytesMut) { if self.a.len() > 0xff_ffff_ffff_usize { panic!( - "Invalid length for {}::{}: {} > {}", - "Foo", - "a", - self.a.len(), + "Invalid length for {}::{}: {} > {}", "Foo", "a", self.a.len(), 0xff_ffff_ffff_usize ); } @@ -104,7 +98,6 @@ impl Foo { 5 + self.a.len() * 2 } } - #[derive(Debug, Clone, PartialEq, Eq)] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] pub struct BarData { @@ -139,16 +132,15 @@ impl BarData { }); } let x_count = bytes.get_mut().get_uint(5) as usize; - let x = (0..x_count).map(|_| Foo::parse_inner(bytes)).collect::>>()?; + let x = (0..x_count) + .map(|_| Foo::parse_inner(bytes)) + .collect::>>()?; Ok(Self { x }) } fn write_to(&self, buffer: &mut BytesMut) { if self.x.len() > 0xff_ffff_ffff_usize { panic!( - "Invalid length for {}::{}: {} > {}", - "Bar", - "x", - self.x.len(), + "Invalid length for {}::{}: {} > {}", "Bar", "x", self.x.len(), 0xff_ffff_ffff_usize ); } diff --git a/tools/pdl/tests/generated/packet_decl_array_unknown_element_width_dynamic_count_little_endian.rs b/tools/pdl/tests/generated/packet_decl_array_unknown_element_width_dynamic_count_little_endian.rs index 4a1e47c6b9c..3fb7990f4d6 100644 --- a/tools/pdl/tests/generated/packet_decl_array_unknown_element_width_dynamic_count_little_endian.rs +++ b/tools/pdl/tests/generated/packet_decl_array_unknown_element_width_dynamic_count_little_endian.rs @@ -1,18 +1,16 @@ -// @generated rust packets from test - +#![rustfmt::skip] +/// @generated rust packets from test. use bytes::{Buf, BufMut, Bytes, BytesMut}; -use std::cell::Cell; use std::convert::{TryFrom, TryInto}; +use std::cell::Cell; use std::fmt; use std::sync::Arc; use thiserror::Error; - type Result = std::result::Result; - -#[doc = r" Private prevents users from creating arbitrary scalar values"] -#[doc = r" in situations where the value needs to be validated."] -#[doc = r" Users can freely deref the value, but only the backend"] -#[doc = r" may create it."] +/// Private prevents users from creating arbitrary scalar values +/// in situations where the value needs to be validated. +/// Users can freely deref the value, but only the backend +/// may create it. #[derive(Debug, Clone, Copy, Hash, PartialEq, Eq, PartialOrd, Ord)] pub struct Private(T); impl std::ops::Deref for Private { @@ -21,7 +19,6 @@ impl std::ops::Deref for Private { &self.0 } } - #[derive(Debug, Error)] pub enum Error { #[error("Packet parsing failed")] @@ -32,7 +29,9 @@ pub enum Error { InvalidFixedValue { expected: u64, actual: u64 }, #[error("when parsing {obj} needed length of {wanted} but got {got}")] InvalidLengthError { obj: String, wanted: usize, got: usize }, - #[error("array size ({array} bytes) is not a multiple of the element size ({element} bytes)")] + #[error( + "array size ({array} bytes) is not a multiple of the element size ({element} bytes)" + )] InvalidArraySize { array: usize, element: usize }, #[error("Due to size restrictions a struct could not be parsed.")] ImpossibleStructError, @@ -41,12 +40,10 @@ pub enum Error { #[error("expected child {expected}, got {actual}")] InvalidChildError { expected: &'static str, actual: String }, } - pub trait Packet { fn to_bytes(self) -> Bytes; fn to_vec(self) -> Vec; } - #[derive(Debug, Clone, PartialEq, Eq)] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] pub struct Foo { @@ -85,10 +82,7 @@ impl Foo { fn write_to(&self, buffer: &mut BytesMut) { if self.a.len() > 0xff_ffff_ffff_usize { panic!( - "Invalid length for {}::{}: {} > {}", - "Foo", - "a", - self.a.len(), + "Invalid length for {}::{}: {} > {}", "Foo", "a", self.a.len(), 0xff_ffff_ffff_usize ); } @@ -104,7 +98,6 @@ impl Foo { 5 + self.a.len() * 2 } } - #[derive(Debug, Clone, PartialEq, Eq)] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] pub struct BarData { @@ -139,16 +132,15 @@ impl BarData { }); } let x_count = bytes.get_mut().get_uint_le(5) as usize; - let x = (0..x_count).map(|_| Foo::parse_inner(bytes)).collect::>>()?; + let x = (0..x_count) + .map(|_| Foo::parse_inner(bytes)) + .collect::>>()?; Ok(Self { x }) } fn write_to(&self, buffer: &mut BytesMut) { if self.x.len() > 0xff_ffff_ffff_usize { panic!( - "Invalid length for {}::{}: {} > {}", - "Bar", - "x", - self.x.len(), + "Invalid length for {}::{}: {} > {}", "Bar", "x", self.x.len(), 0xff_ffff_ffff_usize ); } diff --git a/tools/pdl/tests/generated/packet_decl_array_unknown_element_width_dynamic_size_big_endian.rs b/tools/pdl/tests/generated/packet_decl_array_unknown_element_width_dynamic_size_big_endian.rs index efd41a25a4f..ee4459e5978 100644 --- a/tools/pdl/tests/generated/packet_decl_array_unknown_element_width_dynamic_size_big_endian.rs +++ b/tools/pdl/tests/generated/packet_decl_array_unknown_element_width_dynamic_size_big_endian.rs @@ -1,18 +1,16 @@ -// @generated rust packets from test - +#![rustfmt::skip] +/// @generated rust packets from test. use bytes::{Buf, BufMut, Bytes, BytesMut}; -use std::cell::Cell; use std::convert::{TryFrom, TryInto}; +use std::cell::Cell; use std::fmt; use std::sync::Arc; use thiserror::Error; - type Result = std::result::Result; - -#[doc = r" Private prevents users from creating arbitrary scalar values"] -#[doc = r" in situations where the value needs to be validated."] -#[doc = r" Users can freely deref the value, but only the backend"] -#[doc = r" may create it."] +/// Private prevents users from creating arbitrary scalar values +/// in situations where the value needs to be validated. +/// Users can freely deref the value, but only the backend +/// may create it. #[derive(Debug, Clone, Copy, Hash, PartialEq, Eq, PartialOrd, Ord)] pub struct Private(T); impl std::ops::Deref for Private { @@ -21,7 +19,6 @@ impl std::ops::Deref for Private { &self.0 } } - #[derive(Debug, Error)] pub enum Error { #[error("Packet parsing failed")] @@ -32,7 +29,9 @@ pub enum Error { InvalidFixedValue { expected: u64, actual: u64 }, #[error("when parsing {obj} needed length of {wanted} but got {got}")] InvalidLengthError { obj: String, wanted: usize, got: usize }, - #[error("array size ({array} bytes) is not a multiple of the element size ({element} bytes)")] + #[error( + "array size ({array} bytes) is not a multiple of the element size ({element} bytes)" + )] InvalidArraySize { array: usize, element: usize }, #[error("Due to size restrictions a struct could not be parsed.")] ImpossibleStructError, @@ -41,12 +40,10 @@ pub enum Error { #[error("expected child {expected}, got {actual}")] InvalidChildError { expected: &'static str, actual: String }, } - pub trait Packet { fn to_bytes(self) -> Bytes; fn to_vec(self) -> Vec; } - #[derive(Debug, Clone, PartialEq, Eq)] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] pub struct Foo { @@ -85,10 +82,7 @@ impl Foo { fn write_to(&self, buffer: &mut BytesMut) { if self.a.len() > 0xff_ffff_ffff_usize { panic!( - "Invalid length for {}::{}: {} > {}", - "Foo", - "a", - self.a.len(), + "Invalid length for {}::{}: {} > {}", "Foo", "a", self.a.len(), 0xff_ffff_ffff_usize ); } @@ -104,7 +98,6 @@ impl Foo { 5 + self.a.len() * 2 } } - #[derive(Debug, Clone, PartialEq, Eq)] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] pub struct BarData { @@ -158,7 +151,10 @@ impl BarData { fn write_to(&self, buffer: &mut BytesMut) { let x_size = self.x.iter().map(|elem| elem.get_size()).sum::(); if x_size > 0xff_ffff_ffff_usize { - panic!("Invalid length for {}::{}: {} > {}", "Bar", "x", x_size, 0xff_ffff_ffff_usize); + panic!( + "Invalid length for {}::{}: {} > {}", "Bar", "x", x_size, + 0xff_ffff_ffff_usize + ); } buffer.put_uint(x_size as u64, 5); for elem in &self.x { diff --git a/tools/pdl/tests/generated/packet_decl_array_unknown_element_width_dynamic_size_little_endian.rs b/tools/pdl/tests/generated/packet_decl_array_unknown_element_width_dynamic_size_little_endian.rs index 4fdaa545aa0..a0605eb919d 100644 --- a/tools/pdl/tests/generated/packet_decl_array_unknown_element_width_dynamic_size_little_endian.rs +++ b/tools/pdl/tests/generated/packet_decl_array_unknown_element_width_dynamic_size_little_endian.rs @@ -1,18 +1,16 @@ -// @generated rust packets from test - +#![rustfmt::skip] +/// @generated rust packets from test. use bytes::{Buf, BufMut, Bytes, BytesMut}; -use std::cell::Cell; use std::convert::{TryFrom, TryInto}; +use std::cell::Cell; use std::fmt; use std::sync::Arc; use thiserror::Error; - type Result = std::result::Result; - -#[doc = r" Private prevents users from creating arbitrary scalar values"] -#[doc = r" in situations where the value needs to be validated."] -#[doc = r" Users can freely deref the value, but only the backend"] -#[doc = r" may create it."] +/// Private prevents users from creating arbitrary scalar values +/// in situations where the value needs to be validated. +/// Users can freely deref the value, but only the backend +/// may create it. #[derive(Debug, Clone, Copy, Hash, PartialEq, Eq, PartialOrd, Ord)] pub struct Private(T); impl std::ops::Deref for Private { @@ -21,7 +19,6 @@ impl std::ops::Deref for Private { &self.0 } } - #[derive(Debug, Error)] pub enum Error { #[error("Packet parsing failed")] @@ -32,7 +29,9 @@ pub enum Error { InvalidFixedValue { expected: u64, actual: u64 }, #[error("when parsing {obj} needed length of {wanted} but got {got}")] InvalidLengthError { obj: String, wanted: usize, got: usize }, - #[error("array size ({array} bytes) is not a multiple of the element size ({element} bytes)")] + #[error( + "array size ({array} bytes) is not a multiple of the element size ({element} bytes)" + )] InvalidArraySize { array: usize, element: usize }, #[error("Due to size restrictions a struct could not be parsed.")] ImpossibleStructError, @@ -41,12 +40,10 @@ pub enum Error { #[error("expected child {expected}, got {actual}")] InvalidChildError { expected: &'static str, actual: String }, } - pub trait Packet { fn to_bytes(self) -> Bytes; fn to_vec(self) -> Vec; } - #[derive(Debug, Clone, PartialEq, Eq)] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] pub struct Foo { @@ -85,10 +82,7 @@ impl Foo { fn write_to(&self, buffer: &mut BytesMut) { if self.a.len() > 0xff_ffff_ffff_usize { panic!( - "Invalid length for {}::{}: {} > {}", - "Foo", - "a", - self.a.len(), + "Invalid length for {}::{}: {} > {}", "Foo", "a", self.a.len(), 0xff_ffff_ffff_usize ); } @@ -104,7 +98,6 @@ impl Foo { 5 + self.a.len() * 2 } } - #[derive(Debug, Clone, PartialEq, Eq)] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] pub struct BarData { @@ -158,7 +151,10 @@ impl BarData { fn write_to(&self, buffer: &mut BytesMut) { let x_size = self.x.iter().map(|elem| elem.get_size()).sum::(); if x_size > 0xff_ffff_ffff_usize { - panic!("Invalid length for {}::{}: {} > {}", "Bar", "x", x_size, 0xff_ffff_ffff_usize); + panic!( + "Invalid length for {}::{}: {} > {}", "Bar", "x", x_size, + 0xff_ffff_ffff_usize + ); } buffer.put_uint_le(x_size as u64, 5); for elem in &self.x { diff --git a/tools/pdl/tests/generated/packet_decl_array_with_padding_big_endian.rs b/tools/pdl/tests/generated/packet_decl_array_with_padding_big_endian.rs index 9e285db1444..36b55712183 100644 --- a/tools/pdl/tests/generated/packet_decl_array_with_padding_big_endian.rs +++ b/tools/pdl/tests/generated/packet_decl_array_with_padding_big_endian.rs @@ -1,18 +1,16 @@ -// @generated rust packets from test - +#![rustfmt::skip] +/// @generated rust packets from test. use bytes::{Buf, BufMut, Bytes, BytesMut}; -use std::cell::Cell; use std::convert::{TryFrom, TryInto}; +use std::cell::Cell; use std::fmt; use std::sync::Arc; use thiserror::Error; - type Result = std::result::Result; - -#[doc = r" Private prevents users from creating arbitrary scalar values"] -#[doc = r" in situations where the value needs to be validated."] -#[doc = r" Users can freely deref the value, but only the backend"] -#[doc = r" may create it."] +/// Private prevents users from creating arbitrary scalar values +/// in situations where the value needs to be validated. +/// Users can freely deref the value, but only the backend +/// may create it. #[derive(Debug, Clone, Copy, Hash, PartialEq, Eq, PartialOrd, Ord)] pub struct Private(T); impl std::ops::Deref for Private { @@ -21,7 +19,6 @@ impl std::ops::Deref for Private { &self.0 } } - #[derive(Debug, Error)] pub enum Error { #[error("Packet parsing failed")] @@ -32,7 +29,9 @@ pub enum Error { InvalidFixedValue { expected: u64, actual: u64 }, #[error("when parsing {obj} needed length of {wanted} but got {got}")] InvalidLengthError { obj: String, wanted: usize, got: usize }, - #[error("array size ({array} bytes) is not a multiple of the element size ({element} bytes)")] + #[error( + "array size ({array} bytes) is not a multiple of the element size ({element} bytes)" + )] InvalidArraySize { array: usize, element: usize }, #[error("Due to size restrictions a struct could not be parsed.")] ImpossibleStructError, @@ -41,12 +40,10 @@ pub enum Error { #[error("expected child {expected}, got {actual}")] InvalidChildError { expected: &'static str, actual: String }, } - pub trait Packet { fn to_bytes(self) -> Bytes; fn to_vec(self) -> Vec; } - #[derive(Debug, Clone, PartialEq, Eq)] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] pub struct Foo { @@ -85,10 +82,7 @@ impl Foo { fn write_to(&self, buffer: &mut BytesMut) { if self.a.len() > 0xff_ffff_ffff_usize { panic!( - "Invalid length for {}::{}: {} > {}", - "Foo", - "a", - self.a.len(), + "Invalid length for {}::{}: {} > {}", "Foo", "a", self.a.len(), 0xff_ffff_ffff_usize ); } @@ -104,7 +98,6 @@ impl Foo { 5 + self.a.len() * 2 } } - #[derive(Debug, Clone, PartialEq, Eq)] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] pub struct BarData { @@ -154,7 +147,9 @@ impl BarData { } let array_size = buffer.len() - current_size; if array_size > 128usize { - panic!("attempted to serialize an array larger than the enclosing padding size"); + panic!( + "attempted to serialize an array larger than the enclosing padding size" + ); } buffer.put_bytes(0, 128usize - array_size); } diff --git a/tools/pdl/tests/generated/packet_decl_array_with_padding_little_endian.rs b/tools/pdl/tests/generated/packet_decl_array_with_padding_little_endian.rs index df694a61a5c..53cec927818 100644 --- a/tools/pdl/tests/generated/packet_decl_array_with_padding_little_endian.rs +++ b/tools/pdl/tests/generated/packet_decl_array_with_padding_little_endian.rs @@ -1,18 +1,16 @@ -// @generated rust packets from test - +#![rustfmt::skip] +/// @generated rust packets from test. use bytes::{Buf, BufMut, Bytes, BytesMut}; -use std::cell::Cell; use std::convert::{TryFrom, TryInto}; +use std::cell::Cell; use std::fmt; use std::sync::Arc; use thiserror::Error; - type Result = std::result::Result; - -#[doc = r" Private prevents users from creating arbitrary scalar values"] -#[doc = r" in situations where the value needs to be validated."] -#[doc = r" Users can freely deref the value, but only the backend"] -#[doc = r" may create it."] +/// Private prevents users from creating arbitrary scalar values +/// in situations where the value needs to be validated. +/// Users can freely deref the value, but only the backend +/// may create it. #[derive(Debug, Clone, Copy, Hash, PartialEq, Eq, PartialOrd, Ord)] pub struct Private(T); impl std::ops::Deref for Private { @@ -21,7 +19,6 @@ impl std::ops::Deref for Private { &self.0 } } - #[derive(Debug, Error)] pub enum Error { #[error("Packet parsing failed")] @@ -32,7 +29,9 @@ pub enum Error { InvalidFixedValue { expected: u64, actual: u64 }, #[error("when parsing {obj} needed length of {wanted} but got {got}")] InvalidLengthError { obj: String, wanted: usize, got: usize }, - #[error("array size ({array} bytes) is not a multiple of the element size ({element} bytes)")] + #[error( + "array size ({array} bytes) is not a multiple of the element size ({element} bytes)" + )] InvalidArraySize { array: usize, element: usize }, #[error("Due to size restrictions a struct could not be parsed.")] ImpossibleStructError, @@ -41,12 +40,10 @@ pub enum Error { #[error("expected child {expected}, got {actual}")] InvalidChildError { expected: &'static str, actual: String }, } - pub trait Packet { fn to_bytes(self) -> Bytes; fn to_vec(self) -> Vec; } - #[derive(Debug, Clone, PartialEq, Eq)] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] pub struct Foo { @@ -85,10 +82,7 @@ impl Foo { fn write_to(&self, buffer: &mut BytesMut) { if self.a.len() > 0xff_ffff_ffff_usize { panic!( - "Invalid length for {}::{}: {} > {}", - "Foo", - "a", - self.a.len(), + "Invalid length for {}::{}: {} > {}", "Foo", "a", self.a.len(), 0xff_ffff_ffff_usize ); } @@ -104,7 +98,6 @@ impl Foo { 5 + self.a.len() * 2 } } - #[derive(Debug, Clone, PartialEq, Eq)] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] pub struct BarData { @@ -154,7 +147,9 @@ impl BarData { } let array_size = buffer.len() - current_size; if array_size > 128usize { - panic!("attempted to serialize an array larger than the enclosing padding size"); + panic!( + "attempted to serialize an array larger than the enclosing padding size" + ); } buffer.put_bytes(0, 128usize - array_size); } diff --git a/tools/pdl/tests/generated/packet_decl_child_packets_big_endian.rs b/tools/pdl/tests/generated/packet_decl_child_packets_big_endian.rs index 3940cc0f3fb..e8468a7a44e 100644 --- a/tools/pdl/tests/generated/packet_decl_child_packets_big_endian.rs +++ b/tools/pdl/tests/generated/packet_decl_child_packets_big_endian.rs @@ -1,18 +1,16 @@ -// @generated rust packets from test - +#![rustfmt::skip] +/// @generated rust packets from test. use bytes::{Buf, BufMut, Bytes, BytesMut}; -use std::cell::Cell; use std::convert::{TryFrom, TryInto}; +use std::cell::Cell; use std::fmt; use std::sync::Arc; use thiserror::Error; - type Result = std::result::Result; - -#[doc = r" Private prevents users from creating arbitrary scalar values"] -#[doc = r" in situations where the value needs to be validated."] -#[doc = r" Users can freely deref the value, but only the backend"] -#[doc = r" may create it."] +/// Private prevents users from creating arbitrary scalar values +/// in situations where the value needs to be validated. +/// Users can freely deref the value, but only the backend +/// may create it. #[derive(Debug, Clone, Copy, Hash, PartialEq, Eq, PartialOrd, Ord)] pub struct Private(T); impl std::ops::Deref for Private { @@ -21,7 +19,6 @@ impl std::ops::Deref for Private { &self.0 } } - #[derive(Debug, Error)] pub enum Error { #[error("Packet parsing failed")] @@ -32,7 +29,9 @@ pub enum Error { InvalidFixedValue { expected: u64, actual: u64 }, #[error("when parsing {obj} needed length of {wanted} but got {got}")] InvalidLengthError { obj: String, wanted: usize, got: usize }, - #[error("array size ({array} bytes) is not a multiple of the element size ({element} bytes)")] + #[error( + "array size ({array} bytes) is not a multiple of the element size ({element} bytes)" + )] InvalidArraySize { array: usize, element: usize }, #[error("Due to size restrictions a struct could not be parsed.")] ImpossibleStructError, @@ -41,12 +40,10 @@ pub enum Error { #[error("expected child {expected}, got {actual}")] InvalidChildError { expected: &'static str, actual: String }, } - pub trait Packet { fn to_bytes(self) -> Bytes; fn to_vec(self) -> Vec; } - #[repr(u64)] #[derive(Debug, Clone, Copy, Hash, Eq, PartialEq)] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] @@ -98,7 +95,6 @@ impl From for u64 { u16::from(value) as Self } } - #[derive(Debug, Clone, PartialEq, Eq)] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] pub enum FooDataChild { @@ -170,14 +166,13 @@ impl FooData { got: bytes.get().remaining(), }); } - let b = Enum16::try_from(bytes.get_mut().get_u16()).map_err(|_| { - Error::InvalidEnumValueError { + let b = Enum16::try_from(bytes.get_mut().get_u16()) + .map_err(|_| Error::InvalidEnumValueError { obj: "Foo".to_string(), field: "b".to_string(), value: bytes.get_mut().get_u16() as u64, type_: "Enum16".to_string(), - } - })?; + })?; if bytes.get().remaining() < 1 { return Err(Error::InvalidLengthError { obj: "Foo".to_string(), @@ -206,7 +201,9 @@ impl FooData { let child_data = BazData::parse_inner(&mut cell)?; FooDataChild::Baz(Arc::new(child_data)) } - _ if !payload.is_empty() => FooDataChild::Payload(Bytes::copy_from_slice(payload)), + _ if !payload.is_empty() => { + FooDataChild::Payload(Bytes::copy_from_slice(payload)) + } _ => FooDataChild::None, }; Ok(Self { a, b, child }) @@ -216,11 +213,8 @@ impl FooData { buffer.put_u16(u16::from(self.b)); if self.child.get_total_size() > 0xff { panic!( - "Invalid length for {}::{}: {} > {}", - "Foo", - "_payload_", - self.child.get_total_size(), - 0xff + "Invalid length for {}::{}: {} > {}", "Foo", "_payload_", self.child + .get_total_size(), 0xff ); } buffer.put_u8(self.child.get_total_size() as u8); @@ -310,7 +304,6 @@ impl From for Foo { builder.build().into() } } - #[derive(Debug, Clone, PartialEq, Eq)] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] pub struct BarData { @@ -407,8 +400,8 @@ impl Bar { _ => { return Err(Error::InvalidChildError { expected: stringify!(FooDataChild::Bar), - actual: format!("{:?}", &foo.child), - }) + actual: format!("{:?}", & foo.child), + }); } }; Ok(Self { foo, bar }) @@ -432,7 +425,11 @@ impl Bar { impl BarBuilder { pub fn build(self) -> Bar { let bar = Arc::new(BarData { x: self.x }); - let foo = Arc::new(FooData { a: 100, b: self.b, child: FooDataChild::Bar(bar) }); + let foo = Arc::new(FooData { + a: 100, + b: self.b, + child: FooDataChild::Bar(bar), + }); Bar::new(foo).unwrap() } } @@ -446,7 +443,6 @@ impl From for Bar { builder.build().into() } } - #[derive(Debug, Clone, PartialEq, Eq)] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] pub struct BazData { @@ -543,8 +539,8 @@ impl Baz { _ => { return Err(Error::InvalidChildError { expected: stringify!(FooDataChild::Baz), - actual: format!("{:?}", &foo.child), - }) + actual: format!("{:?}", & foo.child), + }); } }; Ok(Self { foo, baz }) @@ -568,7 +564,11 @@ impl Baz { impl BazBuilder { pub fn build(self) -> Baz { let baz = Arc::new(BazData { y: self.y }); - let foo = Arc::new(FooData { a: self.a, b: Enum16::B, child: FooDataChild::Baz(baz) }); + let foo = Arc::new(FooData { + a: self.a, + b: Enum16::B, + child: FooDataChild::Baz(baz), + }); Baz::new(foo).unwrap() } } diff --git a/tools/pdl/tests/generated/packet_decl_child_packets_little_endian.rs b/tools/pdl/tests/generated/packet_decl_child_packets_little_endian.rs index ca17b244db9..bbbb2617c4e 100644 --- a/tools/pdl/tests/generated/packet_decl_child_packets_little_endian.rs +++ b/tools/pdl/tests/generated/packet_decl_child_packets_little_endian.rs @@ -1,18 +1,16 @@ -// @generated rust packets from test - +#![rustfmt::skip] +/// @generated rust packets from test. use bytes::{Buf, BufMut, Bytes, BytesMut}; -use std::cell::Cell; use std::convert::{TryFrom, TryInto}; +use std::cell::Cell; use std::fmt; use std::sync::Arc; use thiserror::Error; - type Result = std::result::Result; - -#[doc = r" Private prevents users from creating arbitrary scalar values"] -#[doc = r" in situations where the value needs to be validated."] -#[doc = r" Users can freely deref the value, but only the backend"] -#[doc = r" may create it."] +/// Private prevents users from creating arbitrary scalar values +/// in situations where the value needs to be validated. +/// Users can freely deref the value, but only the backend +/// may create it. #[derive(Debug, Clone, Copy, Hash, PartialEq, Eq, PartialOrd, Ord)] pub struct Private(T); impl std::ops::Deref for Private { @@ -21,7 +19,6 @@ impl std::ops::Deref for Private { &self.0 } } - #[derive(Debug, Error)] pub enum Error { #[error("Packet parsing failed")] @@ -32,7 +29,9 @@ pub enum Error { InvalidFixedValue { expected: u64, actual: u64 }, #[error("when parsing {obj} needed length of {wanted} but got {got}")] InvalidLengthError { obj: String, wanted: usize, got: usize }, - #[error("array size ({array} bytes) is not a multiple of the element size ({element} bytes)")] + #[error( + "array size ({array} bytes) is not a multiple of the element size ({element} bytes)" + )] InvalidArraySize { array: usize, element: usize }, #[error("Due to size restrictions a struct could not be parsed.")] ImpossibleStructError, @@ -41,12 +40,10 @@ pub enum Error { #[error("expected child {expected}, got {actual}")] InvalidChildError { expected: &'static str, actual: String }, } - pub trait Packet { fn to_bytes(self) -> Bytes; fn to_vec(self) -> Vec; } - #[repr(u64)] #[derive(Debug, Clone, Copy, Hash, Eq, PartialEq)] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] @@ -98,7 +95,6 @@ impl From for u64 { u16::from(value) as Self } } - #[derive(Debug, Clone, PartialEq, Eq)] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] pub enum FooDataChild { @@ -170,14 +166,13 @@ impl FooData { got: bytes.get().remaining(), }); } - let b = Enum16::try_from(bytes.get_mut().get_u16_le()).map_err(|_| { - Error::InvalidEnumValueError { + let b = Enum16::try_from(bytes.get_mut().get_u16_le()) + .map_err(|_| Error::InvalidEnumValueError { obj: "Foo".to_string(), field: "b".to_string(), value: bytes.get_mut().get_u16_le() as u64, type_: "Enum16".to_string(), - } - })?; + })?; if bytes.get().remaining() < 1 { return Err(Error::InvalidLengthError { obj: "Foo".to_string(), @@ -206,7 +201,9 @@ impl FooData { let child_data = BazData::parse_inner(&mut cell)?; FooDataChild::Baz(Arc::new(child_data)) } - _ if !payload.is_empty() => FooDataChild::Payload(Bytes::copy_from_slice(payload)), + _ if !payload.is_empty() => { + FooDataChild::Payload(Bytes::copy_from_slice(payload)) + } _ => FooDataChild::None, }; Ok(Self { a, b, child }) @@ -216,11 +213,8 @@ impl FooData { buffer.put_u16_le(u16::from(self.b)); if self.child.get_total_size() > 0xff { panic!( - "Invalid length for {}::{}: {} > {}", - "Foo", - "_payload_", - self.child.get_total_size(), - 0xff + "Invalid length for {}::{}: {} > {}", "Foo", "_payload_", self.child + .get_total_size(), 0xff ); } buffer.put_u8(self.child.get_total_size() as u8); @@ -310,7 +304,6 @@ impl From for Foo { builder.build().into() } } - #[derive(Debug, Clone, PartialEq, Eq)] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] pub struct BarData { @@ -407,8 +400,8 @@ impl Bar { _ => { return Err(Error::InvalidChildError { expected: stringify!(FooDataChild::Bar), - actual: format!("{:?}", &foo.child), - }) + actual: format!("{:?}", & foo.child), + }); } }; Ok(Self { foo, bar }) @@ -432,7 +425,11 @@ impl Bar { impl BarBuilder { pub fn build(self) -> Bar { let bar = Arc::new(BarData { x: self.x }); - let foo = Arc::new(FooData { a: 100, b: self.b, child: FooDataChild::Bar(bar) }); + let foo = Arc::new(FooData { + a: 100, + b: self.b, + child: FooDataChild::Bar(bar), + }); Bar::new(foo).unwrap() } } @@ -446,7 +443,6 @@ impl From for Bar { builder.build().into() } } - #[derive(Debug, Clone, PartialEq, Eq)] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] pub struct BazData { @@ -543,8 +539,8 @@ impl Baz { _ => { return Err(Error::InvalidChildError { expected: stringify!(FooDataChild::Baz), - actual: format!("{:?}", &foo.child), - }) + actual: format!("{:?}", & foo.child), + }); } }; Ok(Self { foo, baz }) @@ -568,7 +564,11 @@ impl Baz { impl BazBuilder { pub fn build(self) -> Baz { let baz = Arc::new(BazData { y: self.y }); - let foo = Arc::new(FooData { a: self.a, b: Enum16::B, child: FooDataChild::Baz(baz) }); + let foo = Arc::new(FooData { + a: self.a, + b: Enum16::B, + child: FooDataChild::Baz(baz), + }); Baz::new(foo).unwrap() } } diff --git a/tools/pdl/tests/generated/packet_decl_complex_scalars_big_endian.rs b/tools/pdl/tests/generated/packet_decl_complex_scalars_big_endian.rs index 7eeb9b7df6e..688af4282f9 100644 --- a/tools/pdl/tests/generated/packet_decl_complex_scalars_big_endian.rs +++ b/tools/pdl/tests/generated/packet_decl_complex_scalars_big_endian.rs @@ -1,18 +1,16 @@ -// @generated rust packets from test - +#![rustfmt::skip] +/// @generated rust packets from test. use bytes::{Buf, BufMut, Bytes, BytesMut}; -use std::cell::Cell; use std::convert::{TryFrom, TryInto}; +use std::cell::Cell; use std::fmt; use std::sync::Arc; use thiserror::Error; - type Result = std::result::Result; - -#[doc = r" Private prevents users from creating arbitrary scalar values"] -#[doc = r" in situations where the value needs to be validated."] -#[doc = r" Users can freely deref the value, but only the backend"] -#[doc = r" may create it."] +/// Private prevents users from creating arbitrary scalar values +/// in situations where the value needs to be validated. +/// Users can freely deref the value, but only the backend +/// may create it. #[derive(Debug, Clone, Copy, Hash, PartialEq, Eq, PartialOrd, Ord)] pub struct Private(T); impl std::ops::Deref for Private { @@ -21,7 +19,6 @@ impl std::ops::Deref for Private { &self.0 } } - #[derive(Debug, Error)] pub enum Error { #[error("Packet parsing failed")] @@ -32,7 +29,9 @@ pub enum Error { InvalidFixedValue { expected: u64, actual: u64 }, #[error("when parsing {obj} needed length of {wanted} but got {got}")] InvalidLengthError { obj: String, wanted: usize, got: usize }, - #[error("array size ({array} bytes) is not a multiple of the element size ({element} bytes)")] + #[error( + "array size ({array} bytes) is not a multiple of the element size ({element} bytes)" + )] InvalidArraySize { array: usize, element: usize }, #[error("Due to size restrictions a struct could not be parsed.")] ImpossibleStructError, @@ -41,12 +40,10 @@ pub enum Error { #[error("expected child {expected}, got {actual}")] InvalidChildError { expected: &'static str, actual: String }, } - pub trait Packet { fn to_bytes(self) -> Bytes; fn to_vec(self) -> Vec; } - #[derive(Debug, Clone, PartialEq, Eq)] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] pub struct FooData { @@ -203,8 +200,14 @@ impl Foo { } impl FooBuilder { pub fn build(self) -> Foo { - let foo = - Arc::new(FooData { a: self.a, b: self.b, c: self.c, d: self.d, e: self.e, f: self.f }); + let foo = Arc::new(FooData { + a: self.a, + b: self.b, + c: self.c, + d: self.d, + e: self.e, + f: self.f, + }); Foo::new(foo).unwrap() } } diff --git a/tools/pdl/tests/generated/packet_decl_complex_scalars_little_endian.rs b/tools/pdl/tests/generated/packet_decl_complex_scalars_little_endian.rs index dd684e60a18..83da632a3a0 100644 --- a/tools/pdl/tests/generated/packet_decl_complex_scalars_little_endian.rs +++ b/tools/pdl/tests/generated/packet_decl_complex_scalars_little_endian.rs @@ -1,18 +1,16 @@ -// @generated rust packets from test - +#![rustfmt::skip] +/// @generated rust packets from test. use bytes::{Buf, BufMut, Bytes, BytesMut}; -use std::cell::Cell; use std::convert::{TryFrom, TryInto}; +use std::cell::Cell; use std::fmt; use std::sync::Arc; use thiserror::Error; - type Result = std::result::Result; - -#[doc = r" Private prevents users from creating arbitrary scalar values"] -#[doc = r" in situations where the value needs to be validated."] -#[doc = r" Users can freely deref the value, but only the backend"] -#[doc = r" may create it."] +/// Private prevents users from creating arbitrary scalar values +/// in situations where the value needs to be validated. +/// Users can freely deref the value, but only the backend +/// may create it. #[derive(Debug, Clone, Copy, Hash, PartialEq, Eq, PartialOrd, Ord)] pub struct Private(T); impl std::ops::Deref for Private { @@ -21,7 +19,6 @@ impl std::ops::Deref for Private { &self.0 } } - #[derive(Debug, Error)] pub enum Error { #[error("Packet parsing failed")] @@ -32,7 +29,9 @@ pub enum Error { InvalidFixedValue { expected: u64, actual: u64 }, #[error("when parsing {obj} needed length of {wanted} but got {got}")] InvalidLengthError { obj: String, wanted: usize, got: usize }, - #[error("array size ({array} bytes) is not a multiple of the element size ({element} bytes)")] + #[error( + "array size ({array} bytes) is not a multiple of the element size ({element} bytes)" + )] InvalidArraySize { array: usize, element: usize }, #[error("Due to size restrictions a struct could not be parsed.")] ImpossibleStructError, @@ -41,12 +40,10 @@ pub enum Error { #[error("expected child {expected}, got {actual}")] InvalidChildError { expected: &'static str, actual: String }, } - pub trait Packet { fn to_bytes(self) -> Bytes; fn to_vec(self) -> Vec; } - #[derive(Debug, Clone, PartialEq, Eq)] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] pub struct FooData { @@ -203,8 +200,14 @@ impl Foo { } impl FooBuilder { pub fn build(self) -> Foo { - let foo = - Arc::new(FooData { a: self.a, b: self.b, c: self.c, d: self.d, e: self.e, f: self.f }); + let foo = Arc::new(FooData { + a: self.a, + b: self.b, + c: self.c, + d: self.d, + e: self.e, + f: self.f, + }); Foo::new(foo).unwrap() } } diff --git a/tools/pdl/tests/generated/packet_decl_custom_field_big_endian.rs b/tools/pdl/tests/generated/packet_decl_custom_field_big_endian.rs index cfe327f6b74..4783d1f767d 100644 --- a/tools/pdl/tests/generated/packet_decl_custom_field_big_endian.rs +++ b/tools/pdl/tests/generated/packet_decl_custom_field_big_endian.rs @@ -1,18 +1,16 @@ -// @generated rust packets from test - +#![rustfmt::skip] +/// @generated rust packets from test. use bytes::{Buf, BufMut, Bytes, BytesMut}; -use std::cell::Cell; use std::convert::{TryFrom, TryInto}; +use std::cell::Cell; use std::fmt; use std::sync::Arc; use thiserror::Error; - type Result = std::result::Result; - -#[doc = r" Private prevents users from creating arbitrary scalar values"] -#[doc = r" in situations where the value needs to be validated."] -#[doc = r" Users can freely deref the value, but only the backend"] -#[doc = r" may create it."] +/// Private prevents users from creating arbitrary scalar values +/// in situations where the value needs to be validated. +/// Users can freely deref the value, but only the backend +/// may create it. #[derive(Debug, Clone, Copy, Hash, PartialEq, Eq, PartialOrd, Ord)] pub struct Private(T); impl std::ops::Deref for Private { @@ -21,7 +19,6 @@ impl std::ops::Deref for Private { &self.0 } } - #[derive(Debug, Error)] pub enum Error { #[error("Packet parsing failed")] @@ -32,7 +29,9 @@ pub enum Error { InvalidFixedValue { expected: u64, actual: u64 }, #[error("when parsing {obj} needed length of {wanted} but got {got}")] InvalidLengthError { obj: String, wanted: usize, got: usize }, - #[error("array size ({array} bytes) is not a multiple of the element size ({element} bytes)")] + #[error( + "array size ({array} bytes) is not a multiple of the element size ({element} bytes)" + )] InvalidArraySize { array: usize, element: usize }, #[error("Due to size restrictions a struct could not be parsed.")] ImpossibleStructError, @@ -41,12 +40,10 @@ pub enum Error { #[error("expected child {expected}, got {actual}")] InvalidChildError { expected: &'static str, actual: String }, } - pub trait Packet { fn to_bytes(self) -> Bytes; fn to_vec(self) -> Vec; } - #[derive(Debug, Clone, Copy, Hash, Eq, PartialEq)] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] #[cfg_attr(feature = "serde", serde(try_from = "u32", into = "u32"))] @@ -64,14 +61,9 @@ impl From for u32 { impl TryFrom for Bar1 { type Error = u32; fn try_from(value: u32) -> std::result::Result { - if value > 0xff_ffff { - Err(value) - } else { - Ok(Bar1(value)) - } + if value > 0xff_ffff { Err(value) } else { Ok(Bar1(value)) } } } - #[derive(Debug, Clone, Copy, Hash, Eq, PartialEq)] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] #[cfg_attr(feature = "serde", serde(from = "u32", into = "u32"))] @@ -91,7 +83,6 @@ impl From for Bar2 { Bar2(value) } } - #[derive(Debug, Clone, PartialEq, Eq)] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] pub struct FooData { diff --git a/tools/pdl/tests/generated/packet_decl_custom_field_little_endian.rs b/tools/pdl/tests/generated/packet_decl_custom_field_little_endian.rs index 4a12f13ed4f..60d17f5c7cb 100644 --- a/tools/pdl/tests/generated/packet_decl_custom_field_little_endian.rs +++ b/tools/pdl/tests/generated/packet_decl_custom_field_little_endian.rs @@ -1,18 +1,16 @@ -// @generated rust packets from test - +#![rustfmt::skip] +/// @generated rust packets from test. use bytes::{Buf, BufMut, Bytes, BytesMut}; -use std::cell::Cell; use std::convert::{TryFrom, TryInto}; +use std::cell::Cell; use std::fmt; use std::sync::Arc; use thiserror::Error; - type Result = std::result::Result; - -#[doc = r" Private prevents users from creating arbitrary scalar values"] -#[doc = r" in situations where the value needs to be validated."] -#[doc = r" Users can freely deref the value, but only the backend"] -#[doc = r" may create it."] +/// Private prevents users from creating arbitrary scalar values +/// in situations where the value needs to be validated. +/// Users can freely deref the value, but only the backend +/// may create it. #[derive(Debug, Clone, Copy, Hash, PartialEq, Eq, PartialOrd, Ord)] pub struct Private(T); impl std::ops::Deref for Private { @@ -21,7 +19,6 @@ impl std::ops::Deref for Private { &self.0 } } - #[derive(Debug, Error)] pub enum Error { #[error("Packet parsing failed")] @@ -32,7 +29,9 @@ pub enum Error { InvalidFixedValue { expected: u64, actual: u64 }, #[error("when parsing {obj} needed length of {wanted} but got {got}")] InvalidLengthError { obj: String, wanted: usize, got: usize }, - #[error("array size ({array} bytes) is not a multiple of the element size ({element} bytes)")] + #[error( + "array size ({array} bytes) is not a multiple of the element size ({element} bytes)" + )] InvalidArraySize { array: usize, element: usize }, #[error("Due to size restrictions a struct could not be parsed.")] ImpossibleStructError, @@ -41,12 +40,10 @@ pub enum Error { #[error("expected child {expected}, got {actual}")] InvalidChildError { expected: &'static str, actual: String }, } - pub trait Packet { fn to_bytes(self) -> Bytes; fn to_vec(self) -> Vec; } - #[derive(Debug, Clone, Copy, Hash, Eq, PartialEq)] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] #[cfg_attr(feature = "serde", serde(try_from = "u32", into = "u32"))] @@ -64,14 +61,9 @@ impl From for u32 { impl TryFrom for Bar1 { type Error = u32; fn try_from(value: u32) -> std::result::Result { - if value > 0xff_ffff { - Err(value) - } else { - Ok(Bar1(value)) - } + if value > 0xff_ffff { Err(value) } else { Ok(Bar1(value)) } } } - #[derive(Debug, Clone, Copy, Hash, Eq, PartialEq)] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] #[cfg_attr(feature = "serde", serde(from = "u32", into = "u32"))] @@ -91,7 +83,6 @@ impl From for Bar2 { Bar2(value) } } - #[derive(Debug, Clone, PartialEq, Eq)] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] pub struct FooData { diff --git a/tools/pdl/tests/generated/packet_decl_empty_big_endian.rs b/tools/pdl/tests/generated/packet_decl_empty_big_endian.rs index cecac9589be..d05c2ff7505 100644 --- a/tools/pdl/tests/generated/packet_decl_empty_big_endian.rs +++ b/tools/pdl/tests/generated/packet_decl_empty_big_endian.rs @@ -1,18 +1,16 @@ -// @generated rust packets from test - +#![rustfmt::skip] +/// @generated rust packets from test. use bytes::{Buf, BufMut, Bytes, BytesMut}; -use std::cell::Cell; use std::convert::{TryFrom, TryInto}; +use std::cell::Cell; use std::fmt; use std::sync::Arc; use thiserror::Error; - type Result = std::result::Result; - -#[doc = r" Private prevents users from creating arbitrary scalar values"] -#[doc = r" in situations where the value needs to be validated."] -#[doc = r" Users can freely deref the value, but only the backend"] -#[doc = r" may create it."] +/// Private prevents users from creating arbitrary scalar values +/// in situations where the value needs to be validated. +/// Users can freely deref the value, but only the backend +/// may create it. #[derive(Debug, Clone, Copy, Hash, PartialEq, Eq, PartialOrd, Ord)] pub struct Private(T); impl std::ops::Deref for Private { @@ -21,7 +19,6 @@ impl std::ops::Deref for Private { &self.0 } } - #[derive(Debug, Error)] pub enum Error { #[error("Packet parsing failed")] @@ -32,7 +29,9 @@ pub enum Error { InvalidFixedValue { expected: u64, actual: u64 }, #[error("when parsing {obj} needed length of {wanted} but got {got}")] InvalidLengthError { obj: String, wanted: usize, got: usize }, - #[error("array size ({array} bytes) is not a multiple of the element size ({element} bytes)")] + #[error( + "array size ({array} bytes) is not a multiple of the element size ({element} bytes)" + )] InvalidArraySize { array: usize, element: usize }, #[error("Due to size restrictions a struct could not be parsed.")] ImpossibleStructError, @@ -41,12 +40,10 @@ pub enum Error { #[error("expected child {expected}, got {actual}")] InvalidChildError { expected: &'static str, actual: String }, } - pub trait Packet { fn to_bytes(self) -> Bytes; fn to_vec(self) -> Vec; } - #[derive(Debug, Clone, PartialEq, Eq)] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] pub struct FooData {} diff --git a/tools/pdl/tests/generated/packet_decl_empty_little_endian.rs b/tools/pdl/tests/generated/packet_decl_empty_little_endian.rs index cecac9589be..d05c2ff7505 100644 --- a/tools/pdl/tests/generated/packet_decl_empty_little_endian.rs +++ b/tools/pdl/tests/generated/packet_decl_empty_little_endian.rs @@ -1,18 +1,16 @@ -// @generated rust packets from test - +#![rustfmt::skip] +/// @generated rust packets from test. use bytes::{Buf, BufMut, Bytes, BytesMut}; -use std::cell::Cell; use std::convert::{TryFrom, TryInto}; +use std::cell::Cell; use std::fmt; use std::sync::Arc; use thiserror::Error; - type Result = std::result::Result; - -#[doc = r" Private prevents users from creating arbitrary scalar values"] -#[doc = r" in situations where the value needs to be validated."] -#[doc = r" Users can freely deref the value, but only the backend"] -#[doc = r" may create it."] +/// Private prevents users from creating arbitrary scalar values +/// in situations where the value needs to be validated. +/// Users can freely deref the value, but only the backend +/// may create it. #[derive(Debug, Clone, Copy, Hash, PartialEq, Eq, PartialOrd, Ord)] pub struct Private(T); impl std::ops::Deref for Private { @@ -21,7 +19,6 @@ impl std::ops::Deref for Private { &self.0 } } - #[derive(Debug, Error)] pub enum Error { #[error("Packet parsing failed")] @@ -32,7 +29,9 @@ pub enum Error { InvalidFixedValue { expected: u64, actual: u64 }, #[error("when parsing {obj} needed length of {wanted} but got {got}")] InvalidLengthError { obj: String, wanted: usize, got: usize }, - #[error("array size ({array} bytes) is not a multiple of the element size ({element} bytes)")] + #[error( + "array size ({array} bytes) is not a multiple of the element size ({element} bytes)" + )] InvalidArraySize { array: usize, element: usize }, #[error("Due to size restrictions a struct could not be parsed.")] ImpossibleStructError, @@ -41,12 +40,10 @@ pub enum Error { #[error("expected child {expected}, got {actual}")] InvalidChildError { expected: &'static str, actual: String }, } - pub trait Packet { fn to_bytes(self) -> Bytes; fn to_vec(self) -> Vec; } - #[derive(Debug, Clone, PartialEq, Eq)] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] pub struct FooData {} diff --git a/tools/pdl/tests/generated/packet_decl_fixed_enum_field_big_endian.rs b/tools/pdl/tests/generated/packet_decl_fixed_enum_field_big_endian.rs index 5736028b3da..8683e02959e 100644 --- a/tools/pdl/tests/generated/packet_decl_fixed_enum_field_big_endian.rs +++ b/tools/pdl/tests/generated/packet_decl_fixed_enum_field_big_endian.rs @@ -1,18 +1,16 @@ -// @generated rust packets from test - +#![rustfmt::skip] +/// @generated rust packets from test. use bytes::{Buf, BufMut, Bytes, BytesMut}; -use std::cell::Cell; use std::convert::{TryFrom, TryInto}; +use std::cell::Cell; use std::fmt; use std::sync::Arc; use thiserror::Error; - type Result = std::result::Result; - -#[doc = r" Private prevents users from creating arbitrary scalar values"] -#[doc = r" in situations where the value needs to be validated."] -#[doc = r" Users can freely deref the value, but only the backend"] -#[doc = r" may create it."] +/// Private prevents users from creating arbitrary scalar values +/// in situations where the value needs to be validated. +/// Users can freely deref the value, but only the backend +/// may create it. #[derive(Debug, Clone, Copy, Hash, PartialEq, Eq, PartialOrd, Ord)] pub struct Private(T); impl std::ops::Deref for Private { @@ -21,7 +19,6 @@ impl std::ops::Deref for Private { &self.0 } } - #[derive(Debug, Error)] pub enum Error { #[error("Packet parsing failed")] @@ -32,7 +29,9 @@ pub enum Error { InvalidFixedValue { expected: u64, actual: u64 }, #[error("when parsing {obj} needed length of {wanted} but got {got}")] InvalidLengthError { obj: String, wanted: usize, got: usize }, - #[error("array size ({array} bytes) is not a multiple of the element size ({element} bytes)")] + #[error( + "array size ({array} bytes) is not a multiple of the element size ({element} bytes)" + )] InvalidArraySize { array: usize, element: usize }, #[error("Due to size restrictions a struct could not be parsed.")] ImpossibleStructError, @@ -41,12 +40,10 @@ pub enum Error { #[error("expected child {expected}, got {actual}")] InvalidChildError { expected: &'static str, actual: String }, } - pub trait Packet { fn to_bytes(self) -> Bytes; fn to_vec(self) -> Vec; } - #[repr(u64)] #[derive(Debug, Clone, Copy, Hash, Eq, PartialEq)] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] @@ -113,7 +110,6 @@ impl From for u64 { u8::from(value) as Self } } - #[derive(Debug, Clone, PartialEq, Eq)] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] pub struct FooData { @@ -160,8 +156,8 @@ impl FooData { fn write_to(&self, buffer: &mut BytesMut) { if self.b > 0x1ff_ffff_ffff_ffff_u64 { panic!( - "Invalid value for {}::{}: {} > {}", - "Foo", "b", self.b, 0x1ff_ffff_ffff_ffff_u64 + "Invalid value for {}::{}: {} > {}", "Foo", "b", self.b, + 0x1ff_ffff_ffff_ffff_u64 ); } let value = (u8::from(Enum7::A) as u64) | (self.b << 7); diff --git a/tools/pdl/tests/generated/packet_decl_fixed_enum_field_little_endian.rs b/tools/pdl/tests/generated/packet_decl_fixed_enum_field_little_endian.rs index ec39ae01990..f598d3e7192 100644 --- a/tools/pdl/tests/generated/packet_decl_fixed_enum_field_little_endian.rs +++ b/tools/pdl/tests/generated/packet_decl_fixed_enum_field_little_endian.rs @@ -1,18 +1,16 @@ -// @generated rust packets from test - +#![rustfmt::skip] +/// @generated rust packets from test. use bytes::{Buf, BufMut, Bytes, BytesMut}; -use std::cell::Cell; use std::convert::{TryFrom, TryInto}; +use std::cell::Cell; use std::fmt; use std::sync::Arc; use thiserror::Error; - type Result = std::result::Result; - -#[doc = r" Private prevents users from creating arbitrary scalar values"] -#[doc = r" in situations where the value needs to be validated."] -#[doc = r" Users can freely deref the value, but only the backend"] -#[doc = r" may create it."] +/// Private prevents users from creating arbitrary scalar values +/// in situations where the value needs to be validated. +/// Users can freely deref the value, but only the backend +/// may create it. #[derive(Debug, Clone, Copy, Hash, PartialEq, Eq, PartialOrd, Ord)] pub struct Private(T); impl std::ops::Deref for Private { @@ -21,7 +19,6 @@ impl std::ops::Deref for Private { &self.0 } } - #[derive(Debug, Error)] pub enum Error { #[error("Packet parsing failed")] @@ -32,7 +29,9 @@ pub enum Error { InvalidFixedValue { expected: u64, actual: u64 }, #[error("when parsing {obj} needed length of {wanted} but got {got}")] InvalidLengthError { obj: String, wanted: usize, got: usize }, - #[error("array size ({array} bytes) is not a multiple of the element size ({element} bytes)")] + #[error( + "array size ({array} bytes) is not a multiple of the element size ({element} bytes)" + )] InvalidArraySize { array: usize, element: usize }, #[error("Due to size restrictions a struct could not be parsed.")] ImpossibleStructError, @@ -41,12 +40,10 @@ pub enum Error { #[error("expected child {expected}, got {actual}")] InvalidChildError { expected: &'static str, actual: String }, } - pub trait Packet { fn to_bytes(self) -> Bytes; fn to_vec(self) -> Vec; } - #[repr(u64)] #[derive(Debug, Clone, Copy, Hash, Eq, PartialEq)] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] @@ -113,7 +110,6 @@ impl From for u64 { u8::from(value) as Self } } - #[derive(Debug, Clone, PartialEq, Eq)] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] pub struct FooData { @@ -160,8 +156,8 @@ impl FooData { fn write_to(&self, buffer: &mut BytesMut) { if self.b > 0x1ff_ffff_ffff_ffff_u64 { panic!( - "Invalid value for {}::{}: {} > {}", - "Foo", "b", self.b, 0x1ff_ffff_ffff_ffff_u64 + "Invalid value for {}::{}: {} > {}", "Foo", "b", self.b, + 0x1ff_ffff_ffff_ffff_u64 ); } let value = (u8::from(Enum7::A) as u64) | (self.b << 7); diff --git a/tools/pdl/tests/generated/packet_decl_fixed_scalar_field_big_endian.rs b/tools/pdl/tests/generated/packet_decl_fixed_scalar_field_big_endian.rs index 8623d8b4b25..a44732ebce9 100644 --- a/tools/pdl/tests/generated/packet_decl_fixed_scalar_field_big_endian.rs +++ b/tools/pdl/tests/generated/packet_decl_fixed_scalar_field_big_endian.rs @@ -1,18 +1,16 @@ -// @generated rust packets from test - +#![rustfmt::skip] +/// @generated rust packets from test. use bytes::{Buf, BufMut, Bytes, BytesMut}; -use std::cell::Cell; use std::convert::{TryFrom, TryInto}; +use std::cell::Cell; use std::fmt; use std::sync::Arc; use thiserror::Error; - type Result = std::result::Result; - -#[doc = r" Private prevents users from creating arbitrary scalar values"] -#[doc = r" in situations where the value needs to be validated."] -#[doc = r" Users can freely deref the value, but only the backend"] -#[doc = r" may create it."] +/// Private prevents users from creating arbitrary scalar values +/// in situations where the value needs to be validated. +/// Users can freely deref the value, but only the backend +/// may create it. #[derive(Debug, Clone, Copy, Hash, PartialEq, Eq, PartialOrd, Ord)] pub struct Private(T); impl std::ops::Deref for Private { @@ -21,7 +19,6 @@ impl std::ops::Deref for Private { &self.0 } } - #[derive(Debug, Error)] pub enum Error { #[error("Packet parsing failed")] @@ -32,7 +29,9 @@ pub enum Error { InvalidFixedValue { expected: u64, actual: u64 }, #[error("when parsing {obj} needed length of {wanted} but got {got}")] InvalidLengthError { obj: String, wanted: usize, got: usize }, - #[error("array size ({array} bytes) is not a multiple of the element size ({element} bytes)")] + #[error( + "array size ({array} bytes) is not a multiple of the element size ({element} bytes)" + )] InvalidArraySize { array: usize, element: usize }, #[error("Due to size restrictions a struct could not be parsed.")] ImpossibleStructError, @@ -41,12 +40,10 @@ pub enum Error { #[error("expected child {expected}, got {actual}")] InvalidChildError { expected: &'static str, actual: String }, } - pub trait Packet { fn to_bytes(self) -> Bytes; fn to_vec(self) -> Vec; } - #[derive(Debug, Clone, PartialEq, Eq)] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] pub struct FooData { @@ -93,8 +90,8 @@ impl FooData { fn write_to(&self, buffer: &mut BytesMut) { if self.b > 0x1ff_ffff_ffff_ffff_u64 { panic!( - "Invalid value for {}::{}: {} > {}", - "Foo", "b", self.b, 0x1ff_ffff_ffff_ffff_u64 + "Invalid value for {}::{}: {} > {}", "Foo", "b", self.b, + 0x1ff_ffff_ffff_ffff_u64 ); } let value = (7 as u64) | (self.b << 7); diff --git a/tools/pdl/tests/generated/packet_decl_fixed_scalar_field_little_endian.rs b/tools/pdl/tests/generated/packet_decl_fixed_scalar_field_little_endian.rs index 42d4a8f3ffe..d2c7985aa1b 100644 --- a/tools/pdl/tests/generated/packet_decl_fixed_scalar_field_little_endian.rs +++ b/tools/pdl/tests/generated/packet_decl_fixed_scalar_field_little_endian.rs @@ -1,18 +1,16 @@ -// @generated rust packets from test - +#![rustfmt::skip] +/// @generated rust packets from test. use bytes::{Buf, BufMut, Bytes, BytesMut}; -use std::cell::Cell; use std::convert::{TryFrom, TryInto}; +use std::cell::Cell; use std::fmt; use std::sync::Arc; use thiserror::Error; - type Result = std::result::Result; - -#[doc = r" Private prevents users from creating arbitrary scalar values"] -#[doc = r" in situations where the value needs to be validated."] -#[doc = r" Users can freely deref the value, but only the backend"] -#[doc = r" may create it."] +/// Private prevents users from creating arbitrary scalar values +/// in situations where the value needs to be validated. +/// Users can freely deref the value, but only the backend +/// may create it. #[derive(Debug, Clone, Copy, Hash, PartialEq, Eq, PartialOrd, Ord)] pub struct Private(T); impl std::ops::Deref for Private { @@ -21,7 +19,6 @@ impl std::ops::Deref for Private { &self.0 } } - #[derive(Debug, Error)] pub enum Error { #[error("Packet parsing failed")] @@ -32,7 +29,9 @@ pub enum Error { InvalidFixedValue { expected: u64, actual: u64 }, #[error("when parsing {obj} needed length of {wanted} but got {got}")] InvalidLengthError { obj: String, wanted: usize, got: usize }, - #[error("array size ({array} bytes) is not a multiple of the element size ({element} bytes)")] + #[error( + "array size ({array} bytes) is not a multiple of the element size ({element} bytes)" + )] InvalidArraySize { array: usize, element: usize }, #[error("Due to size restrictions a struct could not be parsed.")] ImpossibleStructError, @@ -41,12 +40,10 @@ pub enum Error { #[error("expected child {expected}, got {actual}")] InvalidChildError { expected: &'static str, actual: String }, } - pub trait Packet { fn to_bytes(self) -> Bytes; fn to_vec(self) -> Vec; } - #[derive(Debug, Clone, PartialEq, Eq)] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] pub struct FooData { @@ -93,8 +90,8 @@ impl FooData { fn write_to(&self, buffer: &mut BytesMut) { if self.b > 0x1ff_ffff_ffff_ffff_u64 { panic!( - "Invalid value for {}::{}: {} > {}", - "Foo", "b", self.b, 0x1ff_ffff_ffff_ffff_u64 + "Invalid value for {}::{}: {} > {}", "Foo", "b", self.b, + 0x1ff_ffff_ffff_ffff_u64 ); } let value = (7 as u64) | (self.b << 7); diff --git a/tools/pdl/tests/generated/packet_decl_grand_children_big_endian.rs b/tools/pdl/tests/generated/packet_decl_grand_children_big_endian.rs index 96bca77d887..33432f3e01d 100644 --- a/tools/pdl/tests/generated/packet_decl_grand_children_big_endian.rs +++ b/tools/pdl/tests/generated/packet_decl_grand_children_big_endian.rs @@ -1,18 +1,16 @@ -// @generated rust packets from test - +#![rustfmt::skip] +/// @generated rust packets from test. use bytes::{Buf, BufMut, Bytes, BytesMut}; -use std::cell::Cell; use std::convert::{TryFrom, TryInto}; +use std::cell::Cell; use std::fmt; use std::sync::Arc; use thiserror::Error; - type Result = std::result::Result; - -#[doc = r" Private prevents users from creating arbitrary scalar values"] -#[doc = r" in situations where the value needs to be validated."] -#[doc = r" Users can freely deref the value, but only the backend"] -#[doc = r" may create it."] +/// Private prevents users from creating arbitrary scalar values +/// in situations where the value needs to be validated. +/// Users can freely deref the value, but only the backend +/// may create it. #[derive(Debug, Clone, Copy, Hash, PartialEq, Eq, PartialOrd, Ord)] pub struct Private(T); impl std::ops::Deref for Private { @@ -21,7 +19,6 @@ impl std::ops::Deref for Private { &self.0 } } - #[derive(Debug, Error)] pub enum Error { #[error("Packet parsing failed")] @@ -32,7 +29,9 @@ pub enum Error { InvalidFixedValue { expected: u64, actual: u64 }, #[error("when parsing {obj} needed length of {wanted} but got {got}")] InvalidLengthError { obj: String, wanted: usize, got: usize }, - #[error("array size ({array} bytes) is not a multiple of the element size ({element} bytes)")] + #[error( + "array size ({array} bytes) is not a multiple of the element size ({element} bytes)" + )] InvalidArraySize { array: usize, element: usize }, #[error("Due to size restrictions a struct could not be parsed.")] ImpossibleStructError, @@ -41,12 +40,10 @@ pub enum Error { #[error("expected child {expected}, got {actual}")] InvalidChildError { expected: &'static str, actual: String }, } - pub trait Packet { fn to_bytes(self) -> Bytes; fn to_vec(self) -> Vec; } - #[repr(u64)] #[derive(Debug, Clone, Copy, Hash, Eq, PartialEq)] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] @@ -98,7 +95,6 @@ impl From for u64 { u16::from(value) as Self } } - #[derive(Debug, Clone, PartialEq, Eq)] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] pub enum ParentDataChild { @@ -161,14 +157,13 @@ impl ParentData { got: bytes.get().remaining(), }); } - let foo = Enum16::try_from(bytes.get_mut().get_u16()).map_err(|_| { - Error::InvalidEnumValueError { + let foo = Enum16::try_from(bytes.get_mut().get_u16()) + .map_err(|_| Error::InvalidEnumValueError { obj: "Parent".to_string(), field: "foo".to_string(), value: bytes.get_mut().get_u16() as u64, type_: "Enum16".to_string(), - } - })?; + })?; if bytes.get().remaining() < 2 { return Err(Error::InvalidLengthError { obj: "Parent".to_string(), @@ -176,14 +171,13 @@ impl ParentData { got: bytes.get().remaining(), }); } - let bar = Enum16::try_from(bytes.get_mut().get_u16()).map_err(|_| { - Error::InvalidEnumValueError { + let bar = Enum16::try_from(bytes.get_mut().get_u16()) + .map_err(|_| Error::InvalidEnumValueError { obj: "Parent".to_string(), field: "bar".to_string(), value: bytes.get_mut().get_u16() as u64, type_: "Enum16".to_string(), - } - })?; + })?; if bytes.get().remaining() < 2 { return Err(Error::InvalidLengthError { obj: "Parent".to_string(), @@ -191,14 +185,13 @@ impl ParentData { got: bytes.get().remaining(), }); } - let baz = Enum16::try_from(bytes.get_mut().get_u16()).map_err(|_| { - Error::InvalidEnumValueError { + let baz = Enum16::try_from(bytes.get_mut().get_u16()) + .map_err(|_| Error::InvalidEnumValueError { obj: "Parent".to_string(), field: "baz".to_string(), value: bytes.get_mut().get_u16() as u64, type_: "Enum16".to_string(), - } - })?; + })?; if bytes.get().remaining() < 1 { return Err(Error::InvalidLengthError { obj: "Parent".to_string(), @@ -222,7 +215,9 @@ impl ParentData { let child_data = ChildData::parse_inner(&mut cell, bar, baz)?; ParentDataChild::Child(Arc::new(child_data)) } - _ if !payload.is_empty() => ParentDataChild::Payload(Bytes::copy_from_slice(payload)), + _ if !payload.is_empty() => { + ParentDataChild::Payload(Bytes::copy_from_slice(payload)) + } _ => ParentDataChild::None, }; Ok(Self { foo, bar, baz, child }) @@ -233,11 +228,8 @@ impl ParentData { buffer.put_u16(u16::from(self.baz)); if self.child.get_total_size() > 0xff { panic!( - "Invalid length for {}::{}: {} > {}", - "Parent", - "_payload_", - self.child.get_total_size(), - 0xff + "Invalid length for {}::{}: {} > {}", "Parent", "_payload_", self.child + .get_total_size(), 0xff ); } buffer.put_u8(self.child.get_total_size() as u8); @@ -331,7 +323,6 @@ impl From for Parent { builder.build().into() } } - #[derive(Debug, Clone, PartialEq, Eq)] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] pub enum ChildDataChild { @@ -386,7 +377,11 @@ impl ChildData { let packet = Self::parse_inner(&mut cell, bar, baz)?; Ok(packet) } - fn parse_inner(mut bytes: &mut Cell<&[u8]>, bar: Enum16, baz: Enum16) -> Result { + fn parse_inner( + mut bytes: &mut Cell<&[u8]>, + bar: Enum16, + baz: Enum16, + ) -> Result { if bytes.get().remaining() < 2 { return Err(Error::InvalidLengthError { obj: "Child".to_string(), @@ -394,14 +389,13 @@ impl ChildData { got: bytes.get().remaining(), }); } - let quux = Enum16::try_from(bytes.get_mut().get_u16()).map_err(|_| { - Error::InvalidEnumValueError { + let quux = Enum16::try_from(bytes.get_mut().get_u16()) + .map_err(|_| Error::InvalidEnumValueError { obj: "Child".to_string(), field: "quux".to_string(), value: bytes.get_mut().get_u16() as u64, type_: "Enum16".to_string(), - } - })?; + })?; let payload = bytes.get(); bytes.get_mut().advance(payload.len()); let child = match (bar, quux) { @@ -410,7 +404,9 @@ impl ChildData { let child_data = GrandChildData::parse_inner(&mut cell, baz)?; ChildDataChild::GrandChild(Arc::new(child_data)) } - _ if !payload.is_empty() => ChildDataChild::Payload(Bytes::copy_from_slice(payload)), + _ if !payload.is_empty() => { + ChildDataChild::Payload(Bytes::copy_from_slice(payload)) + } _ => ChildDataChild::None, }; Ok(Self { quux, child }) @@ -486,8 +482,8 @@ impl Child { _ => { return Err(Error::InvalidChildError { expected: stringify!(ParentDataChild::Child), - actual: format!("{:?}", &parent.child), - }) + actual: format!("{:?}", & parent.child), + }); } }; Ok(Self { parent, child }) @@ -539,7 +535,6 @@ impl From for Child { builder.build().into() } } - #[derive(Debug, Clone, PartialEq, Eq)] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] pub enum GrandChildDataChild { @@ -672,9 +667,13 @@ impl GrandChild { pub fn specialize(&self) -> GrandChildChild { match &self.grandchild.child { GrandChildDataChild::GrandGrandChild(_) => { - GrandChildChild::GrandGrandChild(GrandGrandChild::new(self.parent.clone()).unwrap()) + GrandChildChild::GrandGrandChild( + GrandGrandChild::new(self.parent.clone()).unwrap(), + ) + } + GrandChildDataChild::Payload(payload) => { + GrandChildChild::Payload(payload.clone()) } - GrandChildDataChild::Payload(payload) => GrandChildChild::Payload(payload.clone()), GrandChildDataChild::None => GrandChildChild::None, } } @@ -684,8 +683,8 @@ impl GrandChild { _ => { return Err(Error::InvalidChildError { expected: stringify!(ParentDataChild::Child), - actual: format!("{:?}", &parent.child), - }) + actual: format!("{:?}", & parent.child), + }); } }; let grandchild = match &child.child { @@ -693,8 +692,8 @@ impl GrandChild { _ => { return Err(Error::InvalidChildError { expected: stringify!(ChildDataChild::GrandChild), - actual: format!("{:?}", &child.child), - }) + actual: format!("{:?}", & child.child), + }); } }; Ok(Self { parent, child, grandchild }) @@ -726,8 +725,10 @@ impl GrandChildBuilder { Some(bytes) => GrandChildDataChild::Payload(bytes), }, }); - let child = - Arc::new(ChildData { quux: Enum16::A, child: ChildDataChild::GrandChild(grandchild) }); + let child = Arc::new(ChildData { + quux: Enum16::A, + child: ChildDataChild::GrandChild(grandchild), + }); let parent = Arc::new(ParentData { bar: Enum16::A, baz: self.baz, @@ -752,7 +753,6 @@ impl From for GrandChild { builder.build().into() } } - #[derive(Debug, Clone, PartialEq, Eq)] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] pub enum GrandGrandChildDataChild { @@ -893,8 +893,8 @@ impl GrandGrandChild { _ => { return Err(Error::InvalidChildError { expected: stringify!(ParentDataChild::Child), - actual: format!("{:?}", &parent.child), - }) + actual: format!("{:?}", & parent.child), + }); } }; let grandchild = match &child.child { @@ -902,8 +902,8 @@ impl GrandGrandChild { _ => { return Err(Error::InvalidChildError { expected: stringify!(ChildDataChild::GrandChild), - actual: format!("{:?}", &child.child), - }) + actual: format!("{:?}", & child.child), + }); } }; let grandgrandchild = match &grandchild.child { @@ -911,11 +911,16 @@ impl GrandGrandChild { _ => { return Err(Error::InvalidChildError { expected: stringify!(GrandChildDataChild::GrandGrandChild), - actual: format!("{:?}", &grandchild.child), - }) + actual: format!("{:?}", & grandchild.child), + }); } }; - Ok(Self { parent, child, grandchild, grandgrandchild }) + Ok(Self { + parent, + child, + grandchild, + grandgrandchild, + }) } pub fn get_bar(&self) -> Enum16 { self.parent.as_ref().bar @@ -953,8 +958,10 @@ impl GrandGrandChildBuilder { let grandchild = Arc::new(GrandChildData { child: GrandChildDataChild::GrandGrandChild(grandgrandchild), }); - let child = - Arc::new(ChildData { quux: Enum16::A, child: ChildDataChild::GrandChild(grandchild) }); + let child = Arc::new(ChildData { + quux: Enum16::A, + child: ChildDataChild::GrandChild(grandchild), + }); let parent = Arc::new(ParentData { bar: Enum16::A, baz: Enum16::A, diff --git a/tools/pdl/tests/generated/packet_decl_grand_children_little_endian.rs b/tools/pdl/tests/generated/packet_decl_grand_children_little_endian.rs index 16af6fcfbab..c223814d2b3 100644 --- a/tools/pdl/tests/generated/packet_decl_grand_children_little_endian.rs +++ b/tools/pdl/tests/generated/packet_decl_grand_children_little_endian.rs @@ -1,18 +1,16 @@ -// @generated rust packets from test - +#![rustfmt::skip] +/// @generated rust packets from test. use bytes::{Buf, BufMut, Bytes, BytesMut}; -use std::cell::Cell; use std::convert::{TryFrom, TryInto}; +use std::cell::Cell; use std::fmt; use std::sync::Arc; use thiserror::Error; - type Result = std::result::Result; - -#[doc = r" Private prevents users from creating arbitrary scalar values"] -#[doc = r" in situations where the value needs to be validated."] -#[doc = r" Users can freely deref the value, but only the backend"] -#[doc = r" may create it."] +/// Private prevents users from creating arbitrary scalar values +/// in situations where the value needs to be validated. +/// Users can freely deref the value, but only the backend +/// may create it. #[derive(Debug, Clone, Copy, Hash, PartialEq, Eq, PartialOrd, Ord)] pub struct Private(T); impl std::ops::Deref for Private { @@ -21,7 +19,6 @@ impl std::ops::Deref for Private { &self.0 } } - #[derive(Debug, Error)] pub enum Error { #[error("Packet parsing failed")] @@ -32,7 +29,9 @@ pub enum Error { InvalidFixedValue { expected: u64, actual: u64 }, #[error("when parsing {obj} needed length of {wanted} but got {got}")] InvalidLengthError { obj: String, wanted: usize, got: usize }, - #[error("array size ({array} bytes) is not a multiple of the element size ({element} bytes)")] + #[error( + "array size ({array} bytes) is not a multiple of the element size ({element} bytes)" + )] InvalidArraySize { array: usize, element: usize }, #[error("Due to size restrictions a struct could not be parsed.")] ImpossibleStructError, @@ -41,12 +40,10 @@ pub enum Error { #[error("expected child {expected}, got {actual}")] InvalidChildError { expected: &'static str, actual: String }, } - pub trait Packet { fn to_bytes(self) -> Bytes; fn to_vec(self) -> Vec; } - #[repr(u64)] #[derive(Debug, Clone, Copy, Hash, Eq, PartialEq)] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] @@ -98,7 +95,6 @@ impl From for u64 { u16::from(value) as Self } } - #[derive(Debug, Clone, PartialEq, Eq)] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] pub enum ParentDataChild { @@ -161,14 +157,13 @@ impl ParentData { got: bytes.get().remaining(), }); } - let foo = Enum16::try_from(bytes.get_mut().get_u16_le()).map_err(|_| { - Error::InvalidEnumValueError { + let foo = Enum16::try_from(bytes.get_mut().get_u16_le()) + .map_err(|_| Error::InvalidEnumValueError { obj: "Parent".to_string(), field: "foo".to_string(), value: bytes.get_mut().get_u16_le() as u64, type_: "Enum16".to_string(), - } - })?; + })?; if bytes.get().remaining() < 2 { return Err(Error::InvalidLengthError { obj: "Parent".to_string(), @@ -176,14 +171,13 @@ impl ParentData { got: bytes.get().remaining(), }); } - let bar = Enum16::try_from(bytes.get_mut().get_u16_le()).map_err(|_| { - Error::InvalidEnumValueError { + let bar = Enum16::try_from(bytes.get_mut().get_u16_le()) + .map_err(|_| Error::InvalidEnumValueError { obj: "Parent".to_string(), field: "bar".to_string(), value: bytes.get_mut().get_u16_le() as u64, type_: "Enum16".to_string(), - } - })?; + })?; if bytes.get().remaining() < 2 { return Err(Error::InvalidLengthError { obj: "Parent".to_string(), @@ -191,14 +185,13 @@ impl ParentData { got: bytes.get().remaining(), }); } - let baz = Enum16::try_from(bytes.get_mut().get_u16_le()).map_err(|_| { - Error::InvalidEnumValueError { + let baz = Enum16::try_from(bytes.get_mut().get_u16_le()) + .map_err(|_| Error::InvalidEnumValueError { obj: "Parent".to_string(), field: "baz".to_string(), value: bytes.get_mut().get_u16_le() as u64, type_: "Enum16".to_string(), - } - })?; + })?; if bytes.get().remaining() < 1 { return Err(Error::InvalidLengthError { obj: "Parent".to_string(), @@ -222,7 +215,9 @@ impl ParentData { let child_data = ChildData::parse_inner(&mut cell, bar, baz)?; ParentDataChild::Child(Arc::new(child_data)) } - _ if !payload.is_empty() => ParentDataChild::Payload(Bytes::copy_from_slice(payload)), + _ if !payload.is_empty() => { + ParentDataChild::Payload(Bytes::copy_from_slice(payload)) + } _ => ParentDataChild::None, }; Ok(Self { foo, bar, baz, child }) @@ -233,11 +228,8 @@ impl ParentData { buffer.put_u16_le(u16::from(self.baz)); if self.child.get_total_size() > 0xff { panic!( - "Invalid length for {}::{}: {} > {}", - "Parent", - "_payload_", - self.child.get_total_size(), - 0xff + "Invalid length for {}::{}: {} > {}", "Parent", "_payload_", self.child + .get_total_size(), 0xff ); } buffer.put_u8(self.child.get_total_size() as u8); @@ -331,7 +323,6 @@ impl From for Parent { builder.build().into() } } - #[derive(Debug, Clone, PartialEq, Eq)] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] pub enum ChildDataChild { @@ -386,7 +377,11 @@ impl ChildData { let packet = Self::parse_inner(&mut cell, bar, baz)?; Ok(packet) } - fn parse_inner(mut bytes: &mut Cell<&[u8]>, bar: Enum16, baz: Enum16) -> Result { + fn parse_inner( + mut bytes: &mut Cell<&[u8]>, + bar: Enum16, + baz: Enum16, + ) -> Result { if bytes.get().remaining() < 2 { return Err(Error::InvalidLengthError { obj: "Child".to_string(), @@ -394,14 +389,13 @@ impl ChildData { got: bytes.get().remaining(), }); } - let quux = Enum16::try_from(bytes.get_mut().get_u16_le()).map_err(|_| { - Error::InvalidEnumValueError { + let quux = Enum16::try_from(bytes.get_mut().get_u16_le()) + .map_err(|_| Error::InvalidEnumValueError { obj: "Child".to_string(), field: "quux".to_string(), value: bytes.get_mut().get_u16_le() as u64, type_: "Enum16".to_string(), - } - })?; + })?; let payload = bytes.get(); bytes.get_mut().advance(payload.len()); let child = match (bar, quux) { @@ -410,7 +404,9 @@ impl ChildData { let child_data = GrandChildData::parse_inner(&mut cell, baz)?; ChildDataChild::GrandChild(Arc::new(child_data)) } - _ if !payload.is_empty() => ChildDataChild::Payload(Bytes::copy_from_slice(payload)), + _ if !payload.is_empty() => { + ChildDataChild::Payload(Bytes::copy_from_slice(payload)) + } _ => ChildDataChild::None, }; Ok(Self { quux, child }) @@ -486,8 +482,8 @@ impl Child { _ => { return Err(Error::InvalidChildError { expected: stringify!(ParentDataChild::Child), - actual: format!("{:?}", &parent.child), - }) + actual: format!("{:?}", & parent.child), + }); } }; Ok(Self { parent, child }) @@ -539,7 +535,6 @@ impl From for Child { builder.build().into() } } - #[derive(Debug, Clone, PartialEq, Eq)] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] pub enum GrandChildDataChild { @@ -672,9 +667,13 @@ impl GrandChild { pub fn specialize(&self) -> GrandChildChild { match &self.grandchild.child { GrandChildDataChild::GrandGrandChild(_) => { - GrandChildChild::GrandGrandChild(GrandGrandChild::new(self.parent.clone()).unwrap()) + GrandChildChild::GrandGrandChild( + GrandGrandChild::new(self.parent.clone()).unwrap(), + ) + } + GrandChildDataChild::Payload(payload) => { + GrandChildChild::Payload(payload.clone()) } - GrandChildDataChild::Payload(payload) => GrandChildChild::Payload(payload.clone()), GrandChildDataChild::None => GrandChildChild::None, } } @@ -684,8 +683,8 @@ impl GrandChild { _ => { return Err(Error::InvalidChildError { expected: stringify!(ParentDataChild::Child), - actual: format!("{:?}", &parent.child), - }) + actual: format!("{:?}", & parent.child), + }); } }; let grandchild = match &child.child { @@ -693,8 +692,8 @@ impl GrandChild { _ => { return Err(Error::InvalidChildError { expected: stringify!(ChildDataChild::GrandChild), - actual: format!("{:?}", &child.child), - }) + actual: format!("{:?}", & child.child), + }); } }; Ok(Self { parent, child, grandchild }) @@ -726,8 +725,10 @@ impl GrandChildBuilder { Some(bytes) => GrandChildDataChild::Payload(bytes), }, }); - let child = - Arc::new(ChildData { quux: Enum16::A, child: ChildDataChild::GrandChild(grandchild) }); + let child = Arc::new(ChildData { + quux: Enum16::A, + child: ChildDataChild::GrandChild(grandchild), + }); let parent = Arc::new(ParentData { bar: Enum16::A, baz: self.baz, @@ -752,7 +753,6 @@ impl From for GrandChild { builder.build().into() } } - #[derive(Debug, Clone, PartialEq, Eq)] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] pub enum GrandGrandChildDataChild { @@ -893,8 +893,8 @@ impl GrandGrandChild { _ => { return Err(Error::InvalidChildError { expected: stringify!(ParentDataChild::Child), - actual: format!("{:?}", &parent.child), - }) + actual: format!("{:?}", & parent.child), + }); } }; let grandchild = match &child.child { @@ -902,8 +902,8 @@ impl GrandGrandChild { _ => { return Err(Error::InvalidChildError { expected: stringify!(ChildDataChild::GrandChild), - actual: format!("{:?}", &child.child), - }) + actual: format!("{:?}", & child.child), + }); } }; let grandgrandchild = match &grandchild.child { @@ -911,11 +911,16 @@ impl GrandGrandChild { _ => { return Err(Error::InvalidChildError { expected: stringify!(GrandChildDataChild::GrandGrandChild), - actual: format!("{:?}", &grandchild.child), - }) + actual: format!("{:?}", & grandchild.child), + }); } }; - Ok(Self { parent, child, grandchild, grandgrandchild }) + Ok(Self { + parent, + child, + grandchild, + grandgrandchild, + }) } pub fn get_bar(&self) -> Enum16 { self.parent.as_ref().bar @@ -953,8 +958,10 @@ impl GrandGrandChildBuilder { let grandchild = Arc::new(GrandChildData { child: GrandChildDataChild::GrandGrandChild(grandgrandchild), }); - let child = - Arc::new(ChildData { quux: Enum16::A, child: ChildDataChild::GrandChild(grandchild) }); + let child = Arc::new(ChildData { + quux: Enum16::A, + child: ChildDataChild::GrandChild(grandchild), + }); let parent = Arc::new(ParentData { bar: Enum16::A, baz: Enum16::A, diff --git a/tools/pdl/tests/generated/packet_decl_mask_scalar_value_big_endian.rs b/tools/pdl/tests/generated/packet_decl_mask_scalar_value_big_endian.rs index 6879967e728..581542d44e0 100644 --- a/tools/pdl/tests/generated/packet_decl_mask_scalar_value_big_endian.rs +++ b/tools/pdl/tests/generated/packet_decl_mask_scalar_value_big_endian.rs @@ -1,18 +1,16 @@ -// @generated rust packets from test - +#![rustfmt::skip] +/// @generated rust packets from test. use bytes::{Buf, BufMut, Bytes, BytesMut}; -use std::cell::Cell; use std::convert::{TryFrom, TryInto}; +use std::cell::Cell; use std::fmt; use std::sync::Arc; use thiserror::Error; - type Result = std::result::Result; - -#[doc = r" Private prevents users from creating arbitrary scalar values"] -#[doc = r" in situations where the value needs to be validated."] -#[doc = r" Users can freely deref the value, but only the backend"] -#[doc = r" may create it."] +/// Private prevents users from creating arbitrary scalar values +/// in situations where the value needs to be validated. +/// Users can freely deref the value, but only the backend +/// may create it. #[derive(Debug, Clone, Copy, Hash, PartialEq, Eq, PartialOrd, Ord)] pub struct Private(T); impl std::ops::Deref for Private { @@ -21,7 +19,6 @@ impl std::ops::Deref for Private { &self.0 } } - #[derive(Debug, Error)] pub enum Error { #[error("Packet parsing failed")] @@ -32,7 +29,9 @@ pub enum Error { InvalidFixedValue { expected: u64, actual: u64 }, #[error("when parsing {obj} needed length of {wanted} but got {got}")] InvalidLengthError { obj: String, wanted: usize, got: usize }, - #[error("array size ({array} bytes) is not a multiple of the element size ({element} bytes)")] + #[error( + "array size ({array} bytes) is not a multiple of the element size ({element} bytes)" + )] InvalidArraySize { array: usize, element: usize }, #[error("Due to size restrictions a struct could not be parsed.")] ImpossibleStructError, @@ -41,12 +40,10 @@ pub enum Error { #[error("expected child {expected}, got {actual}")] InvalidChildError { expected: &'static str, actual: String }, } - pub trait Packet { fn to_bytes(self) -> Bytes; fn to_vec(self) -> Vec; } - #[derive(Debug, Clone, PartialEq, Eq)] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] pub struct FooData { @@ -161,7 +158,11 @@ impl Foo { } impl FooBuilder { pub fn build(self) -> Foo { - let foo = Arc::new(FooData { a: self.a, b: self.b, c: self.c }); + let foo = Arc::new(FooData { + a: self.a, + b: self.b, + c: self.c, + }); Foo::new(foo).unwrap() } } diff --git a/tools/pdl/tests/generated/packet_decl_mask_scalar_value_little_endian.rs b/tools/pdl/tests/generated/packet_decl_mask_scalar_value_little_endian.rs index b4c5b3c3579..9bce70a0522 100644 --- a/tools/pdl/tests/generated/packet_decl_mask_scalar_value_little_endian.rs +++ b/tools/pdl/tests/generated/packet_decl_mask_scalar_value_little_endian.rs @@ -1,18 +1,16 @@ -// @generated rust packets from test - +#![rustfmt::skip] +/// @generated rust packets from test. use bytes::{Buf, BufMut, Bytes, BytesMut}; -use std::cell::Cell; use std::convert::{TryFrom, TryInto}; +use std::cell::Cell; use std::fmt; use std::sync::Arc; use thiserror::Error; - type Result = std::result::Result; - -#[doc = r" Private prevents users from creating arbitrary scalar values"] -#[doc = r" in situations where the value needs to be validated."] -#[doc = r" Users can freely deref the value, but only the backend"] -#[doc = r" may create it."] +/// Private prevents users from creating arbitrary scalar values +/// in situations where the value needs to be validated. +/// Users can freely deref the value, but only the backend +/// may create it. #[derive(Debug, Clone, Copy, Hash, PartialEq, Eq, PartialOrd, Ord)] pub struct Private(T); impl std::ops::Deref for Private { @@ -21,7 +19,6 @@ impl std::ops::Deref for Private { &self.0 } } - #[derive(Debug, Error)] pub enum Error { #[error("Packet parsing failed")] @@ -32,7 +29,9 @@ pub enum Error { InvalidFixedValue { expected: u64, actual: u64 }, #[error("when parsing {obj} needed length of {wanted} but got {got}")] InvalidLengthError { obj: String, wanted: usize, got: usize }, - #[error("array size ({array} bytes) is not a multiple of the element size ({element} bytes)")] + #[error( + "array size ({array} bytes) is not a multiple of the element size ({element} bytes)" + )] InvalidArraySize { array: usize, element: usize }, #[error("Due to size restrictions a struct could not be parsed.")] ImpossibleStructError, @@ -41,12 +40,10 @@ pub enum Error { #[error("expected child {expected}, got {actual}")] InvalidChildError { expected: &'static str, actual: String }, } - pub trait Packet { fn to_bytes(self) -> Bytes; fn to_vec(self) -> Vec; } - #[derive(Debug, Clone, PartialEq, Eq)] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] pub struct FooData { @@ -161,7 +158,11 @@ impl Foo { } impl FooBuilder { pub fn build(self) -> Foo { - let foo = Arc::new(FooData { a: self.a, b: self.b, c: self.c }); + let foo = Arc::new(FooData { + a: self.a, + b: self.b, + c: self.c, + }); Foo::new(foo).unwrap() } } diff --git a/tools/pdl/tests/generated/packet_decl_mixed_scalars_enums_big_endian.rs b/tools/pdl/tests/generated/packet_decl_mixed_scalars_enums_big_endian.rs index 49982a0a4a4..87d0ecf28ab 100644 --- a/tools/pdl/tests/generated/packet_decl_mixed_scalars_enums_big_endian.rs +++ b/tools/pdl/tests/generated/packet_decl_mixed_scalars_enums_big_endian.rs @@ -1,18 +1,16 @@ -// @generated rust packets from test - +#![rustfmt::skip] +/// @generated rust packets from test. use bytes::{Buf, BufMut, Bytes, BytesMut}; -use std::cell::Cell; use std::convert::{TryFrom, TryInto}; +use std::cell::Cell; use std::fmt; use std::sync::Arc; use thiserror::Error; - type Result = std::result::Result; - -#[doc = r" Private prevents users from creating arbitrary scalar values"] -#[doc = r" in situations where the value needs to be validated."] -#[doc = r" Users can freely deref the value, but only the backend"] -#[doc = r" may create it."] +/// Private prevents users from creating arbitrary scalar values +/// in situations where the value needs to be validated. +/// Users can freely deref the value, but only the backend +/// may create it. #[derive(Debug, Clone, Copy, Hash, PartialEq, Eq, PartialOrd, Ord)] pub struct Private(T); impl std::ops::Deref for Private { @@ -21,7 +19,6 @@ impl std::ops::Deref for Private { &self.0 } } - #[derive(Debug, Error)] pub enum Error { #[error("Packet parsing failed")] @@ -32,7 +29,9 @@ pub enum Error { InvalidFixedValue { expected: u64, actual: u64 }, #[error("when parsing {obj} needed length of {wanted} but got {got}")] InvalidLengthError { obj: String, wanted: usize, got: usize }, - #[error("array size ({array} bytes) is not a multiple of the element size ({element} bytes)")] + #[error( + "array size ({array} bytes) is not a multiple of the element size ({element} bytes)" + )] InvalidArraySize { array: usize, element: usize }, #[error("Due to size restrictions a struct could not be parsed.")] ImpossibleStructError, @@ -41,12 +40,10 @@ pub enum Error { #[error("expected child {expected}, got {actual}")] InvalidChildError { expected: &'static str, actual: String }, } - pub trait Packet { fn to_bytes(self) -> Bytes; fn to_vec(self) -> Vec; } - #[repr(u64)] #[derive(Debug, Clone, Copy, Hash, Eq, PartialEq)] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] @@ -113,7 +110,6 @@ impl From for u64 { u8::from(value) as Self } } - #[repr(u64)] #[derive(Debug, Clone, Copy, Hash, Eq, PartialEq)] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] @@ -170,7 +166,6 @@ impl From for u64 { u16::from(value) as Self } } - #[derive(Debug, Clone, PartialEq, Eq)] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] pub struct FooData { @@ -211,22 +206,21 @@ impl FooData { }); } let chunk = bytes.get_mut().get_uint(3) as u32; - let x = - Enum7::try_from((chunk & 0x7f) as u8).map_err(|_| Error::InvalidEnumValueError { + let x = Enum7::try_from((chunk & 0x7f) as u8) + .map_err(|_| Error::InvalidEnumValueError { obj: "Foo".to_string(), field: "x".to_string(), value: (chunk & 0x7f) as u8 as u64, type_: "Enum7".to_string(), })?; let y = ((chunk >> 7) & 0x1f) as u8; - let z = Enum9::try_from(((chunk >> 12) & 0x1ff) as u16).map_err(|_| { - Error::InvalidEnumValueError { + let z = Enum9::try_from(((chunk >> 12) & 0x1ff) as u16) + .map_err(|_| Error::InvalidEnumValueError { obj: "Foo".to_string(), field: "z".to_string(), value: ((chunk >> 12) & 0x1ff) as u16 as u64, type_: "Enum9".to_string(), - } - })?; + })?; let w = ((chunk >> 21) & 0x7) as u8; Ok(Self { x, y, z, w }) } @@ -237,10 +231,8 @@ impl FooData { if self.w > 0x7 { panic!("Invalid value for {}::{}: {} > {}", "Foo", "w", self.w, 0x7); } - let value = (u8::from(self.x) as u32) - | ((self.y as u32) << 7) - | ((u16::from(self.z) as u32) << 12) - | ((self.w as u32) << 21); + let value = (u8::from(self.x) as u32) | ((self.y as u32) << 7) + | ((u16::from(self.z) as u32) << 12) | ((self.w as u32) << 21); buffer.put_uint(value as u64, 3); } fn get_total_size(&self) -> usize { @@ -304,7 +296,12 @@ impl Foo { } impl FooBuilder { pub fn build(self) -> Foo { - let foo = Arc::new(FooData { w: self.w, x: self.x, y: self.y, z: self.z }); + let foo = Arc::new(FooData { + w: self.w, + x: self.x, + y: self.y, + z: self.z, + }); Foo::new(foo).unwrap() } } diff --git a/tools/pdl/tests/generated/packet_decl_mixed_scalars_enums_little_endian.rs b/tools/pdl/tests/generated/packet_decl_mixed_scalars_enums_little_endian.rs index 0ca860b8076..85297cc586e 100644 --- a/tools/pdl/tests/generated/packet_decl_mixed_scalars_enums_little_endian.rs +++ b/tools/pdl/tests/generated/packet_decl_mixed_scalars_enums_little_endian.rs @@ -1,18 +1,16 @@ -// @generated rust packets from test - +#![rustfmt::skip] +/// @generated rust packets from test. use bytes::{Buf, BufMut, Bytes, BytesMut}; -use std::cell::Cell; use std::convert::{TryFrom, TryInto}; +use std::cell::Cell; use std::fmt; use std::sync::Arc; use thiserror::Error; - type Result = std::result::Result; - -#[doc = r" Private prevents users from creating arbitrary scalar values"] -#[doc = r" in situations where the value needs to be validated."] -#[doc = r" Users can freely deref the value, but only the backend"] -#[doc = r" may create it."] +/// Private prevents users from creating arbitrary scalar values +/// in situations where the value needs to be validated. +/// Users can freely deref the value, but only the backend +/// may create it. #[derive(Debug, Clone, Copy, Hash, PartialEq, Eq, PartialOrd, Ord)] pub struct Private(T); impl std::ops::Deref for Private { @@ -21,7 +19,6 @@ impl std::ops::Deref for Private { &self.0 } } - #[derive(Debug, Error)] pub enum Error { #[error("Packet parsing failed")] @@ -32,7 +29,9 @@ pub enum Error { InvalidFixedValue { expected: u64, actual: u64 }, #[error("when parsing {obj} needed length of {wanted} but got {got}")] InvalidLengthError { obj: String, wanted: usize, got: usize }, - #[error("array size ({array} bytes) is not a multiple of the element size ({element} bytes)")] + #[error( + "array size ({array} bytes) is not a multiple of the element size ({element} bytes)" + )] InvalidArraySize { array: usize, element: usize }, #[error("Due to size restrictions a struct could not be parsed.")] ImpossibleStructError, @@ -41,12 +40,10 @@ pub enum Error { #[error("expected child {expected}, got {actual}")] InvalidChildError { expected: &'static str, actual: String }, } - pub trait Packet { fn to_bytes(self) -> Bytes; fn to_vec(self) -> Vec; } - #[repr(u64)] #[derive(Debug, Clone, Copy, Hash, Eq, PartialEq)] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] @@ -113,7 +110,6 @@ impl From for u64 { u8::from(value) as Self } } - #[repr(u64)] #[derive(Debug, Clone, Copy, Hash, Eq, PartialEq)] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] @@ -170,7 +166,6 @@ impl From for u64 { u16::from(value) as Self } } - #[derive(Debug, Clone, PartialEq, Eq)] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] pub struct FooData { @@ -211,22 +206,21 @@ impl FooData { }); } let chunk = bytes.get_mut().get_uint_le(3) as u32; - let x = - Enum7::try_from((chunk & 0x7f) as u8).map_err(|_| Error::InvalidEnumValueError { + let x = Enum7::try_from((chunk & 0x7f) as u8) + .map_err(|_| Error::InvalidEnumValueError { obj: "Foo".to_string(), field: "x".to_string(), value: (chunk & 0x7f) as u8 as u64, type_: "Enum7".to_string(), })?; let y = ((chunk >> 7) & 0x1f) as u8; - let z = Enum9::try_from(((chunk >> 12) & 0x1ff) as u16).map_err(|_| { - Error::InvalidEnumValueError { + let z = Enum9::try_from(((chunk >> 12) & 0x1ff) as u16) + .map_err(|_| Error::InvalidEnumValueError { obj: "Foo".to_string(), field: "z".to_string(), value: ((chunk >> 12) & 0x1ff) as u16 as u64, type_: "Enum9".to_string(), - } - })?; + })?; let w = ((chunk >> 21) & 0x7) as u8; Ok(Self { x, y, z, w }) } @@ -237,10 +231,8 @@ impl FooData { if self.w > 0x7 { panic!("Invalid value for {}::{}: {} > {}", "Foo", "w", self.w, 0x7); } - let value = (u8::from(self.x) as u32) - | ((self.y as u32) << 7) - | ((u16::from(self.z) as u32) << 12) - | ((self.w as u32) << 21); + let value = (u8::from(self.x) as u32) | ((self.y as u32) << 7) + | ((u16::from(self.z) as u32) << 12) | ((self.w as u32) << 21); buffer.put_uint_le(value as u64, 3); } fn get_total_size(&self) -> usize { @@ -304,7 +296,12 @@ impl Foo { } impl FooBuilder { pub fn build(self) -> Foo { - let foo = Arc::new(FooData { w: self.w, x: self.x, y: self.y, z: self.z }); + let foo = Arc::new(FooData { + w: self.w, + x: self.x, + y: self.y, + z: self.z, + }); Foo::new(foo).unwrap() } } diff --git a/tools/pdl/tests/generated/packet_decl_payload_field_unknown_size_big_endian.rs b/tools/pdl/tests/generated/packet_decl_payload_field_unknown_size_big_endian.rs index 40f779a75a2..452c3657659 100644 --- a/tools/pdl/tests/generated/packet_decl_payload_field_unknown_size_big_endian.rs +++ b/tools/pdl/tests/generated/packet_decl_payload_field_unknown_size_big_endian.rs @@ -1,18 +1,16 @@ -// @generated rust packets from test - +#![rustfmt::skip] +/// @generated rust packets from test. use bytes::{Buf, BufMut, Bytes, BytesMut}; -use std::cell::Cell; use std::convert::{TryFrom, TryInto}; +use std::cell::Cell; use std::fmt; use std::sync::Arc; use thiserror::Error; - type Result = std::result::Result; - -#[doc = r" Private prevents users from creating arbitrary scalar values"] -#[doc = r" in situations where the value needs to be validated."] -#[doc = r" Users can freely deref the value, but only the backend"] -#[doc = r" may create it."] +/// Private prevents users from creating arbitrary scalar values +/// in situations where the value needs to be validated. +/// Users can freely deref the value, but only the backend +/// may create it. #[derive(Debug, Clone, Copy, Hash, PartialEq, Eq, PartialOrd, Ord)] pub struct Private(T); impl std::ops::Deref for Private { @@ -21,7 +19,6 @@ impl std::ops::Deref for Private { &self.0 } } - #[derive(Debug, Error)] pub enum Error { #[error("Packet parsing failed")] @@ -32,7 +29,9 @@ pub enum Error { InvalidFixedValue { expected: u64, actual: u64 }, #[error("when parsing {obj} needed length of {wanted} but got {got}")] InvalidLengthError { obj: String, wanted: usize, got: usize }, - #[error("array size ({array} bytes) is not a multiple of the element size ({element} bytes)")] + #[error( + "array size ({array} bytes) is not a multiple of the element size ({element} bytes)" + )] InvalidArraySize { array: usize, element: usize }, #[error("Due to size restrictions a struct could not be parsed.")] ImpossibleStructError, @@ -41,12 +40,10 @@ pub enum Error { #[error("expected child {expected}, got {actual}")] InvalidChildError { expected: &'static str, actual: String }, } - pub trait Packet { fn to_bytes(self) -> Bytes; fn to_vec(self) -> Vec; } - #[derive(Debug, Clone, PartialEq, Eq)] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] pub enum FooDataChild { @@ -106,7 +103,9 @@ impl FooData { let payload = bytes.get(); bytes.get_mut().advance(payload.len()); let child = match () { - _ if !payload.is_empty() => FooDataChild::Payload(Bytes::copy_from_slice(payload)), + _ if !payload.is_empty() => { + FooDataChild::Payload(Bytes::copy_from_slice(payload)) + } _ => FooDataChild::None, }; Ok(Self { a, child }) diff --git a/tools/pdl/tests/generated/packet_decl_payload_field_unknown_size_little_endian.rs b/tools/pdl/tests/generated/packet_decl_payload_field_unknown_size_little_endian.rs index 36bcca6553a..99c06b9ccf3 100644 --- a/tools/pdl/tests/generated/packet_decl_payload_field_unknown_size_little_endian.rs +++ b/tools/pdl/tests/generated/packet_decl_payload_field_unknown_size_little_endian.rs @@ -1,18 +1,16 @@ -// @generated rust packets from test - +#![rustfmt::skip] +/// @generated rust packets from test. use bytes::{Buf, BufMut, Bytes, BytesMut}; -use std::cell::Cell; use std::convert::{TryFrom, TryInto}; +use std::cell::Cell; use std::fmt; use std::sync::Arc; use thiserror::Error; - type Result = std::result::Result; - -#[doc = r" Private prevents users from creating arbitrary scalar values"] -#[doc = r" in situations where the value needs to be validated."] -#[doc = r" Users can freely deref the value, but only the backend"] -#[doc = r" may create it."] +/// Private prevents users from creating arbitrary scalar values +/// in situations where the value needs to be validated. +/// Users can freely deref the value, but only the backend +/// may create it. #[derive(Debug, Clone, Copy, Hash, PartialEq, Eq, PartialOrd, Ord)] pub struct Private(T); impl std::ops::Deref for Private { @@ -21,7 +19,6 @@ impl std::ops::Deref for Private { &self.0 } } - #[derive(Debug, Error)] pub enum Error { #[error("Packet parsing failed")] @@ -32,7 +29,9 @@ pub enum Error { InvalidFixedValue { expected: u64, actual: u64 }, #[error("when parsing {obj} needed length of {wanted} but got {got}")] InvalidLengthError { obj: String, wanted: usize, got: usize }, - #[error("array size ({array} bytes) is not a multiple of the element size ({element} bytes)")] + #[error( + "array size ({array} bytes) is not a multiple of the element size ({element} bytes)" + )] InvalidArraySize { array: usize, element: usize }, #[error("Due to size restrictions a struct could not be parsed.")] ImpossibleStructError, @@ -41,12 +40,10 @@ pub enum Error { #[error("expected child {expected}, got {actual}")] InvalidChildError { expected: &'static str, actual: String }, } - pub trait Packet { fn to_bytes(self) -> Bytes; fn to_vec(self) -> Vec; } - #[derive(Debug, Clone, PartialEq, Eq)] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] pub enum FooDataChild { @@ -106,7 +103,9 @@ impl FooData { let payload = bytes.get(); bytes.get_mut().advance(payload.len()); let child = match () { - _ if !payload.is_empty() => FooDataChild::Payload(Bytes::copy_from_slice(payload)), + _ if !payload.is_empty() => { + FooDataChild::Payload(Bytes::copy_from_slice(payload)) + } _ => FooDataChild::None, }; Ok(Self { a, child }) diff --git a/tools/pdl/tests/generated/packet_decl_payload_field_unknown_size_terminal_big_endian.rs b/tools/pdl/tests/generated/packet_decl_payload_field_unknown_size_terminal_big_endian.rs index fcfbb99ba8d..f54477a12c5 100644 --- a/tools/pdl/tests/generated/packet_decl_payload_field_unknown_size_terminal_big_endian.rs +++ b/tools/pdl/tests/generated/packet_decl_payload_field_unknown_size_terminal_big_endian.rs @@ -1,18 +1,16 @@ -// @generated rust packets from test - +#![rustfmt::skip] +/// @generated rust packets from test. use bytes::{Buf, BufMut, Bytes, BytesMut}; -use std::cell::Cell; use std::convert::{TryFrom, TryInto}; +use std::cell::Cell; use std::fmt; use std::sync::Arc; use thiserror::Error; - type Result = std::result::Result; - -#[doc = r" Private prevents users from creating arbitrary scalar values"] -#[doc = r" in situations where the value needs to be validated."] -#[doc = r" Users can freely deref the value, but only the backend"] -#[doc = r" may create it."] +/// Private prevents users from creating arbitrary scalar values +/// in situations where the value needs to be validated. +/// Users can freely deref the value, but only the backend +/// may create it. #[derive(Debug, Clone, Copy, Hash, PartialEq, Eq, PartialOrd, Ord)] pub struct Private(T); impl std::ops::Deref for Private { @@ -21,7 +19,6 @@ impl std::ops::Deref for Private { &self.0 } } - #[derive(Debug, Error)] pub enum Error { #[error("Packet parsing failed")] @@ -32,7 +29,9 @@ pub enum Error { InvalidFixedValue { expected: u64, actual: u64 }, #[error("when parsing {obj} needed length of {wanted} but got {got}")] InvalidLengthError { obj: String, wanted: usize, got: usize }, - #[error("array size ({array} bytes) is not a multiple of the element size ({element} bytes)")] + #[error( + "array size ({array} bytes) is not a multiple of the element size ({element} bytes)" + )] InvalidArraySize { array: usize, element: usize }, #[error("Due to size restrictions a struct could not be parsed.")] ImpossibleStructError, @@ -41,12 +40,10 @@ pub enum Error { #[error("expected child {expected}, got {actual}")] InvalidChildError { expected: &'static str, actual: String }, } - pub trait Packet { fn to_bytes(self) -> Bytes; fn to_vec(self) -> Vec; } - #[derive(Debug, Clone, PartialEq, Eq)] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] pub enum FooDataChild { @@ -113,7 +110,9 @@ impl FooData { } let a = bytes.get_mut().get_uint(3) as u32; let child = match () { - _ if !payload.is_empty() => FooDataChild::Payload(Bytes::copy_from_slice(payload)), + _ if !payload.is_empty() => { + FooDataChild::Payload(Bytes::copy_from_slice(payload)) + } _ => FooDataChild::None, }; Ok(Self { a, child }) diff --git a/tools/pdl/tests/generated/packet_decl_payload_field_unknown_size_terminal_little_endian.rs b/tools/pdl/tests/generated/packet_decl_payload_field_unknown_size_terminal_little_endian.rs index 277eddd0a1b..616c87f212a 100644 --- a/tools/pdl/tests/generated/packet_decl_payload_field_unknown_size_terminal_little_endian.rs +++ b/tools/pdl/tests/generated/packet_decl_payload_field_unknown_size_terminal_little_endian.rs @@ -1,18 +1,16 @@ -// @generated rust packets from test - +#![rustfmt::skip] +/// @generated rust packets from test. use bytes::{Buf, BufMut, Bytes, BytesMut}; -use std::cell::Cell; use std::convert::{TryFrom, TryInto}; +use std::cell::Cell; use std::fmt; use std::sync::Arc; use thiserror::Error; - type Result = std::result::Result; - -#[doc = r" Private prevents users from creating arbitrary scalar values"] -#[doc = r" in situations where the value needs to be validated."] -#[doc = r" Users can freely deref the value, but only the backend"] -#[doc = r" may create it."] +/// Private prevents users from creating arbitrary scalar values +/// in situations where the value needs to be validated. +/// Users can freely deref the value, but only the backend +/// may create it. #[derive(Debug, Clone, Copy, Hash, PartialEq, Eq, PartialOrd, Ord)] pub struct Private(T); impl std::ops::Deref for Private { @@ -21,7 +19,6 @@ impl std::ops::Deref for Private { &self.0 } } - #[derive(Debug, Error)] pub enum Error { #[error("Packet parsing failed")] @@ -32,7 +29,9 @@ pub enum Error { InvalidFixedValue { expected: u64, actual: u64 }, #[error("when parsing {obj} needed length of {wanted} but got {got}")] InvalidLengthError { obj: String, wanted: usize, got: usize }, - #[error("array size ({array} bytes) is not a multiple of the element size ({element} bytes)")] + #[error( + "array size ({array} bytes) is not a multiple of the element size ({element} bytes)" + )] InvalidArraySize { array: usize, element: usize }, #[error("Due to size restrictions a struct could not be parsed.")] ImpossibleStructError, @@ -41,12 +40,10 @@ pub enum Error { #[error("expected child {expected}, got {actual}")] InvalidChildError { expected: &'static str, actual: String }, } - pub trait Packet { fn to_bytes(self) -> Bytes; fn to_vec(self) -> Vec; } - #[derive(Debug, Clone, PartialEq, Eq)] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] pub enum FooDataChild { @@ -113,7 +110,9 @@ impl FooData { } let a = bytes.get_mut().get_uint_le(3) as u32; let child = match () { - _ if !payload.is_empty() => FooDataChild::Payload(Bytes::copy_from_slice(payload)), + _ if !payload.is_empty() => { + FooDataChild::Payload(Bytes::copy_from_slice(payload)) + } _ => FooDataChild::None, }; Ok(Self { a, child }) diff --git a/tools/pdl/tests/generated/packet_decl_payload_field_variable_size_big_endian.rs b/tools/pdl/tests/generated/packet_decl_payload_field_variable_size_big_endian.rs index 3b57129bf79..fd2a3c1891a 100644 --- a/tools/pdl/tests/generated/packet_decl_payload_field_variable_size_big_endian.rs +++ b/tools/pdl/tests/generated/packet_decl_payload_field_variable_size_big_endian.rs @@ -1,18 +1,16 @@ -// @generated rust packets from test - +#![rustfmt::skip] +/// @generated rust packets from test. use bytes::{Buf, BufMut, Bytes, BytesMut}; -use std::cell::Cell; use std::convert::{TryFrom, TryInto}; +use std::cell::Cell; use std::fmt; use std::sync::Arc; use thiserror::Error; - type Result = std::result::Result; - -#[doc = r" Private prevents users from creating arbitrary scalar values"] -#[doc = r" in situations where the value needs to be validated."] -#[doc = r" Users can freely deref the value, but only the backend"] -#[doc = r" may create it."] +/// Private prevents users from creating arbitrary scalar values +/// in situations where the value needs to be validated. +/// Users can freely deref the value, but only the backend +/// may create it. #[derive(Debug, Clone, Copy, Hash, PartialEq, Eq, PartialOrd, Ord)] pub struct Private(T); impl std::ops::Deref for Private { @@ -21,7 +19,6 @@ impl std::ops::Deref for Private { &self.0 } } - #[derive(Debug, Error)] pub enum Error { #[error("Packet parsing failed")] @@ -32,7 +29,9 @@ pub enum Error { InvalidFixedValue { expected: u64, actual: u64 }, #[error("when parsing {obj} needed length of {wanted} but got {got}")] InvalidLengthError { obj: String, wanted: usize, got: usize }, - #[error("array size ({array} bytes) is not a multiple of the element size ({element} bytes)")] + #[error( + "array size ({array} bytes) is not a multiple of the element size ({element} bytes)" + )] InvalidArraySize { array: usize, element: usize }, #[error("Due to size restrictions a struct could not be parsed.")] ImpossibleStructError, @@ -41,12 +40,10 @@ pub enum Error { #[error("expected child {expected}, got {actual}")] InvalidChildError { expected: &'static str, actual: String }, } - pub trait Packet { fn to_bytes(self) -> Bytes; fn to_vec(self) -> Vec; } - #[derive(Debug, Clone, PartialEq, Eq)] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] pub enum FooDataChild { @@ -131,7 +128,9 @@ impl FooData { } let b = bytes.get_mut().get_u16(); let child = match () { - _ if !payload.is_empty() => FooDataChild::Payload(Bytes::copy_from_slice(payload)), + _ if !payload.is_empty() => { + FooDataChild::Payload(Bytes::copy_from_slice(payload)) + } _ => FooDataChild::None, }; Ok(Self { a, b, child }) @@ -140,11 +139,8 @@ impl FooData { buffer.put_u8(self.a); if self.child.get_total_size() > 0xff { panic!( - "Invalid length for {}::{}: {} > {}", - "Foo", - "_payload_", - self.child.get_total_size(), - 0xff + "Invalid length for {}::{}: {} > {}", "Foo", "_payload_", self.child + .get_total_size(), 0xff ); } buffer.put_u8(self.child.get_total_size() as u8); diff --git a/tools/pdl/tests/generated/packet_decl_payload_field_variable_size_little_endian.rs b/tools/pdl/tests/generated/packet_decl_payload_field_variable_size_little_endian.rs index d7ae81fec5a..65f18097ee5 100644 --- a/tools/pdl/tests/generated/packet_decl_payload_field_variable_size_little_endian.rs +++ b/tools/pdl/tests/generated/packet_decl_payload_field_variable_size_little_endian.rs @@ -1,18 +1,16 @@ -// @generated rust packets from test - +#![rustfmt::skip] +/// @generated rust packets from test. use bytes::{Buf, BufMut, Bytes, BytesMut}; -use std::cell::Cell; use std::convert::{TryFrom, TryInto}; +use std::cell::Cell; use std::fmt; use std::sync::Arc; use thiserror::Error; - type Result = std::result::Result; - -#[doc = r" Private prevents users from creating arbitrary scalar values"] -#[doc = r" in situations where the value needs to be validated."] -#[doc = r" Users can freely deref the value, but only the backend"] -#[doc = r" may create it."] +/// Private prevents users from creating arbitrary scalar values +/// in situations where the value needs to be validated. +/// Users can freely deref the value, but only the backend +/// may create it. #[derive(Debug, Clone, Copy, Hash, PartialEq, Eq, PartialOrd, Ord)] pub struct Private(T); impl std::ops::Deref for Private { @@ -21,7 +19,6 @@ impl std::ops::Deref for Private { &self.0 } } - #[derive(Debug, Error)] pub enum Error { #[error("Packet parsing failed")] @@ -32,7 +29,9 @@ pub enum Error { InvalidFixedValue { expected: u64, actual: u64 }, #[error("when parsing {obj} needed length of {wanted} but got {got}")] InvalidLengthError { obj: String, wanted: usize, got: usize }, - #[error("array size ({array} bytes) is not a multiple of the element size ({element} bytes)")] + #[error( + "array size ({array} bytes) is not a multiple of the element size ({element} bytes)" + )] InvalidArraySize { array: usize, element: usize }, #[error("Due to size restrictions a struct could not be parsed.")] ImpossibleStructError, @@ -41,12 +40,10 @@ pub enum Error { #[error("expected child {expected}, got {actual}")] InvalidChildError { expected: &'static str, actual: String }, } - pub trait Packet { fn to_bytes(self) -> Bytes; fn to_vec(self) -> Vec; } - #[derive(Debug, Clone, PartialEq, Eq)] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] pub enum FooDataChild { @@ -131,7 +128,9 @@ impl FooData { } let b = bytes.get_mut().get_u16_le(); let child = match () { - _ if !payload.is_empty() => FooDataChild::Payload(Bytes::copy_from_slice(payload)), + _ if !payload.is_empty() => { + FooDataChild::Payload(Bytes::copy_from_slice(payload)) + } _ => FooDataChild::None, }; Ok(Self { a, b, child }) @@ -140,11 +139,8 @@ impl FooData { buffer.put_u8(self.a); if self.child.get_total_size() > 0xff { panic!( - "Invalid length for {}::{}: {} > {}", - "Foo", - "_payload_", - self.child.get_total_size(), - 0xff + "Invalid length for {}::{}: {} > {}", "Foo", "_payload_", self.child + .get_total_size(), 0xff ); } buffer.put_u8(self.child.get_total_size() as u8); diff --git a/tools/pdl/tests/generated/packet_decl_reserved_field_big_endian.rs b/tools/pdl/tests/generated/packet_decl_reserved_field_big_endian.rs index 6cfe597634c..f03c7bfcd12 100644 --- a/tools/pdl/tests/generated/packet_decl_reserved_field_big_endian.rs +++ b/tools/pdl/tests/generated/packet_decl_reserved_field_big_endian.rs @@ -1,18 +1,16 @@ -// @generated rust packets from test - +#![rustfmt::skip] +/// @generated rust packets from test. use bytes::{Buf, BufMut, Bytes, BytesMut}; -use std::cell::Cell; use std::convert::{TryFrom, TryInto}; +use std::cell::Cell; use std::fmt; use std::sync::Arc; use thiserror::Error; - type Result = std::result::Result; - -#[doc = r" Private prevents users from creating arbitrary scalar values"] -#[doc = r" in situations where the value needs to be validated."] -#[doc = r" Users can freely deref the value, but only the backend"] -#[doc = r" may create it."] +/// Private prevents users from creating arbitrary scalar values +/// in situations where the value needs to be validated. +/// Users can freely deref the value, but only the backend +/// may create it. #[derive(Debug, Clone, Copy, Hash, PartialEq, Eq, PartialOrd, Ord)] pub struct Private(T); impl std::ops::Deref for Private { @@ -21,7 +19,6 @@ impl std::ops::Deref for Private { &self.0 } } - #[derive(Debug, Error)] pub enum Error { #[error("Packet parsing failed")] @@ -32,7 +29,9 @@ pub enum Error { InvalidFixedValue { expected: u64, actual: u64 }, #[error("when parsing {obj} needed length of {wanted} but got {got}")] InvalidLengthError { obj: String, wanted: usize, got: usize }, - #[error("array size ({array} bytes) is not a multiple of the element size ({element} bytes)")] + #[error( + "array size ({array} bytes) is not a multiple of the element size ({element} bytes)" + )] InvalidArraySize { array: usize, element: usize }, #[error("Due to size restrictions a struct could not be parsed.")] ImpossibleStructError, @@ -41,12 +40,10 @@ pub enum Error { #[error("expected child {expected}, got {actual}")] InvalidChildError { expected: &'static str, actual: String }, } - pub trait Packet { fn to_bytes(self) -> Bytes; fn to_vec(self) -> Vec; } - #[derive(Debug, Clone, PartialEq, Eq)] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] pub struct FooData {} diff --git a/tools/pdl/tests/generated/packet_decl_reserved_field_little_endian.rs b/tools/pdl/tests/generated/packet_decl_reserved_field_little_endian.rs index 6cfe597634c..f03c7bfcd12 100644 --- a/tools/pdl/tests/generated/packet_decl_reserved_field_little_endian.rs +++ b/tools/pdl/tests/generated/packet_decl_reserved_field_little_endian.rs @@ -1,18 +1,16 @@ -// @generated rust packets from test - +#![rustfmt::skip] +/// @generated rust packets from test. use bytes::{Buf, BufMut, Bytes, BytesMut}; -use std::cell::Cell; use std::convert::{TryFrom, TryInto}; +use std::cell::Cell; use std::fmt; use std::sync::Arc; use thiserror::Error; - type Result = std::result::Result; - -#[doc = r" Private prevents users from creating arbitrary scalar values"] -#[doc = r" in situations where the value needs to be validated."] -#[doc = r" Users can freely deref the value, but only the backend"] -#[doc = r" may create it."] +/// Private prevents users from creating arbitrary scalar values +/// in situations where the value needs to be validated. +/// Users can freely deref the value, but only the backend +/// may create it. #[derive(Debug, Clone, Copy, Hash, PartialEq, Eq, PartialOrd, Ord)] pub struct Private(T); impl std::ops::Deref for Private { @@ -21,7 +19,6 @@ impl std::ops::Deref for Private { &self.0 } } - #[derive(Debug, Error)] pub enum Error { #[error("Packet parsing failed")] @@ -32,7 +29,9 @@ pub enum Error { InvalidFixedValue { expected: u64, actual: u64 }, #[error("when parsing {obj} needed length of {wanted} but got {got}")] InvalidLengthError { obj: String, wanted: usize, got: usize }, - #[error("array size ({array} bytes) is not a multiple of the element size ({element} bytes)")] + #[error( + "array size ({array} bytes) is not a multiple of the element size ({element} bytes)" + )] InvalidArraySize { array: usize, element: usize }, #[error("Due to size restrictions a struct could not be parsed.")] ImpossibleStructError, @@ -41,12 +40,10 @@ pub enum Error { #[error("expected child {expected}, got {actual}")] InvalidChildError { expected: &'static str, actual: String }, } - pub trait Packet { fn to_bytes(self) -> Bytes; fn to_vec(self) -> Vec; } - #[derive(Debug, Clone, PartialEq, Eq)] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] pub struct FooData {} diff --git a/tools/pdl/tests/generated/packet_decl_simple_scalars_big_endian.rs b/tools/pdl/tests/generated/packet_decl_simple_scalars_big_endian.rs index 244ed08e671..303a7855e9a 100644 --- a/tools/pdl/tests/generated/packet_decl_simple_scalars_big_endian.rs +++ b/tools/pdl/tests/generated/packet_decl_simple_scalars_big_endian.rs @@ -1,18 +1,16 @@ -// @generated rust packets from test - +#![rustfmt::skip] +/// @generated rust packets from test. use bytes::{Buf, BufMut, Bytes, BytesMut}; -use std::cell::Cell; use std::convert::{TryFrom, TryInto}; +use std::cell::Cell; use std::fmt; use std::sync::Arc; use thiserror::Error; - type Result = std::result::Result; - -#[doc = r" Private prevents users from creating arbitrary scalar values"] -#[doc = r" in situations where the value needs to be validated."] -#[doc = r" Users can freely deref the value, but only the backend"] -#[doc = r" may create it."] +/// Private prevents users from creating arbitrary scalar values +/// in situations where the value needs to be validated. +/// Users can freely deref the value, but only the backend +/// may create it. #[derive(Debug, Clone, Copy, Hash, PartialEq, Eq, PartialOrd, Ord)] pub struct Private(T); impl std::ops::Deref for Private { @@ -21,7 +19,6 @@ impl std::ops::Deref for Private { &self.0 } } - #[derive(Debug, Error)] pub enum Error { #[error("Packet parsing failed")] @@ -32,7 +29,9 @@ pub enum Error { InvalidFixedValue { expected: u64, actual: u64 }, #[error("when parsing {obj} needed length of {wanted} but got {got}")] InvalidLengthError { obj: String, wanted: usize, got: usize }, - #[error("array size ({array} bytes) is not a multiple of the element size ({element} bytes)")] + #[error( + "array size ({array} bytes) is not a multiple of the element size ({element} bytes)" + )] InvalidArraySize { array: usize, element: usize }, #[error("Due to size restrictions a struct could not be parsed.")] ImpossibleStructError, @@ -41,12 +40,10 @@ pub enum Error { #[error("expected child {expected}, got {actual}")] InvalidChildError { expected: &'static str, actual: String }, } - pub trait Packet { fn to_bytes(self) -> Bytes; fn to_vec(self) -> Vec; } - #[derive(Debug, Clone, PartialEq, Eq)] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] pub struct FooData { @@ -169,7 +166,11 @@ impl Foo { } impl FooBuilder { pub fn build(self) -> Foo { - let foo = Arc::new(FooData { x: self.x, y: self.y, z: self.z }); + let foo = Arc::new(FooData { + x: self.x, + y: self.y, + z: self.z, + }); Foo::new(foo).unwrap() } } diff --git a/tools/pdl/tests/generated/packet_decl_simple_scalars_little_endian.rs b/tools/pdl/tests/generated/packet_decl_simple_scalars_little_endian.rs index 775d7a09129..043a72f1133 100644 --- a/tools/pdl/tests/generated/packet_decl_simple_scalars_little_endian.rs +++ b/tools/pdl/tests/generated/packet_decl_simple_scalars_little_endian.rs @@ -1,18 +1,16 @@ -// @generated rust packets from test - +#![rustfmt::skip] +/// @generated rust packets from test. use bytes::{Buf, BufMut, Bytes, BytesMut}; -use std::cell::Cell; use std::convert::{TryFrom, TryInto}; +use std::cell::Cell; use std::fmt; use std::sync::Arc; use thiserror::Error; - type Result = std::result::Result; - -#[doc = r" Private prevents users from creating arbitrary scalar values"] -#[doc = r" in situations where the value needs to be validated."] -#[doc = r" Users can freely deref the value, but only the backend"] -#[doc = r" may create it."] +/// Private prevents users from creating arbitrary scalar values +/// in situations where the value needs to be validated. +/// Users can freely deref the value, but only the backend +/// may create it. #[derive(Debug, Clone, Copy, Hash, PartialEq, Eq, PartialOrd, Ord)] pub struct Private(T); impl std::ops::Deref for Private { @@ -21,7 +19,6 @@ impl std::ops::Deref for Private { &self.0 } } - #[derive(Debug, Error)] pub enum Error { #[error("Packet parsing failed")] @@ -32,7 +29,9 @@ pub enum Error { InvalidFixedValue { expected: u64, actual: u64 }, #[error("when parsing {obj} needed length of {wanted} but got {got}")] InvalidLengthError { obj: String, wanted: usize, got: usize }, - #[error("array size ({array} bytes) is not a multiple of the element size ({element} bytes)")] + #[error( + "array size ({array} bytes) is not a multiple of the element size ({element} bytes)" + )] InvalidArraySize { array: usize, element: usize }, #[error("Due to size restrictions a struct could not be parsed.")] ImpossibleStructError, @@ -41,12 +40,10 @@ pub enum Error { #[error("expected child {expected}, got {actual}")] InvalidChildError { expected: &'static str, actual: String }, } - pub trait Packet { fn to_bytes(self) -> Bytes; fn to_vec(self) -> Vec; } - #[derive(Debug, Clone, PartialEq, Eq)] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] pub struct FooData { @@ -169,7 +166,11 @@ impl Foo { } impl FooBuilder { pub fn build(self) -> Foo { - let foo = Arc::new(FooData { x: self.x, y: self.y, z: self.z }); + let foo = Arc::new(FooData { + x: self.x, + y: self.y, + z: self.z, + }); Foo::new(foo).unwrap() } } diff --git a/tools/pdl/tests/generated/preamble.rs b/tools/pdl/tests/generated/preamble.rs index c7d0fad1b92..e200e6d7b1e 100644 --- a/tools/pdl/tests/generated/preamble.rs +++ b/tools/pdl/tests/generated/preamble.rs @@ -1,18 +1,16 @@ -// @generated rust packets from foo.pdl - +#![rustfmt::skip] +/// @generated rust packets from foo.pdl. use bytes::{Buf, BufMut, Bytes, BytesMut}; -use std::cell::Cell; use std::convert::{TryFrom, TryInto}; +use std::cell::Cell; use std::fmt; use std::sync::Arc; use thiserror::Error; - type Result = std::result::Result; - -#[doc = r" Private prevents users from creating arbitrary scalar values"] -#[doc = r" in situations where the value needs to be validated."] -#[doc = r" Users can freely deref the value, but only the backend"] -#[doc = r" may create it."] +/// Private prevents users from creating arbitrary scalar values +/// in situations where the value needs to be validated. +/// Users can freely deref the value, but only the backend +/// may create it. #[derive(Debug, Clone, Copy, Hash, PartialEq, Eq, PartialOrd, Ord)] pub struct Private(T); impl std::ops::Deref for Private { @@ -21,7 +19,6 @@ impl std::ops::Deref for Private { &self.0 } } - #[derive(Debug, Error)] pub enum Error { #[error("Packet parsing failed")] @@ -32,7 +29,9 @@ pub enum Error { InvalidFixedValue { expected: u64, actual: u64 }, #[error("when parsing {obj} needed length of {wanted} but got {got}")] InvalidLengthError { obj: String, wanted: usize, got: usize }, - #[error("array size ({array} bytes) is not a multiple of the element size ({element} bytes)")] + #[error( + "array size ({array} bytes) is not a multiple of the element size ({element} bytes)" + )] InvalidArraySize { array: usize, element: usize }, #[error("Due to size restrictions a struct could not be parsed.")] ImpossibleStructError, @@ -41,7 +40,6 @@ pub enum Error { #[error("expected child {expected}, got {actual}")] InvalidChildError { expected: &'static str, actual: String }, } - pub trait Packet { fn to_bytes(self) -> Bytes; fn to_vec(self) -> Vec; diff --git a/tools/pdl/tests/generated/struct_decl_complex_scalars_big_endian.rs b/tools/pdl/tests/generated/struct_decl_complex_scalars_big_endian.rs index 35cbe95eb3b..8ea2bb92ba7 100644 --- a/tools/pdl/tests/generated/struct_decl_complex_scalars_big_endian.rs +++ b/tools/pdl/tests/generated/struct_decl_complex_scalars_big_endian.rs @@ -1,18 +1,16 @@ -// @generated rust packets from test - +#![rustfmt::skip] +/// @generated rust packets from test. use bytes::{Buf, BufMut, Bytes, BytesMut}; -use std::cell::Cell; use std::convert::{TryFrom, TryInto}; +use std::cell::Cell; use std::fmt; use std::sync::Arc; use thiserror::Error; - type Result = std::result::Result; - -#[doc = r" Private prevents users from creating arbitrary scalar values"] -#[doc = r" in situations where the value needs to be validated."] -#[doc = r" Users can freely deref the value, but only the backend"] -#[doc = r" may create it."] +/// Private prevents users from creating arbitrary scalar values +/// in situations where the value needs to be validated. +/// Users can freely deref the value, but only the backend +/// may create it. #[derive(Debug, Clone, Copy, Hash, PartialEq, Eq, PartialOrd, Ord)] pub struct Private(T); impl std::ops::Deref for Private { @@ -21,7 +19,6 @@ impl std::ops::Deref for Private { &self.0 } } - #[derive(Debug, Error)] pub enum Error { #[error("Packet parsing failed")] @@ -32,7 +29,9 @@ pub enum Error { InvalidFixedValue { expected: u64, actual: u64 }, #[error("when parsing {obj} needed length of {wanted} but got {got}")] InvalidLengthError { obj: String, wanted: usize, got: usize }, - #[error("array size ({array} bytes) is not a multiple of the element size ({element} bytes)")] + #[error( + "array size ({array} bytes) is not a multiple of the element size ({element} bytes)" + )] InvalidArraySize { array: usize, element: usize }, #[error("Due to size restrictions a struct could not be parsed.")] ImpossibleStructError, @@ -41,12 +40,10 @@ pub enum Error { #[error("expected child {expected}, got {actual}")] InvalidChildError { expected: &'static str, actual: String }, } - pub trait Packet { fn to_bytes(self) -> Bytes; fn to_vec(self) -> Vec; } - #[derive(Debug, Clone, PartialEq, Eq)] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] pub struct Foo { diff --git a/tools/pdl/tests/generated/struct_decl_complex_scalars_little_endian.rs b/tools/pdl/tests/generated/struct_decl_complex_scalars_little_endian.rs index d227b3846fd..0ec2c384b4e 100644 --- a/tools/pdl/tests/generated/struct_decl_complex_scalars_little_endian.rs +++ b/tools/pdl/tests/generated/struct_decl_complex_scalars_little_endian.rs @@ -1,18 +1,16 @@ -// @generated rust packets from test - +#![rustfmt::skip] +/// @generated rust packets from test. use bytes::{Buf, BufMut, Bytes, BytesMut}; -use std::cell::Cell; use std::convert::{TryFrom, TryInto}; +use std::cell::Cell; use std::fmt; use std::sync::Arc; use thiserror::Error; - type Result = std::result::Result; - -#[doc = r" Private prevents users from creating arbitrary scalar values"] -#[doc = r" in situations where the value needs to be validated."] -#[doc = r" Users can freely deref the value, but only the backend"] -#[doc = r" may create it."] +/// Private prevents users from creating arbitrary scalar values +/// in situations where the value needs to be validated. +/// Users can freely deref the value, but only the backend +/// may create it. #[derive(Debug, Clone, Copy, Hash, PartialEq, Eq, PartialOrd, Ord)] pub struct Private(T); impl std::ops::Deref for Private { @@ -21,7 +19,6 @@ impl std::ops::Deref for Private { &self.0 } } - #[derive(Debug, Error)] pub enum Error { #[error("Packet parsing failed")] @@ -32,7 +29,9 @@ pub enum Error { InvalidFixedValue { expected: u64, actual: u64 }, #[error("when parsing {obj} needed length of {wanted} but got {got}")] InvalidLengthError { obj: String, wanted: usize, got: usize }, - #[error("array size ({array} bytes) is not a multiple of the element size ({element} bytes)")] + #[error( + "array size ({array} bytes) is not a multiple of the element size ({element} bytes)" + )] InvalidArraySize { array: usize, element: usize }, #[error("Due to size restrictions a struct could not be parsed.")] ImpossibleStructError, @@ -41,12 +40,10 @@ pub enum Error { #[error("expected child {expected}, got {actual}")] InvalidChildError { expected: &'static str, actual: String }, } - pub trait Packet { fn to_bytes(self) -> Bytes; fn to_vec(self) -> Vec; } - #[derive(Debug, Clone, PartialEq, Eq)] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] pub struct Foo { diff --git a/tools/pdl/tests/generated_files_compile.sh b/tools/pdl/tests/generated_files_compile.sh index 583abac8337..89d12ba2148 100755 --- a/tools/pdl/tests/generated_files_compile.sh +++ b/tools/pdl/tests/generated_files_compile.sh @@ -25,7 +25,9 @@ for input_path in "$@"; do echo "mod $(basename -s .rs "$input_path") {" - cat "$input_path" + # The inner (module) attribute needs to be removed to produce a + # valid file. + grep -v '#!\[rustfmt::skip\]' "$input_path" echo "}" done -- GitLab From 1d25858cdc7884cb5bd89d6aa1d82a9baad41db3 Mon Sep 17 00:00:00 2001 From: Martin Geisler Date: Fri, 12 May 2023 16:21:01 +0200 Subject: [PATCH 0068/2405] pdl: Generate canonical tests with prettyplease This removes another dependency on rustfmt. Tag: #refactor Bug: 274187738 Test: atest pdl_tests pdl_rust_generator_tests_{le,be} pdl_generated_files_compile Change-Id: I7eb435fcb7583794f12ab23f4ba48d595ac02524 --- tools/pdl/Android.bp | 21 +++++-------------- tools/pdl/src/bin/generate-canonical-tests.rs | 21 +++++++++---------- 2 files changed, 15 insertions(+), 27 deletions(-) diff --git a/tools/pdl/Android.bp b/tools/pdl/Android.bp index df4fd25fbaf..65a23bcca4e 100644 --- a/tools/pdl/Android.bp +++ b/tools/pdl/Android.bp @@ -245,6 +245,7 @@ rust_binary_host { name: "pdl_generate_tests", srcs: ["src/bin/generate-canonical-tests.rs"], rustlibs: [ + "libprettyplease", "libproc_macro2", "libquote", "libserde", @@ -254,32 +255,20 @@ rust_binary_host { ], } -genrule_defaults { - name: "pdl_rust_generator_src_defaults", - tools: [ - ":pdl_generate_tests", - ":rustfmt", - ], -} - genrule { name: "pdl_rust_generator_tests_le_src", - cmd: "set -o pipefail;" + - " $(location :pdl_generate_tests) $(in) pdl_le_backend |" + - " $(location :rustfmt) > $(out)", + cmd: "$(location :pdl_generate_tests) $(in) pdl_le_backend > $(out)", srcs: ["tests/canonical/le_test_vectors.json"], out: ["le_canonical.rs"], - defaults: ["pdl_rust_generator_src_defaults"], + tools: [":pdl_generate_tests"], } genrule { name: "pdl_rust_generator_tests_be_src", - cmd: "set -o pipefail;" + - " $(location :pdl_generate_tests) $(in) pdl_be_backend |" + - " $(location :rustfmt) > $(out)", + cmd: "$(location :pdl_generate_tests) $(in) pdl_be_backend > $(out)", srcs: ["tests/canonical/be_test_vectors.json"], out: ["be_canonical.rs"], - defaults: ["pdl_rust_generator_src_defaults"], + tools: [":pdl_generate_tests"], } rust_test_host { diff --git a/tools/pdl/src/bin/generate-canonical-tests.rs b/tools/pdl/src/bin/generate-canonical-tests.rs index 06246392497..44ad2b1543b 100644 --- a/tools/pdl/src/bin/generate-canonical-tests.rs +++ b/tools/pdl/src/bin/generate-canonical-tests.rs @@ -128,17 +128,16 @@ fn generate_unit_tests(input: &str, packet_names: &[&str], module_name: &str) { } // TODO(mgeisler): make the generated code clean from warnings. - println!("#![allow(warnings, missing_docs)]"); - println!(); - println!( - "{}", - "e! { - use #module::Packet; - use serde_json::json; - - #(#tests)* - } - ); + let code = quote! { + #![allow(warnings, missing_docs)] + + use #module::Packet; + use serde_json::json; + + #(#tests)* + }; + let syntax_tree = syn::parse2::(code).expect("Could not parse {code:#?}"); + println!("{}", prettyplease::unparse(&syntax_tree)); } fn main() { -- GitLab From 441c3b16223b2f2380bf3c6e56897501f2f2e7b0 Mon Sep 17 00:00:00 2001 From: Martin Geisler Date: Fri, 12 May 2023 17:41:02 +0200 Subject: [PATCH 0069/2405] pdl: Format generated code using prettyplease This removes the need for using rustfmt when invoking pdl. Tag: #refactor Bug: 274187738 Test: atest pdl_tests pdl_rust_generator_tests_{le,be} pdl_generated_files_compile Change-Id: Ia49e6b2aec53b9c23d62532b7fcdfbc59ca723ca --- tools/pdl/Android.bp | 9 ++------ tools/pdl/src/backends/rust.rs | 30 +++++++++++-------------- tools/pdl/src/backends/rust/preamble.rs | 18 +++++---------- 3 files changed, 20 insertions(+), 37 deletions(-) diff --git a/tools/pdl/Android.bp b/tools/pdl/Android.bp index 65a23bcca4e..9f668b42735 100644 --- a/tools/pdl/Android.bp +++ b/tools/pdl/Android.bp @@ -146,13 +146,8 @@ rust_test_host { genrule_defaults { name: "pdl_rust_generator_defaults", - cmd: "set -o pipefail;" + - " $(location :pdl) --output-format rust $(in) |" + - " $(location :rustfmt) > $(out)", - tools: [ - ":pdl", - ":rustfmt", - ], + cmd: "$(location :pdl) --output-format rust $(in) > $(out)", + tools: [":pdl"], defaults_visibility: [ "//external/uwb/src", "//packages/modules/Bluetooth:__subpackages__", diff --git a/tools/pdl/src/backends/rust.rs b/tools/pdl/src/backends/rust.rs index c9101521cb0..b480ca665a2 100644 --- a/tools/pdl/src/backends/rust.rs +++ b/tools/pdl/src/backends/rust.rs @@ -964,24 +964,20 @@ fn generate_decl( scope: &lint::Scope<'_>, file: &analyzer_ast::File, decl: &analyzer_ast::Decl, -) -> String { +) -> proc_macro2::TokenStream { match &decl.desc { - ast::DeclDesc::Packet { id, .. } => { - generate_packet_decl(scope, file.endianness.value, id).to_string() - } + ast::DeclDesc::Packet { id, .. } => generate_packet_decl(scope, file.endianness.value, id), ast::DeclDesc::Struct { id, parent_id: None, .. } => { // TODO(mgeisler): handle structs with parents. We could // generate code for them, but the code is not useful // since it would require the caller to unpack everything // manually. We either need to change the API, or // implement the recursive (de)serialization. - generate_struct_decl(scope, file.endianness.value, id).to_string() - } - ast::DeclDesc::Enum { id, tags, width } => { - generate_enum_decl(id, tags, *width, false).to_string() + generate_struct_decl(scope, file.endianness.value, id) } + ast::DeclDesc::Enum { id, tags, width } => generate_enum_decl(id, tags, *width, false), ast::DeclDesc::CustomField { id, width: Some(width), .. } => { - generate_custom_field_decl(id, *width).to_string() + generate_custom_field_decl(id, *width) } _ => todo!("unsupported Decl::{:?}", decl), } @@ -992,18 +988,18 @@ fn generate_decl( /// The code is not formatted, pipe it through `rustfmt` to get /// readable source code. pub fn generate(sources: &ast::SourceDatabase, file: &analyzer_ast::File) -> String { - let mut code = String::new(); - let source = sources.get(file.file).expect("could not read source"); - code.push_str(&preamble::generate(Path::new(source.name()))); + let preamble = preamble::generate(Path::new(source.name())); let scope = lint::Scope::new(file); - for decl in &file.declarations { - code.push_str(&generate_decl(&scope, file, decl)); - code.push_str("\n\n"); - } + let decls = file.declarations.iter().map(|decl| generate_decl(&scope, file, decl)); + let code = quote! { + #preamble - code + #(#decls)* + }; + let syntax_tree = syn::parse2(code).expect("Could not parse code"); + prettyplease::unparse(&syntax_tree) } #[cfg(test)] diff --git a/tools/pdl/src/backends/rust/preamble.rs b/tools/pdl/src/backends/rust/preamble.rs index afd84da84a6..45978f13ff9 100644 --- a/tools/pdl/src/backends/rust/preamble.rs +++ b/tools/pdl/src/backends/rust/preamble.rs @@ -12,13 +12,11 @@ // See the License for the specific language governing permissions and // limitations under the License. +use quote::quote; use std::path::Path; -use crate::quote_block; - /// Generate the file preamble. -pub fn generate(path: &Path) -> String { - let mut code = String::new(); +pub fn generate(path: &Path) -> proc_macro2::TokenStream { // TODO(mgeisler): Make the generated code free from warnings. // // The code either needs @@ -50,7 +48,7 @@ pub fn generate(path: &Path) -> String { // mod foo { include_str!("generated.rs") } // use foo::*; // fn after() {} - code.push_str("e_block! { + quote! { #[doc = #module_doc_string] use bytes::{Buf, BufMut, Bytes, BytesMut}; @@ -75,9 +73,7 @@ pub fn generate(path: &Path) -> String { &self.0 } } - }); - code.push_str("e_block! { #[derive(Debug, Error)] pub enum Error { #[error("Packet parsing failed")] @@ -97,16 +93,12 @@ pub fn generate(path: &Path) -> String { #[error("expected child {expected}, got {actual}")] InvalidChildError { expected: &'static str, actual: String }, } - }); - code.push_str("e_block! { pub trait Packet { fn to_bytes(self) -> Bytes; fn to_vec(self) -> Vec; } - }); - - code + } } #[cfg(test)] @@ -116,7 +108,7 @@ mod tests { #[test] fn test_generate_preamble() { - let actual_code = generate(Path::new("some/path/foo.pdl")); + let actual_code = generate(Path::new("some/path/foo.pdl")).to_string(); assert_snapshot_eq("tests/generated/preamble.rs", &format_rust(&actual_code)); } } -- GitLab From 418cd123440eb41cecd560f88a80494a0bddaacc Mon Sep 17 00:00:00 2001 From: Martin Geisler Date: Fri, 12 May 2023 17:50:20 +0200 Subject: [PATCH 0070/2405] pdl: Remove rustfmt from no_alloc test The no_alloc backend used rustfmt for an intermediate file generated as part of a unit test. We plan to remove this backend, so the formatting of this file is not critical. Tag: #refactor Bug: 274187738 Test: atest pdl_rust_noalloc_le_test Change-Id: I3c7739a7c7ceeb447aa1b82890ec62d5c0e87276 --- tools/pdl/Android.bp | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/tools/pdl/Android.bp b/tools/pdl/Android.bp index 9f668b42735..d81908a4f0b 100644 --- a/tools/pdl/Android.bp +++ b/tools/pdl/Android.bp @@ -381,13 +381,8 @@ python_test_host { // Defaults for the rust_noalloc backend genrule_defaults { name: "pdl_rust_noalloc_generator_defaults", - cmd: "set -o pipefail;" + - " $(location :pdl) --output-format rust_no_alloc $(in) |" + - " $(location :rustfmt) > $(out)", - tools: [ - ":pdl", - ":rustfmt", - ], + cmd: "$(location :pdl) --output-format rust_no_alloc $(in) > $(out)", + tools: [":pdl"], } // Generate the rust_noalloc backend srcs against the little-endian test vectors -- GitLab From 7a639a84b58e349628916fd44db6da2ead3aeb89 Mon Sep 17 00:00:00 2001 From: Chris Manton Date: Sun, 14 May 2023 18:32:09 -0700 Subject: [PATCH 0071/2405] Break out stack::include::smp_status.h Bug: 282731464 Test: net_test_stack_smp Change-Id: I15f52663b0a63399bbb37fdd278cd97a8d84bdbf --- system/stack/include/smp_api_types.h | 72 +-------------------- system/stack/include/smp_status.h | 96 ++++++++++++++++++++++++++++ system/stack/test/stack_smp_test.cc | 48 ++++++++++++-- 3 files changed, 141 insertions(+), 75 deletions(-) create mode 100644 system/stack/include/smp_status.h diff --git a/system/stack/include/smp_api_types.h b/system/stack/include/smp_api_types.h index 47e4078fadb..12b64f35c99 100644 --- a/system/stack/include/smp_api_types.h +++ b/system/stack/include/smp_api_types.h @@ -26,6 +26,7 @@ #include "bt_target.h" // Must be first to define build configuration #include "stack/include/bt_octets.h" #include "stack/include/btm_status.h" +#include "stack/include/smp_status.h" #include "types/ble_address_with_type.h" #include "types/raw_address.h" @@ -102,77 +103,6 @@ typedef enum : uint8_t { SMP_LE_ADDR_ASSOC_EVT = 15, /* Identity address association event */ } tSMP_EVT; -/* pairing failure reason code */ -typedef enum : uint8_t { - SMP_SUCCESS = 0, - SMP_PASSKEY_ENTRY_FAIL = 0x01, - SMP_OOB_FAIL = 0x02, - SMP_PAIR_AUTH_FAIL = 0x03, - SMP_CONFIRM_VALUE_ERR = 0x04, - SMP_PAIR_NOT_SUPPORT = 0x05, - SMP_ENC_KEY_SIZE = 0x06, - SMP_INVALID_CMD = 0x07, - SMP_PAIR_FAIL_UNKNOWN = 0x08, - SMP_REPEATED_ATTEMPTS = 0x09, - SMP_INVALID_PARAMETERS = 0x0A, - SMP_DHKEY_CHK_FAIL = 0x0B, - SMP_NUMERIC_COMPAR_FAIL = 0x0C, - SMP_BR_PARING_IN_PROGR = 0x0D, - SMP_XTRANS_DERIVE_NOT_ALLOW = 0x0E, - SMP_MAX_FAIL_RSN_PER_SPEC = SMP_XTRANS_DERIVE_NOT_ALLOW, - - /* self defined error code */ - SMP_PAIR_INTERNAL_ERR = (SMP_MAX_FAIL_RSN_PER_SPEC + 0x01), /* 0x0F */ - - /* Unknown IO capability, unable to decide association model */ - SMP_UNKNOWN_IO_CAP = (SMP_MAX_FAIL_RSN_PER_SPEC + 0x02), /* 0x10 */ - - SMP_BUSY = (SMP_MAX_FAIL_RSN_PER_SPEC + 0x05), /* 0x13 */ - SMP_ENC_FAIL = (SMP_MAX_FAIL_RSN_PER_SPEC + 0x06), /* 0x14 */ - SMP_STARTED = (SMP_MAX_FAIL_RSN_PER_SPEC + 0x07), /* 0x15 */ - SMP_RSP_TIMEOUT = (SMP_MAX_FAIL_RSN_PER_SPEC + 0x08), /* 0x16 */ - - /* Unspecified failure reason */ - SMP_FAIL = (SMP_MAX_FAIL_RSN_PER_SPEC + 0x0A), /* 0x18 */ - - SMP_CONN_TOUT = (SMP_MAX_FAIL_RSN_PER_SPEC + 0x0B), /* 0x19 */ -} tSMP_STATUS; - -#define CASE_RETURN_TEXT(code) \ - case code: \ - return #code - -inline std::string smp_status_text(const tSMP_STATUS& status) { - switch (status) { - CASE_RETURN_TEXT(SMP_SUCCESS); - CASE_RETURN_TEXT(SMP_PASSKEY_ENTRY_FAIL); - CASE_RETURN_TEXT(SMP_OOB_FAIL); - CASE_RETURN_TEXT(SMP_PAIR_AUTH_FAIL); - CASE_RETURN_TEXT(SMP_CONFIRM_VALUE_ERR); - CASE_RETURN_TEXT(SMP_PAIR_NOT_SUPPORT); - CASE_RETURN_TEXT(SMP_ENC_KEY_SIZE); - CASE_RETURN_TEXT(SMP_INVALID_CMD); - CASE_RETURN_TEXT(SMP_PAIR_FAIL_UNKNOWN); - CASE_RETURN_TEXT(SMP_REPEATED_ATTEMPTS); - CASE_RETURN_TEXT(SMP_INVALID_PARAMETERS); - CASE_RETURN_TEXT(SMP_DHKEY_CHK_FAIL); - CASE_RETURN_TEXT(SMP_NUMERIC_COMPAR_FAIL); - CASE_RETURN_TEXT(SMP_BR_PARING_IN_PROGR); - CASE_RETURN_TEXT(SMP_XTRANS_DERIVE_NOT_ALLOW); - CASE_RETURN_TEXT(SMP_PAIR_INTERNAL_ERR); - CASE_RETURN_TEXT(SMP_UNKNOWN_IO_CAP); - CASE_RETURN_TEXT(SMP_BUSY); - CASE_RETURN_TEXT(SMP_ENC_FAIL); - CASE_RETURN_TEXT(SMP_STARTED); - CASE_RETURN_TEXT(SMP_RSP_TIMEOUT); - CASE_RETURN_TEXT(SMP_FAIL); - CASE_RETURN_TEXT(SMP_CONN_TOUT); - default: - return base::StringPrintf("UNKNOWN[%hhu]", status); - } -} -#undef CASE_RETURN_TEXT - /* Device IO capability */ #define SMP_IO_CAP_IO BTM_IO_CAP_IO /* DisplayYesNo */ #define SMP_IO_CAP_KBDISP BTM_IO_CAP_KBDISP /* Keyboard Display */ diff --git a/system/stack/include/smp_status.h b/system/stack/include/smp_status.h new file mode 100644 index 00000000000..10c6e59483f --- /dev/null +++ b/system/stack/include/smp_status.h @@ -0,0 +1,96 @@ +/****************************************************************************** + * + * Copyright 1999-2012 Broadcom Corporation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + ******************************************************************************/ + +#pragma once + +#include + +#include + +/* pairing failure reason code */ +typedef enum : uint8_t { + SMP_SUCCESS = 0, + SMP_PASSKEY_ENTRY_FAIL = 0x01, + SMP_OOB_FAIL = 0x02, + SMP_PAIR_AUTH_FAIL = 0x03, + SMP_CONFIRM_VALUE_ERR = 0x04, + SMP_PAIR_NOT_SUPPORT = 0x05, + SMP_ENC_KEY_SIZE = 0x06, + SMP_INVALID_CMD = 0x07, + SMP_PAIR_FAIL_UNKNOWN = 0x08, + SMP_REPEATED_ATTEMPTS = 0x09, + SMP_INVALID_PARAMETERS = 0x0A, + SMP_DHKEY_CHK_FAIL = 0x0B, + SMP_NUMERIC_COMPAR_FAIL = 0x0C, + SMP_BR_PARING_IN_PROGR = 0x0D, + SMP_XTRANS_DERIVE_NOT_ALLOW = 0x0E, + SMP_MAX_FAIL_RSN_PER_SPEC = SMP_XTRANS_DERIVE_NOT_ALLOW, + + /* self defined error code */ + SMP_PAIR_INTERNAL_ERR = (SMP_MAX_FAIL_RSN_PER_SPEC + 0x01), /* 0x0F */ + + /* Unknown IO capability, unable to decide association model */ + SMP_UNKNOWN_IO_CAP = (SMP_MAX_FAIL_RSN_PER_SPEC + 0x02), /* 0x10 */ + + SMP_BUSY = (SMP_MAX_FAIL_RSN_PER_SPEC + 0x05), /* 0x13 */ + SMP_ENC_FAIL = (SMP_MAX_FAIL_RSN_PER_SPEC + 0x06), /* 0x14 */ + SMP_STARTED = (SMP_MAX_FAIL_RSN_PER_SPEC + 0x07), /* 0x15 */ + SMP_RSP_TIMEOUT = (SMP_MAX_FAIL_RSN_PER_SPEC + 0x08), /* 0x16 */ + + /* Unspecified failure reason */ + SMP_FAIL = (SMP_MAX_FAIL_RSN_PER_SPEC + 0x0A), /* 0x18 */ + + SMP_CONN_TOUT = (SMP_MAX_FAIL_RSN_PER_SPEC + 0x0B), /* 0x19 */ +} tSMP_STATUS; + +#ifndef CASE_RETURN_TEXT +#define CASE_RETURN_TEXT(code) \ + case code: \ + return #code +#endif + +inline std::string smp_status_text(const tSMP_STATUS& status) { + switch (status) { + CASE_RETURN_TEXT(SMP_SUCCESS); + CASE_RETURN_TEXT(SMP_PASSKEY_ENTRY_FAIL); + CASE_RETURN_TEXT(SMP_OOB_FAIL); + CASE_RETURN_TEXT(SMP_PAIR_AUTH_FAIL); + CASE_RETURN_TEXT(SMP_CONFIRM_VALUE_ERR); + CASE_RETURN_TEXT(SMP_PAIR_NOT_SUPPORT); + CASE_RETURN_TEXT(SMP_ENC_KEY_SIZE); + CASE_RETURN_TEXT(SMP_INVALID_CMD); + CASE_RETURN_TEXT(SMP_PAIR_FAIL_UNKNOWN); + CASE_RETURN_TEXT(SMP_REPEATED_ATTEMPTS); + CASE_RETURN_TEXT(SMP_INVALID_PARAMETERS); + CASE_RETURN_TEXT(SMP_DHKEY_CHK_FAIL); + CASE_RETURN_TEXT(SMP_NUMERIC_COMPAR_FAIL); + CASE_RETURN_TEXT(SMP_BR_PARING_IN_PROGR); + CASE_RETURN_TEXT(SMP_XTRANS_DERIVE_NOT_ALLOW); + CASE_RETURN_TEXT(SMP_PAIR_INTERNAL_ERR); + CASE_RETURN_TEXT(SMP_UNKNOWN_IO_CAP); + CASE_RETURN_TEXT(SMP_BUSY); + CASE_RETURN_TEXT(SMP_ENC_FAIL); + CASE_RETURN_TEXT(SMP_STARTED); + CASE_RETURN_TEXT(SMP_RSP_TIMEOUT); + CASE_RETURN_TEXT(SMP_FAIL); + CASE_RETURN_TEXT(SMP_CONN_TOUT); + default: + return base::StringPrintf("UNKNOWN[%hhu]", status); + } +} +#undef CASE_RETURN_TEXT diff --git a/system/stack/test/stack_smp_test.cc b/system/stack/test/stack_smp_test.cc index bf442842346..edd82321b28 100644 --- a/system/stack/test/stack_smp_test.cc +++ b/system/stack/test/stack_smp_test.cc @@ -28,6 +28,7 @@ #include "stack/include/acl_api.h" #include "stack/include/bt_octets.h" #include "stack/include/smp_api.h" +#include "stack/include/smp_status.h" #include "stack/smp/p_256_ecc_pp.h" #include "stack/smp/smp_int.h" #include "test/common/mock_functions.h" @@ -35,6 +36,8 @@ #include "types/hci_role.h" #include "types/raw_address.h" +using testing::StrEq; + tBTM_CB btm_cb; const std::string kSmpOptions("mock smp options"); @@ -140,8 +143,6 @@ Octet16 smp_gen_p2_4_confirm(tSMP_CB* p_cb, const RawAddress& remote_bda); tSMP_STATUS smp_calculate_comfirm(tSMP_CB* p_cb, const Octet16& rand, Octet16* output); -namespace testing { - void dump_uint128(const Octet16& a, char* buffer) { for (unsigned int i = 0; i < OCTET16_LEN; ++i) { snprintf(buffer, 3, "%02x", a[i]); @@ -174,7 +175,7 @@ Octet16 parse_uint128(const char* input) { return output; } -class SmpCalculateConfirmTest : public Test { +class SmpCalculateConfirmTest : public testing::Test { protected: tSMP_CB p_cb_; // Set random to 0x5783D52156AD6F0E6388274EC6702EE0 @@ -401,4 +402,43 @@ TEST(SmpEccValidationTest, test_invalid_points) { EXPECT_FALSE(ECC_ValidatePoint(p)); } -} // namespace testing + +TEST(SmpStatusText, smp_status_text) { + std::vector> status = { + std::make_pair(SMP_SUCCESS, "SMP_SUCCESS"), + std::make_pair(SMP_PASSKEY_ENTRY_FAIL, "SMP_PASSKEY_ENTRY_FAIL"), + std::make_pair(SMP_OOB_FAIL, "SMP_OOB_FAIL"), + std::make_pair(SMP_PAIR_AUTH_FAIL, "SMP_PAIR_AUTH_FAIL"), + std::make_pair(SMP_CONFIRM_VALUE_ERR, "SMP_CONFIRM_VALUE_ERR"), + std::make_pair(SMP_PAIR_NOT_SUPPORT, "SMP_PAIR_NOT_SUPPORT"), + std::make_pair(SMP_ENC_KEY_SIZE, "SMP_ENC_KEY_SIZE"), + std::make_pair(SMP_INVALID_CMD, "SMP_INVALID_CMD"), + std::make_pair(SMP_PAIR_FAIL_UNKNOWN, "SMP_PAIR_FAIL_UNKNOWN"), + std::make_pair(SMP_REPEATED_ATTEMPTS, "SMP_REPEATED_ATTEMPTS"), + std::make_pair(SMP_INVALID_PARAMETERS, "SMP_INVALID_PARAMETERS"), + std::make_pair(SMP_DHKEY_CHK_FAIL, "SMP_DHKEY_CHK_FAIL"), + std::make_pair(SMP_NUMERIC_COMPAR_FAIL, "SMP_NUMERIC_COMPAR_FAIL"), + std::make_pair(SMP_BR_PARING_IN_PROGR, "SMP_BR_PARING_IN_PROGR"), + std::make_pair(SMP_XTRANS_DERIVE_NOT_ALLOW, + "SMP_XTRANS_DERIVE_NOT_ALLOW"), + std::make_pair(SMP_MAX_FAIL_RSN_PER_SPEC, + "SMP_XTRANS_DERIVE_NOT_ALLOW"), // NOTE: Dup + std::make_pair(SMP_PAIR_INTERNAL_ERR, "SMP_PAIR_INTERNAL_ERR"), + std::make_pair(SMP_UNKNOWN_IO_CAP, "SMP_UNKNOWN_IO_CAP"), + std::make_pair(SMP_BUSY, "SMP_BUSY"), + std::make_pair(SMP_ENC_FAIL, "SMP_ENC_FAIL"), + std::make_pair(SMP_STARTED, "SMP_STARTED"), + std::make_pair(SMP_RSP_TIMEOUT, "SMP_RSP_TIMEOUT"), + std::make_pair(SMP_FAIL, "SMP_FAIL"), + std::make_pair(SMP_CONN_TOUT, "SMP_CONN_TOUT"), + }; + for (const auto& stat : status) { + ASSERT_STREQ(stat.second.c_str(), smp_status_text(stat.first).c_str()); + } + auto unknown = + base::StringPrintf("UNKNOWN[%hhu]", std::numeric_limits::max()); + ASSERT_STREQ(unknown.c_str(), + smp_status_text(static_cast( + std::numeric_limits::max())) + .c_str()); +} -- GitLab From fe2d40d739f225cdef2bcae2666f40977ebdb1e6 Mon Sep 17 00:00:00 2001 From: Jakub Pawlowski Date: Mon, 8 Nov 2021 13:09:38 +0100 Subject: [PATCH 0072/2405] Keep the IRK when the scan is finished Bug: 201255908 Bug: 280811285 Test: manually tested against phone with sample IRK scanning app Change-Id: I58f8caf2c29bf2b12db2e595d42295b65dc4fa13 Merged-In: I58f8caf2c29bf2b12db2e595d42295b65dc4fa13 --- system/stack/btm/btm_ble_adv_filter.cc | 28 +------------------------- 1 file changed, 1 insertion(+), 27 deletions(-) diff --git a/system/stack/btm/btm_ble_adv_filter.cc b/system/stack/btm/btm_ble_adv_filter.cc index 73a12aeb2ac..f2fd0d9a87c 100644 --- a/system/stack/btm/btm_ble_adv_filter.cc +++ b/system/stack/btm/btm_ble_adv_filter.cc @@ -682,6 +682,7 @@ void BTM_LE_PF_set(tBTM_BLE_PF_FILT_INDEX filt_index, return; } // Allocate a new "temporary" device record + btm_sec_alloc_dev(cmd.address); remove_me_later_map.emplace(filt_index, cmd.address); // Set the IRK @@ -770,15 +771,6 @@ void BTM_LE_PF_clear(tBTM_BLE_PF_FILT_INDEX filt_index, /* clear service data filter */ BTM_LE_PF_srvc_data_pattern(BTM_BLE_SCAN_COND_CLEAR, filt_index, {}, {}, fDoNothing); - - // If we have an entry, lets remove the device if it isn't bonded - auto entry = remove_me_later_map.find(filt_index); - if (entry != remove_me_later_map.end()) { - auto entry = remove_me_later_map.find(filt_index); - if (!btm_sec_is_a_bonded_dev(entry->second)) { - BTM_SecDeleteDevice(entry->second); - } - } } uint8_t len = BTM_BLE_ADV_FILT_META_HDR_LENGTH + BTM_BLE_PF_FEAT_SEL_LEN; @@ -896,24 +888,6 @@ void BTM_BleAdvFilterParamSetup( (uint8_t)(BTM_BLE_ADV_FILT_META_HDR_LENGTH), base::Bind(&btm_flt_update_cb, BTM_BLE_META_PF_FEAT_SEL, cb)); - auto entry = remove_me_later_map.find(filt_index); - if (entry != remove_me_later_map.end()) { - LOG_WARN("Replacing existing filter index entry with new address"); - // If device is not bonded, then try removing the device - // If the device doesn't get removed then it is currently connected - // (may be pairing?) If we do delete the device we want to erase the - // filter index so we can replace it If the device is bonded, we - // want to erase the filter index so we don't delete it in the later - // BTM_LE_PF_clear call. - if (!btm_sec_is_a_bonded_dev(entry->second)) { - if (!BTM_SecDeleteDevice(entry->second)) { - LOG_WARN("Unable to remove device, still connected."); - return; - } - } - remove_me_later_map.erase(filt_index); - } - } else if (BTM_BLE_SCAN_COND_CLEAR == action) { /* Deallocate all filters here */ btm_ble_dealloc_addr_filter_counter(NULL, BTM_BLE_PF_TYPE_ALL); -- GitLab From 3ce8cc69d200afede24964e2257ee410df9743d2 Mon Sep 17 00:00:00 2001 From: Chris Manton Date: Mon, 15 May 2023 14:13:34 -0700 Subject: [PATCH 0073/2405] Remove unused data structure stack::include::sdp_api Bug: 191555414 Test: Compiles Change-Id: Id1200ceddd670b1f9d17049ae41877cf945c6f18 --- system/stack/include/sdp_api.h | 15 --------------- 1 file changed, 15 deletions(-) diff --git a/system/stack/include/sdp_api.h b/system/stack/include/sdp_api.h index c7c4364e9b0..0bcd6bfebaf 100644 --- a/system/stack/include/sdp_api.h +++ b/system/stack/include/sdp_api.h @@ -48,21 +48,6 @@ typedef void(tSDP_DISC_CMPL_CB)(tSDP_RESULT result); typedef void(tSDP_DISC_CMPL_CB2)(tSDP_RESULT result, const void* user_data); -typedef struct { - RawAddress peer_addr; - uint16_t peer_mtu; -} tSDP_DR_OPEN; - -typedef struct { - uint8_t* p_data; - uint16_t data_len; -} tSDP_DR_DATA; - -typedef union { - tSDP_DR_OPEN open; - tSDP_DR_DATA data; -} tSDP_DATA; - /* Define a structure to hold the discovered service information. */ typedef struct { union { -- GitLab From d65e0596b6886cc4089000c6b6c13f21a2ee49b1 Mon Sep 17 00:00:00 2001 From: Bill Yi Date: Tue, 16 May 2023 14:33:09 -0700 Subject: [PATCH 0074/2405] Import translations. DO NOT MERGE ANYWHERE Auto-generated-cl: translation import Change-Id: I03f68c819ae183be456b13f0c74e2ac88bc0f596 --- android/app/res/values-af/strings.xml | 9 ++++++--- android/app/res/values-am/strings.xml | 9 ++++++--- android/app/res/values-ar/strings.xml | 9 ++++++--- android/app/res/values-as/strings.xml | 9 ++++++--- android/app/res/values-az/strings.xml | 9 ++++++--- android/app/res/values-b+sr+Latn/strings.xml | 9 ++++++--- android/app/res/values-be/strings.xml | 9 ++++++--- android/app/res/values-bg/strings.xml | 9 ++++++--- android/app/res/values-bn/strings.xml | 9 ++++++--- android/app/res/values-bs/strings.xml | 9 ++++++--- android/app/res/values-ca/strings.xml | 9 ++++++--- android/app/res/values-cs/strings.xml | 9 ++++++--- android/app/res/values-da/strings.xml | 9 ++++++--- android/app/res/values-de/strings.xml | 9 ++++++--- android/app/res/values-el/strings.xml | 9 ++++++--- android/app/res/values-en-rAU/strings.xml | 9 ++++++--- android/app/res/values-en-rCA/strings.xml | 6 +++--- android/app/res/values-en-rGB/strings.xml | 9 ++++++--- android/app/res/values-en-rIN/strings.xml | 9 ++++++--- android/app/res/values-en-rXC/strings.xml | 6 +++--- android/app/res/values-es-rUS/strings.xml | 9 ++++++--- android/app/res/values-es/strings.xml | 9 ++++++--- android/app/res/values-et/strings.xml | 9 ++++++--- android/app/res/values-eu/strings.xml | 9 ++++++--- android/app/res/values-fa/strings.xml | 9 ++++++--- android/app/res/values-fi/strings.xml | 9 ++++++--- android/app/res/values-fr-rCA/strings.xml | 9 ++++++--- android/app/res/values-fr/strings.xml | 9 ++++++--- android/app/res/values-gl/strings.xml | 9 ++++++--- android/app/res/values-gu/strings.xml | 9 ++++++--- android/app/res/values-hi/strings.xml | 9 ++++++--- android/app/res/values-hr/strings.xml | 9 ++++++--- android/app/res/values-hu/strings.xml | 9 ++++++--- android/app/res/values-hy/strings.xml | 9 ++++++--- android/app/res/values-in/strings.xml | 9 ++++++--- android/app/res/values-is/strings.xml | 9 ++++++--- android/app/res/values-it/strings.xml | 6 +++--- android/app/res/values-iw/strings.xml | 9 ++++++--- android/app/res/values-ja/strings.xml | 9 ++++++--- android/app/res/values-ka/strings.xml | 9 ++++++--- android/app/res/values-kk/strings.xml | 9 ++++++--- android/app/res/values-km/strings.xml | 9 ++++++--- android/app/res/values-kn/strings.xml | 11 +++++++---- android/app/res/values-ko/strings.xml | 9 ++++++--- android/app/res/values-ky/strings.xml | 9 ++++++--- android/app/res/values-lo/strings.xml | 9 ++++++--- android/app/res/values-lt/strings.xml | 9 ++++++--- android/app/res/values-lv/strings.xml | 9 ++++++--- android/app/res/values-mk/strings.xml | 9 ++++++--- android/app/res/values-ml/strings.xml | 9 ++++++--- android/app/res/values-mn/strings.xml | 9 ++++++--- android/app/res/values-mr/strings.xml | 9 ++++++--- android/app/res/values-ms/strings.xml | 9 ++++++--- android/app/res/values-my/strings.xml | 9 ++++++--- android/app/res/values-nb/strings.xml | 9 ++++++--- android/app/res/values-ne/strings.xml | 9 ++++++--- android/app/res/values-nl/strings.xml | 9 ++++++--- android/app/res/values-or/strings.xml | 9 ++++++--- android/app/res/values-pa/strings.xml | 9 ++++++--- android/app/res/values-pl/strings.xml | 9 ++++++--- android/app/res/values-pt-rPT/strings.xml | 6 +++--- android/app/res/values-pt/strings.xml | 9 ++++++--- android/app/res/values-ro/strings.xml | 9 ++++++--- android/app/res/values-ru/strings.xml | 9 ++++++--- android/app/res/values-si/strings.xml | 9 ++++++--- android/app/res/values-sk/strings.xml | 9 ++++++--- android/app/res/values-sl/strings.xml | 9 ++++++--- android/app/res/values-sq/strings.xml | 9 ++++++--- android/app/res/values-sr/strings.xml | 9 ++++++--- android/app/res/values-sv/strings.xml | 9 ++++++--- android/app/res/values-sw/strings.xml | 9 ++++++--- android/app/res/values-ta/strings.xml | 9 ++++++--- android/app/res/values-te/strings.xml | 9 ++++++--- android/app/res/values-th/strings.xml | 9 ++++++--- android/app/res/values-tl/strings.xml | 9 ++++++--- android/app/res/values-tr/strings.xml | 9 ++++++--- android/app/res/values-uk/strings.xml | 9 ++++++--- android/app/res/values-ur/strings.xml | 9 ++++++--- android/app/res/values-uz/strings.xml | 9 ++++++--- android/app/res/values-vi/strings.xml | 9 ++++++--- android/app/res/values-zh-rCN/strings.xml | 9 ++++++--- android/app/res/values-zh-rHK/strings.xml | 9 ++++++--- android/app/res/values-zh-rTW/strings.xml | 9 ++++++--- android/app/res/values-zu/strings.xml | 9 ++++++--- 84 files changed, 493 insertions(+), 253 deletions(-) diff --git a/android/app/res/values-af/strings.xml b/android/app/res/values-af/strings.xml index b48fae73814..892d9e29243 100644 --- a/android/app/res/values-af/strings.xml +++ b/android/app/res/values-af/strings.xml @@ -130,9 +130,12 @@ "Lêers groter as 4 GB kan nie oorgedra word nie" "Koppel aan Bluetooth" "Bluetooth is aan in vliegtuigmodus" - "As jy Bluetooth aangeskakel hou, sal jou foon onthou om dit aan te hou wanneer jy weer in vliegtuigmodus is" + + "Bluetooth bly aan" - "Jou foon onthou om Bluetooth aangeskakel te hou in vliegtuigmodus. Skakel Bluetooth af as jy nie wil hê dit moet aan bly nie." + + "Wi-fi en Bluetooth bly aan" - "Jou foon onthou om wi‑fi en Bluetooth aan te hou in vliegtuigmodus. Skakel wi-fi en Bluetooth af as jy nie wil het hulle moet aan bly nie." + + diff --git a/android/app/res/values-am/strings.xml b/android/app/res/values-am/strings.xml index 6b8449e5f6c..0225a9c74ac 100644 --- a/android/app/res/values-am/strings.xml +++ b/android/app/res/values-am/strings.xml @@ -130,9 +130,12 @@ "ከ4 ጊባ በላይ የሆኑ ፋይሎች ሊዛወሩ አይችሉም" "ከብሉቱዝ ጋር ተገናኝ" "ብሉቱዝ በአውሮፕላን ሁነታ ላይ በርቷል" - "ብሉቱዝን አብርተው ካቆዩ በቀጣይ ጊዜ በአውሮፕላን ሁነታ ውስጥ ሲሆኑ ስልክዎ እሱን አብርቶ ማቆየቱን ያስታውሳል" + + "ብሉቱዝ በርቶ ይቆያል" - "ስልክዎ ብሉቱዝን በአውሮፕላን ሁነታ ውስጥ አብርቶ ማቆየትን ያስታውሳል። በርቶ እንዲቆይ ካልፈለጉ ብሉቱዝን ያጥፉት።" + + "Wi-Fi እና ብሉቱዝ በርተው ይቆያሉ" - "ስልክዎ Wi-Fiን እና ብሉቱዝን በአውሮፕላን ሁነታ ውስጥ አብርቶ ማቆየትን ያስታውሳል። በርተው እንዲቆዩ ካልፈለጉ Wi-Fi እና ብሉቱዝን ያጥፏቸው።" + + diff --git a/android/app/res/values-ar/strings.xml b/android/app/res/values-ar/strings.xml index c6f7396342c..185a98d45d6 100644 --- a/android/app/res/values-ar/strings.xml +++ b/android/app/res/values-ar/strings.xml @@ -130,9 +130,12 @@ "يتعذّر نقل الملفات التي يزيد حجمها عن 4 غيغابايت" "الاتصال ببلوتوث" "تقنية البلوتوث مفعّلة في \"وضع الطيران\"" - "إذا واصلت تفعيل تقنية البلوتوث، سيتذكر هاتفك إبقاءها مفعَّلة في المرة القادمة التي تفعِّل فيها \"وضع الطيران\"." + + "تظل تقنية البلوتوث مفعّلة" - "يتذكر هاتفك الاحتفاظ بتقنية البلوتوث مفعَّلة في \"وضع الطيران\". يمكنك إيقاف تقنية البلوتوث إذا لم تكن تريد مواصلة تفعيلها." + + "‏تظل شبكة Wi‑Fi وتقنية البلوتوث مفعَّلتَين." - "‏يتذكر هاتفك الاحتفاظ بشبكة Wi‑Fi وتقنية البلوتوث مفعَّلتَين في \"وضع الطيران\". يمكنك إيقاف شبكة Wi‑Fi وتقنية البلوتوث إذا لم تكن تريد مواصلة تفعيلهما." + + diff --git a/android/app/res/values-as/strings.xml b/android/app/res/values-as/strings.xml index bcc4a27c942..8ea69c7a586 100644 --- a/android/app/res/values-as/strings.xml +++ b/android/app/res/values-as/strings.xml @@ -130,9 +130,12 @@ "৪ জি. বি. তকৈ ডাঙৰ ফাইল স্থানান্তৰ কৰিব নোৱাৰি" "ব্লুটুথৰ সৈতে সংযোগ কৰক" "এয়াৰপ্লেন ম’ডত ব্লুটুথ অন হৈ থাকিব" - "আপুনি যদি ব্লুটুথ অন কৰি ৰাখে, পৰৱৰ্তী সময়ত আপুনি এয়াৰপ্লেন ম’ড ব্যৱহাৰ কৰিলে আপোনাৰ ফ’নটোৱে এয়া অন কৰি ৰাখিবলৈ মনত ৰাখিব" + + "ব্লুটুথ অন হৈ থাকে" - "আপোনাৰ ফ’নটোৱে এয়াৰপ্লেন ম’ডত ব্লুটুথ অন ৰাখিবলৈ মনত ৰাখে। আপুনি যদি ব্লুটুথ অন হৈ থকাটো নিবিচাৰে, তেন্তে ইয়াক অফ কৰক।" + + "ৱাই-ফাই আৰু ব্লুটুথ অন হৈ থাকে" - "আপোনাৰ ফ’নটোৱে এয়াৰপ্লেন ম’ডত ৱাই-ফাই আৰু ব্লুটুথ অন ৰাখিবলৈ মনত ৰাখে। আপুনি ৱাই-ফাই আৰু ব্লুটুথ অন হৈ থকাটো নিবিচাৰিলে সেইবোৰ অফ কৰক।" + + diff --git a/android/app/res/values-az/strings.xml b/android/app/res/values-az/strings.xml index ec63e9583da..b14eab4ff33 100644 --- a/android/app/res/values-az/strings.xml +++ b/android/app/res/values-az/strings.xml @@ -130,9 +130,12 @@ "4GB-dən böyük olan faylları köçürmək mümkün deyil" "Bluetooth\'a qoşulun" "Bluetooth təyyarə rejimində aktivdir" - "Bluetooth\'u aktiv saxlasanız, növbəti dəfə təyyarə rejimində olduqda telefonunuz onu aktiv saxlayacaq" + + "Bluetooth aktiv qalacaq" - "Telefonunuz təyyarə rejimində Bluetooth\'u aktiv saxlayacaq. Aktiv qalmasını istəmirsinizsə, Bluetooth\'u deaktiv edin." + + "Wi-Fi və Bluetooth aktiv qalır" - "Telefonunuz təyyarə rejimində Wi‑Fi və Bluetooth\'u aktiv saxlayacaq. Aktiv qalmasını istəmirsinizsə, Wi-Fi və Bluetooth\'u deaktiv edin." + + diff --git a/android/app/res/values-b+sr+Latn/strings.xml b/android/app/res/values-b+sr+Latn/strings.xml index e9548e2f298..8a06f3ec2c3 100644 --- a/android/app/res/values-b+sr+Latn/strings.xml +++ b/android/app/res/values-b+sr+Latn/strings.xml @@ -130,9 +130,12 @@ "Ne mogu da se prenose datoteke veće od 4 GB" "Poveži sa Bluetooth-om" "Bluetooth je uključen u režimu rada u avionu" - "Ako odlučite da ne isključujete Bluetooth, telefon će zapamtiti da ga ne isključuje sledeći put kada budete u režimu rada u avionu" + + "Bluetooth se ne isključuje" - "Telefon pamti da ne treba da isključuje Bluetooth u režimu rada u avionu. Isključite Bluetooth ako ne želite da ostane uključen." + + "WiFi i Bluetooth ostaju uključeni" - "Telefon pamti da ne treba da isključuje WiFi i Bluetooth u režimu rada u avionu. Isključite WiFi i Bluetooth ako ne želite da ostanu uključeni." + + diff --git a/android/app/res/values-be/strings.xml b/android/app/res/values-be/strings.xml index ca6767e4a83..b4124f80d6f 100644 --- a/android/app/res/values-be/strings.xml +++ b/android/app/res/values-be/strings.xml @@ -130,9 +130,12 @@ "Немагчыма перадаць файлы, большыя за 4 ГБ" "Падключыцца да Bluetooth" "У рэжыме палёту Bluetooth уключаны" - "Калі вы не выключыце Bluetooth, падчас наступнага пераходу ў рэжым палёту тэлефон будзе захоўваць яго ўключаным" + + "Bluetooth застаецца ўключаным" - "На тэлефоне ў рэжыме палёту Bluetooth застанецца ўключаным, але вы можаце выключыць яго." + + "Wi-Fi і Bluetooth застаюцца ўключанымі" - "На тэлефоне ў рэжыме палёту сетка Wi‑Fi і Bluetooth будуць заставацца ўключанымі, але вы можаце выключыць іх." + + diff --git a/android/app/res/values-bg/strings.xml b/android/app/res/values-bg/strings.xml index 22d88eb0591..0e0d24261d2 100644 --- a/android/app/res/values-bg/strings.xml +++ b/android/app/res/values-bg/strings.xml @@ -130,9 +130,12 @@ "Файловете с размер над 4 ГБ не могат да бъдат прехвърлени" "Свързване с Bluetooth" "Функцията за Bluetooth е включена в самолетния режим" - "Ако не изключите функцията за Bluetooth, телефонът ви ще я остави активна следващия път, когато използвате самолетния режим" + + "Функцията за Bluetooth няма да се изключи" - "Функцията за Bluetooth ще бъде включена, докато телефонът ви е в самолетен режим. Ако не искате това, изключете я." + + "Функциите за Wi-Fi и Bluetooth няма да бъдат изключени" - "Функциите за Wi‑Fi и Bluetooth ще бъдат включени, докато телефонът ви е в самолетен режим. Ако не искате това, изключете ги." + + diff --git a/android/app/res/values-bn/strings.xml b/android/app/res/values-bn/strings.xml index e83784183fc..95d354d40b6 100644 --- a/android/app/res/values-bn/strings.xml +++ b/android/app/res/values-bn/strings.xml @@ -130,9 +130,12 @@ "৪GB থেকে বড় ফটো ট্রান্সফার করা যাবে না" "ব্লুটুথের সাথে কানেক্ট করুন" "\'বিমান মোড\'-এ থাকাকালীন ব্লুটুথ চালু থাকে" - "আপনি ওয়াই-ফাই চালু রাখলে, আপনি এরপর \'বিমান মোডে\' থাকলে আপনার ফোন এটি চালু রাখবে" + + "ব্লুটুথ চালু থাকে" - "\'বিমান মোড\'-এ থাকাকালীন আপনার ফোন ব্লুটুথ চালু রাখে। আপনি ব্লুটুথ চালু না রাখতে চাইলে এটি বন্ধ করুন।" + + "ওয়াই-ফাই ও ব্লুটুথ চালু থাকে" - "\'বিমান মোড\'-এ থাকাকালীন আপনার ফোন ওয়াই-ফাই ও ব্লুটুথ চালু রাখে। আপনি যদি ওয়াই-ফাই এবং ব্লুটুথ চালু রাখতে না চান, সেগুলি বন্ধ করে দিন।" + + diff --git a/android/app/res/values-bs/strings.xml b/android/app/res/values-bs/strings.xml index f21cce84a95..28429a36306 100644 --- a/android/app/res/values-bs/strings.xml +++ b/android/app/res/values-bs/strings.xml @@ -130,9 +130,12 @@ "Nije moguće prenijeti fajlove veće od 4 GB" "Poveži se na Bluetooth" "Bluetooth je uključen u načinu rada u avionu" - "Ako ostavite Bluetooth uključenim, telefon će zapamtiti da ga ostavi uključenog sljedeći put kada budete u načinu rada u avionu" + + "Bluetooth ostaje uključen" - "Telefon pamti da Bluetooth treba biti uključen u načinu rada u avionu. Isključite Bluetooth ako ne želite da ostane uključen." + + "WiFi i Bluetooth ostaju uključeni" - "Telefon pamti da WiFi i Bluetooth trebaju biti uključeni u načinu rada u avionu. Isključite WiFi i Bluetooth ako ne želite da ostanu uključeni." + + diff --git a/android/app/res/values-ca/strings.xml b/android/app/res/values-ca/strings.xml index b476c4e0761..fe765e13640 100644 --- a/android/app/res/values-ca/strings.xml +++ b/android/app/res/values-ca/strings.xml @@ -130,9 +130,12 @@ "No es poden transferir fitxers més grans de 4 GB" "Connecta el Bluetooth" "El Bluetooth està activat en mode d\'avió" - "Si tens activat el Bluetooth, el telèfon recordarà mantenir-lo així la pròxima vegada que utilitzis el mode d\'avió" + + "El Bluetooth es mantindrà activat" - "El telèfon recorda mantenir el Bluetooth activat en mode d\'avió. Desactiva el Bluetooth si no vols que es quedi activat." + + "La Wi‑Fi i el Bluetooth es mantenen activats" - "El telèfon recorda mantenir la Wi‑Fi i el Bluetooth activats en mode d\'avió. Desactiva la Wi‑Fi i el Bluetooth si no vols que es quedin activats." + + diff --git a/android/app/res/values-cs/strings.xml b/android/app/res/values-cs/strings.xml index 09dc67bbb06..c2d1a87658a 100644 --- a/android/app/res/values-cs/strings.xml +++ b/android/app/res/values-cs/strings.xml @@ -130,9 +130,12 @@ "Soubory větší než 4 GB nelze přenést" "Připojit k Bluetooth" "Zapnutý Bluetooth v režimu Letadlo" - "Pokud Bluetooth necháte zapnutý, telefon si zapamatuje, že ho má příště v režimu Letadlo ponechat zapnutý" + + "Bluetooth zůstane zapnutý" - "Telefon si pamatuje, že má v režimu Letadlo ponechat zapnutý Bluetooth. Pokud nechcete, aby Bluetooth zůstal zapnutý, vypněte ho." + + "Wi-Fi a Bluetooth zůstávají zapnuté" - "Telefon si pamatuje, že má v režimu Letadlo ponechat zapnutou Wi-Fi a Bluetooth. Pokud nechcete, aby Wi-Fi a Bluetooth zůstaly zapnuté, vypněte je." + + diff --git a/android/app/res/values-da/strings.xml b/android/app/res/values-da/strings.xml index 47f0b5405c2..1cbd768e721 100644 --- a/android/app/res/values-da/strings.xml +++ b/android/app/res/values-da/strings.xml @@ -130,9 +130,12 @@ "File, der er større end 4 GB, kan ikke overføres" "Opret forbindelse til Bluetooth" "Bluetooth er aktiveret i flytilstand" - "Hvis du holder Bluetooth aktiveret, sørger din telefon for, at Bluetooth forbliver aktiveret, næste gang du sætter den til flytilstand" + + "Bluetooth forbliver aktiveret" - "Din telefon beholder Bluetooth aktiveret i flytilstand. Deaktiver Bluetooth, hvis du ikke vil have, at det forbliver aktiveret." + + "Wi-Fi og Bluetooth forbliver aktiveret" - "Din telefon husker at holde Wi-Fi og Bluetooth aktiveret i flytilstand. Deaktiver Wi-Fi og Bluetooth, hvis du ikke vil have, at de forbliver aktiveret." + + diff --git a/android/app/res/values-de/strings.xml b/android/app/res/values-de/strings.xml index 7d9ade34d72..afbb8b200f0 100644 --- a/android/app/res/values-de/strings.xml +++ b/android/app/res/values-de/strings.xml @@ -130,9 +130,12 @@ "Dateien mit mehr als 4 GB können nicht übertragen werden" "Mit Bluetooth verbinden" "Bluetooth im Flugmodus eingeschaltet" - "Wenn du Bluetooth nicht ausschaltest, bleibt es eingeschaltet, wenn du das nächste Mal in den Flugmodus wechselst" + + "Bluetooth bleibt aktiviert" - "Auf deinem Smartphone bleibt Bluetooth im Flugmodus eingeschaltet. Schalte Bluetooth aus, wenn du das nicht möchtest." + + "WLAN und Bluetooth bleiben eingeschaltet" - "Auf deinem Smartphone bleiben WLAN und Bluetooth im Flugmodus eingeschaltet. Schalte sie aus, wenn du das nicht möchtest." + + diff --git a/android/app/res/values-el/strings.xml b/android/app/res/values-el/strings.xml index 36ebd165d3d..1ff16ce3ae0 100644 --- a/android/app/res/values-el/strings.xml +++ b/android/app/res/values-el/strings.xml @@ -130,9 +130,12 @@ "Δεν είναι δυνατή η μεταφορά αρχείων που ξεπερνούν τα 4 GB" "Σύνδεση σε Bluetooth" "Bluetooth ενεργοποιημένο σε λειτουργία πτήσης" - "Αν διατηρήσετε το Bluetooth ενεργοποιημένο, το τηλέφωνό σας θα θυμάται να το διατηρήσει ενεργοποιημένο την επόμενη φορά που θα βρεθεί σε λειτουργία πτήσης" + + "Το Bluetooth παραμένει ενεργό" - "Το τηλέφωνο θυμάται να διατηρεί ενεργοποιημένο το Bluetooth σε λειτουργία πτήσης. Απενεργοποιήστε το Bluetooth αν δεν θέλετε να παραμένει ενεργοποιημένο." + + "Το Wi-Fi και το Bluetooth παραμένουν ενεργοποιημένα" - "Το τηλέφωνο θυμάται να διατηρεί ενεργοποιημένο το Wi‑Fi και το Bluetooth σε λειτουργία πτήσης. Απενεργοποιήστε το Wi-Fi και το Bluetooth αν δεν θέλετε να παραμένουν ενεργοποιημένα." + + diff --git a/android/app/res/values-en-rAU/strings.xml b/android/app/res/values-en-rAU/strings.xml index 6db8bfaf7c0..80d35500087 100644 --- a/android/app/res/values-en-rAU/strings.xml +++ b/android/app/res/values-en-rAU/strings.xml @@ -130,9 +130,12 @@ "Files bigger than 4 GB cannot be transferred" "Connect to Bluetooth" "Bluetooth on in aeroplane mode" - "If you keep Bluetooth on, your phone will remember to keep it on the next time that you\'re in aeroplane mode" + + "Bluetooth stays on" - "Your phone remembers to keep Bluetooth on in aeroplane mode. Turn off Bluetooth if you don\'t want it to stay on." + + "Wi-Fi and Bluetooth stay on" - "Your phone remembers to keep Wi-Fi and Bluetooth on in aeroplane mode. Turn off Wi-Fi and Bluetooth if you don\'t want them to stay on." + + diff --git a/android/app/res/values-en-rCA/strings.xml b/android/app/res/values-en-rCA/strings.xml index 545853f2c55..45bedcd3f3c 100644 --- a/android/app/res/values-en-rCA/strings.xml +++ b/android/app/res/values-en-rCA/strings.xml @@ -130,9 +130,9 @@ "Files bigger than 4GB cannot be transferred" "Connect to Bluetooth" "Bluetooth on in Airplane mode" - "If you keep Bluetooth on, your phone will remember to keep it on the next time you\'re in Airplane mode" + "If you keep Bluetooth on, your device will remember to keep it on the next time you\'re in airplane mode" "Bluetooth stays on" - "Your phone remembers to keep Bluetooth on in Airplane mode. Turn off Bluetooth if you don\'t want it to stay on." + "Your device remembers to keep Bluetooth on in airplane mode. Turn off Bluetooth if you don\'t want it to stay on." "Wi-Fi and Bluetooth stay on" - "Your phone remembers to keep Wi-Fi and Bluetooth on in Airplane mode. Turn off Wi-Fi and Bluetooth if you don\'t want them to stay on." + "Your device remembers to keep Wi-Fi and Bluetooth on in airplane mode. Turn off Wi-Fi and Bluetooth if you don\'t want them to stay on." diff --git a/android/app/res/values-en-rGB/strings.xml b/android/app/res/values-en-rGB/strings.xml index 6db8bfaf7c0..80d35500087 100644 --- a/android/app/res/values-en-rGB/strings.xml +++ b/android/app/res/values-en-rGB/strings.xml @@ -130,9 +130,12 @@ "Files bigger than 4 GB cannot be transferred" "Connect to Bluetooth" "Bluetooth on in aeroplane mode" - "If you keep Bluetooth on, your phone will remember to keep it on the next time that you\'re in aeroplane mode" + + "Bluetooth stays on" - "Your phone remembers to keep Bluetooth on in aeroplane mode. Turn off Bluetooth if you don\'t want it to stay on." + + "Wi-Fi and Bluetooth stay on" - "Your phone remembers to keep Wi-Fi and Bluetooth on in aeroplane mode. Turn off Wi-Fi and Bluetooth if you don\'t want them to stay on." + + diff --git a/android/app/res/values-en-rIN/strings.xml b/android/app/res/values-en-rIN/strings.xml index 6db8bfaf7c0..80d35500087 100644 --- a/android/app/res/values-en-rIN/strings.xml +++ b/android/app/res/values-en-rIN/strings.xml @@ -130,9 +130,12 @@ "Files bigger than 4 GB cannot be transferred" "Connect to Bluetooth" "Bluetooth on in aeroplane mode" - "If you keep Bluetooth on, your phone will remember to keep it on the next time that you\'re in aeroplane mode" + + "Bluetooth stays on" - "Your phone remembers to keep Bluetooth on in aeroplane mode. Turn off Bluetooth if you don\'t want it to stay on." + + "Wi-Fi and Bluetooth stay on" - "Your phone remembers to keep Wi-Fi and Bluetooth on in aeroplane mode. Turn off Wi-Fi and Bluetooth if you don\'t want them to stay on." + + diff --git a/android/app/res/values-en-rXC/strings.xml b/android/app/res/values-en-rXC/strings.xml index ab3c717f0ef..ec88c80e1b4 100644 --- a/android/app/res/values-en-rXC/strings.xml +++ b/android/app/res/values-en-rXC/strings.xml @@ -130,9 +130,9 @@ "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‎‎‎‏‏‏‎‏‏‏‏‏‏‏‎‏‏‎‏‏‏‏‎‎‎‎‏‎‏‏‏‎‏‏‏‎‏‏‏‎‎‎‏‎‏‎‏‎‎‏‏‎‎‎‎‏‎‎‎‏‎‎‏‏‎‎‏‎‏‎‎‎‏‎‏‎‎Files bigger than 4GB cannot be transferred‎‏‎‎‏‎" "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‎‎‎‏‏‏‎‏‏‏‏‏‎‏‎‎‎‎‎‎‎‏‏‎‎‎‎‎‏‎‏‎‏‏‎‏‎‏‎‏‎‎‏‎‏‎‎‎‎‎‏‏‎‏‎‎‏‏‎‏‏‎‏‎‏‏‎‏‏‎‏‎‎‎‏‎Connect to Bluetooth‎‏‎‎‏‎" "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‎‎‎‏‏‏‎‏‏‏‏‏‏‏‎‏‏‏‏‏‏‏‏‏‎‏‎‏‎‎‎‏‏‎‎‏‏‏‎‎‎‏‏‏‏‎‎‏‎‎‏‎‏‎‎‎‏‎‎‏‏‎‏‏‎‏‎‎‎‎‏‏‎‏‎‎‎Bluetooth on in airplane mode‎‏‎‎‏‎" - "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‎‎‎‏‏‏‎‏‏‏‏‏‏‏‏‏‎‏‎‎‏‎‏‏‎‏‎‏‏‏‏‏‏‎‎‎‎‎‎‎‎‎‎‏‎‎‎‎‎‏‏‏‏‏‎‏‏‏‎‎‏‏‎‏‎‏‎‏‎‏‏‎‎‎‎‏‎If you keep Bluetooth on, your phone will remember to keep it on the next time you\'re in airplane mode‎‏‎‎‏‎" + "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‎‎‎‏‏‏‎‏‏‏‏‏‏‏‎‏‎‏‎‏‏‎‎‏‏‎‏‏‏‎‎‏‎‎‏‏‎‏‏‎‏‎‎‎‏‏‏‎‎‎‏‎‏‏‏‏‏‏‎‎‏‏‏‏‎‏‎‏‏‎‏‏‎‎‎‏‎If you keep Bluetooth on, your device will remember to keep it on the next time you\'re in airplane mode‎‏‎‎‏‎" "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‎‎‎‏‏‏‎‏‏‏‎‎‎‏‎‎‎‏‏‎‏‎‎‎‏‏‏‎‏‏‏‏‎‎‎‎‎‎‏‎‎‏‏‏‏‎‎‏‏‏‎‎‎‏‏‏‎‏‏‎‎‎‏‏‏‎‏‏‎‎Bluetooth stays on‎‏‎‎‏‎" - "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‎‎‎‏‏‏‎‏‏‏‏‏‏‏‏‎‎‎‏‏‎‎‎‏‏‏‏‏‎‎‎‏‎‏‏‏‎‏‏‏‏‏‏‏‏‎‏‏‎‎‎‎‎‏‏‏‏‏‏‎‎‏‎‏‎‎‎‏‏‏‏‎‏‏‎‏‎Your phone remembers to keep Bluetooth on in airplane mode. Turn off Bluetooth if you don\'t want it to stay on.‎‏‎‎‏‎" + "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‎‎‎‏‏‏‎‏‏‏‏‏‎‏‏‎‎‏‎‏‏‏‎‏‏‎‏‎‏‎‎‎‎‏‏‎‏‏‏‎‏‏‏‏‎‏‎‏‎‎‏‎‎‎‎‏‏‎‎‎‏‏‏‎‏‏‎‎‏‏‎‏‎‎‏‎Your device remembers to keep Bluetooth on in airplane mode. Turn off Bluetooth if you don\'t want it to stay on.‎‏‎‎‏‎" "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‎‎‎‏‏‏‎‏‏‏‏‏‏‏‎‏‎‎‎‎‏‏‎‎‏‎‏‏‏‎‏‎‏‎‎‏‎‎‎‎‏‎‎‎‏‏‎‏‏‏‏‎‎‏‎‎‏‎‏‏‏‎‎‎‎‎‏‎‏‏‏‏‏‏‎‎‎Wi-Fi and Bluetooth stay on‎‏‎‎‏‎" - "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‎‎‎‏‏‏‎‏‏‏‏‏‎‏‎‎‎‎‏‎‎‏‎‏‏‎‏‏‎‏‎‎‏‏‎‎‏‎‎‏‏‎‏‏‎‎‎‎‎‎‎‎‎‏‏‏‏‎‎‎‎‏‎‎‏‏‏‎‎‎‎‎‏‎‎‎Your phone remembers to keep Wi-Fi and Bluetooth on in airplane mode. Turn off Wi-Fi and Bluetooth if you don\'t want them to stay on.‎‏‎‎‏‎" + "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‎‎‎‏‏‏‎‏‏‏‏‏‏‏‏‎‏‏‎‎‏‏‏‎‏‎‏‏‏‎‏‏‎‏‎‎‎‏‏‏‏‎‎‎‎‎‏‎‏‎‏‏‏‎‎‏‏‎‏‏‎‎‎‏‏‏‏‎‎‎‏‏‏‏‏‎‎Your device remembers to keep Wi-Fi and Bluetooth on in airplane mode. Turn off Wi-Fi and Bluetooth if you don\'t want them to stay on.‎‏‎‎‏‎" diff --git a/android/app/res/values-es-rUS/strings.xml b/android/app/res/values-es-rUS/strings.xml index 9969588c3b7..696a6b83ae4 100644 --- a/android/app/res/values-es-rUS/strings.xml +++ b/android/app/res/values-es-rUS/strings.xml @@ -130,9 +130,12 @@ "No se pueden transferir los archivos de más de 4 GB" "Conectarse a Bluetooth" "Bluetooth activado en modo de avión" - "Si mantienes el Bluetooth activado, el teléfono lo dejará activado la próxima vez que actives el modo de avión" + + "El Bluetooth permanece activado" - "El teléfono dejará activado el Bluetooth en el modo de avión. Desactívalo si no quieres que permanezca activado." + + "El Wi-Fi y el Bluetooth permanecen activados" - "El teléfono dejará activado el Wi-Fi y el Bluetooth en el modo de avión. Si no quieres que permanezcan activados, desactívalos." + + diff --git a/android/app/res/values-es/strings.xml b/android/app/res/values-es/strings.xml index 59550d79099..58e607d4744 100644 --- a/android/app/res/values-es/strings.xml +++ b/android/app/res/values-es/strings.xml @@ -130,9 +130,12 @@ "No se pueden transferir archivos de más de 4 GB" "Conectarse a un dispositivo Bluetooth" "Bluetooth activado en modo Avión" - "Si dejas el Bluetooth activado, tu teléfono se acordará de mantenerlo así la próxima vez que uses el modo Avión" + + "El Bluetooth permanece activado" - "Tu teléfono se acordará de mantener activado el Bluetooth en modo Avión. Desactiva el Bluetooth si no quieres que permanezca activado." + + "El Wi-Fi y el Bluetooth permanecen activados" - "Tu teléfono se acordará de mantener activados el Wi-Fi y el Bluetooth en modo Avión. Desactívalos si no quieres que permanezcan activados." + + diff --git a/android/app/res/values-et/strings.xml b/android/app/res/values-et/strings.xml index 95163ce8d2b..96a0b2e9fd7 100644 --- a/android/app/res/values-et/strings.xml +++ b/android/app/res/values-et/strings.xml @@ -130,9 +130,12 @@ "Faile, mis on üle 4 GB, ei saa üle kanda" "Ühenda Bluetoothiga" "Bluetooth on lennukirežiimis sisse lülitatud" - "Kui hoiate Bluetoothi sisselülitatuna, jätab telefon teie valiku meelde ja kasutab seda järgmisel korral lennukirežiimi aktiveerimisel." + + "Bluetooth jääb sisselülitatuks" - "Teie telefon hoiab Bluetoothi lennukirežiimis sisselülitatuna. Lülitage Bluetooth välja, kui te ei soovi, et see oleks sisse lülitatud." + + "WiFi ja Bluetoothi jäävad sisselülitatuks" - "Teie telefon hoiab WiFi ja Bluetoothi lennukirežiimis sisselülitatuna. Lülitage WiFi ja Bluetooth välja, kui te ei soovi, et need oleksid sisse lülitatud." + + diff --git a/android/app/res/values-eu/strings.xml b/android/app/res/values-eu/strings.xml index 72a8773ed4c..f7190e2b9d3 100644 --- a/android/app/res/values-eu/strings.xml +++ b/android/app/res/values-eu/strings.xml @@ -130,9 +130,12 @@ "Ezin dira transferitu 4 GB baino gehiagoko fitxategiak" "Konektatu Bluetoothera" "Bluetootha aktibatuta mantentzen da hegaldi moduan" - "Bluetootha aktibatuta utziz gero, hura aktibatuta mantentzeaz gogoratuko da telefonoa hegaldi modua erabiltzen duzun hurrengoan" + + "Bluetootha aktibatuta mantenduko da" - "Hegaldi moduan, Bluetootha aktibatuta mantentzeaz gogoratzen da telefonoa. Halakorik nahi ez baduzu, desaktiba ezazu zuk zeuk." + + "Wifia eta Bluetootha aktibatuta mantentzen dira" - "Hegaldi moduan, wifia eta Bluetootha aktibatuta mantentzeaz gogoratzen da telefonoa. Halakorik nahi ez baduzu, desaktiba itzazu zuk zeuk." + + diff --git a/android/app/res/values-fa/strings.xml b/android/app/res/values-fa/strings.xml index a6234d2ef37..726b2b1fd4f 100644 --- a/android/app/res/values-fa/strings.xml +++ b/android/app/res/values-fa/strings.xml @@ -130,9 +130,12 @@ "فایل‌های بزرگ‌تر از ۴ گیگابایت نمی‌توانند منتقل شوند" "اتصال به بلوتوث" "بلوتوث در «حالت هواپیما» روشن باشد" - "اگر بلوتوث را روشن نگه دارید، تلفنتان به‌یاد خواهد داشت تا دفعه بعدی که در «حالت هواپیما» هستید آن را روشن نگه دارد" + + "بلوتوث روشن بماند" - "تلفنتان به‌یاد می‌آورد که بلوتوث را در «حالت هواپیما» روشن نگه دارد. اگر نمی‌خواهید بلوتوث روشن بماند، آن را خاموش کنید." + + "‏‫Wi-Fi و بلوتوث روشن بماند" - "‏تلفنتان به‌یاد می‌آورد که Wi-Fi و بلوتوث را در «حالت هواپیما» روشن نگه دارد. اگر نمی‌خواهید Wi-Fi و بلوتوث روشن بمانند، آن‌ها را خاموش کنید." + + diff --git a/android/app/res/values-fi/strings.xml b/android/app/res/values-fi/strings.xml index 7df0835d2ee..6ec8a4d8d29 100644 --- a/android/app/res/values-fi/strings.xml +++ b/android/app/res/values-fi/strings.xml @@ -130,9 +130,12 @@ "Yli 4 Gt:n kokoisia tiedostoja ei voi siirtää." "Muodosta Bluetooth-yhteys" "Bluetooth päällä lentokonetilassa" - "Jos pidät Bluetooth-yhteyden päällä, puhelin pitää sen päällä, kun seuraavan kerran olet lentokonetilassa" + + "Bluetooth pysyy päällä" - "Puhelimen Bluetooth pysyy päällä lentokonetilassa. Voit halutessasi laittaa Bluetooth-yhteyden pois päältä." + + "Wi-Fi ja Bluetooth pysyvät päällä" - "Puhelimen Wi-Fi-yhteys ja Bluetooth pysyvät päällä lentokonetilassa. Voit halutessasi laittaa ne pois päältä." + + diff --git a/android/app/res/values-fr-rCA/strings.xml b/android/app/res/values-fr-rCA/strings.xml index a31fd1f34d3..3cc879dc709 100644 --- a/android/app/res/values-fr-rCA/strings.xml +++ b/android/app/res/values-fr-rCA/strings.xml @@ -130,9 +130,12 @@ "Les fichiers dépassant 4 Go ne peuvent pas être transférés" "Connexion au Bluetooth" "Bluetooth activé en mode Avion" - "Si vous laissez le Bluetooth activé, votre téléphone se souviendra qu\'il doit le laisser activé la prochaine fois que vous serez en mode Avion" + + "Le Bluetooth reste activé" - "Votre téléphone se souvient de garder le Bluetooth activé en mode Avion. Désactivez le Bluetooth si vous ne souhaitez pas qu\'il reste activé." + + "Le Wi-Fi et le Bluetooth restent activés" - "Votre téléphone se souvient de garder le Wi-Fi et le Bluetooth activés en mode Avion. Désactivez le Wi-Fi et le Bluetooth si vous ne souhaitez pas qu\'ils restent activés." + + diff --git a/android/app/res/values-fr/strings.xml b/android/app/res/values-fr/strings.xml index c21ab432091..b80558ee009 100644 --- a/android/app/res/values-fr/strings.xml +++ b/android/app/res/values-fr/strings.xml @@ -130,9 +130,12 @@ "Impossible de transférer les fichiers supérieurs à 4 Go" "Se connecter au Bluetooth" "Bluetooth activé en mode Avion" - "Si vous laissez le Bluetooth activé, votre téléphone s\'en souviendra et le Bluetooth restera activé la prochaine fois que vous serez en mode Avion" + + "Le Bluetooth reste activé" - "Le Bluetooth restera activé en mode Avion. Vous pouvez le désactiver si vous le souhaitez." + + "Le Wi-Fi et le Bluetooth restent activés" - "Le Wi‑Fi et le Bluetooth de votre téléphone resteront activés en mode Avion. Vous pouvez les désactivez si vous le souhaitez." + + diff --git a/android/app/res/values-gl/strings.xml b/android/app/res/values-gl/strings.xml index 65c367f494d..9f2fe3dbcbc 100644 --- a/android/app/res/values-gl/strings.xml +++ b/android/app/res/values-gl/strings.xml @@ -130,9 +130,12 @@ "Non se poden transferir ficheiros de máis de 4 GB" "Conectar ao Bluetooth" "Bluetooth activado no modo avión" - "Se mantés o Bluetooth activado, o teléfono lembrará que ten que deixalo nese estado a próxima vez que esteas no modo avión" + + "O Bluetooth permanece activado" - "O teu teléfono lembrará manter o Bluetooth activado no modo avión. Se non queres que permaneza nese estado, desactívao." + + "A wifi e o Bluetooth permanecen activados" - "O teu teléfono lembrará manter a wifi e o Bluetooth activados no modo avión. Se non queres que permanezan nese estado, desactívaos." + + diff --git a/android/app/res/values-gu/strings.xml b/android/app/res/values-gu/strings.xml index d33df6b00b7..2ff5809472b 100644 --- a/android/app/res/values-gu/strings.xml +++ b/android/app/res/values-gu/strings.xml @@ -130,9 +130,12 @@ "4GB કરતા મોટી ફાઇલ ટ્રાન્સફર કરી શકાતી નથી" "બ્લૂટૂથ સાથે કનેક્ટ કરો" "એરપ્લેન મોડમાં બ્લૂટૂથ ચાલુ છે" - "જો તમે બ્લૂટૂથ ચાલુ રાખો, તો તમે જ્યારે આગલી વખતે એરપ્લેન મોડ પર જશો, ત્યારે તમારો ફોન તેને ચાલુ રાખવાનું યાદ રાખશે" + + "બ્લૂટૂથ ચાલુ રહેશે" - "તમારો ફોન બ્લૂટૂથને એરપ્લેન મોડમાં ચાલુ રાખવાનું યાદ રાખે છે. જો તમે બ્લૂટૂથ ચાલુ રાખવા માગતા ન હો, તો તેને બંધ કરો." + + "વાઇ-ફાઇ અને બ્લૂટૂથ ચાલુ રહે છે" - "તમારો ફોન વાઇ-ફાઇ અને બ્લૂટૂથને એરપ્લેન મોડમાં ચાલુ રાખવાનું યાદ રાખે છે. જો તમે વાઇ-ફાઇ અને બ્લૂટૂથ ચાલુ રાખવા માગતા ન હો, તો તેને બંધ કરો." + + diff --git a/android/app/res/values-hi/strings.xml b/android/app/res/values-hi/strings.xml index 829042394ea..e57a75de5bf 100644 --- a/android/app/res/values-hi/strings.xml +++ b/android/app/res/values-hi/strings.xml @@ -130,9 +130,12 @@ "4 जीबी से बड़ी फ़ाइलें ट्रांसफ़र नहीं की जा सकतीं" "ब्लूटूथ से कनेक्ट करें" "हवाई जहाज़ मोड में ब्लूटूथ चालू है" - "ब्लूटूथ चालू रखने पर आपका फ़ोन, अगली बार हवाई जहाज़ मोड चालू होने पर भी ब्लूटूथ चालू रखेगा" + + "ब्लूटूथ चालू रहता है" - "हवाई जहाज़ मोड में भी, आपका फ़ोन ब्लूटूथ चालू रखता है. अगर ब्लूटूथ चालू नहीं रखना है, तो उसे बंद कर दें." + + "वाई-फ़ाई और ब्लूटूथ चालू रहते हैं" - "हवाई जहाज़ मोड में भी, आपका फ़ोन वाई-फ़ाई और ब्लूटूथ को चालू रखता है. अगर आपको वाई-फ़ाई और ब्लूटूथ चालू नहीं रखना है, तो उन्हें बंद कर दें." + + diff --git a/android/app/res/values-hr/strings.xml b/android/app/res/values-hr/strings.xml index f660c0ba248..9369aa96d02 100644 --- a/android/app/res/values-hr/strings.xml +++ b/android/app/res/values-hr/strings.xml @@ -130,9 +130,12 @@ "Datoteke veće od 4 GB ne mogu se prenijeti" "Povezivanje s Bluetoothom" "Bluetooth je uključen u načinu rada u zrakoplovu" - "Ako Bluetooth ostane uključen, telefon će zapamtiti da treba ostati uključen u načinu rada u zrakoplovu" + + "Bluetooth ostaje uključen" - "Telefon će zapamtiti da Bluetooth treba ostati uključen u načinu rada u zrakoplovu. Isključite Bluetooth ako ne želite da ostane uključen." + + "Wi-Fi i Bluetooth ostat će uključeni" - "Telefon će zapamtiti da Wi‑Fi i Bluetooth trebaju ostati uključeni u načinu rada u zrakoplovu. Uključite Wi-Fi i Bluetooth ako ne želite da ostanu uključeni." + + diff --git a/android/app/res/values-hu/strings.xml b/android/app/res/values-hu/strings.xml index 85a1c3ecd85..0e97f2707a4 100644 --- a/android/app/res/values-hu/strings.xml +++ b/android/app/res/values-hu/strings.xml @@ -130,9 +130,12 @@ "A 4 GB-nál nagyobb fájlokat nem lehet átvinni" "Csatlakozás Bluetooth-eszközhöz" "Bluetooth bekapcsolva Repülős üzemmódban" - "Ha bekapcsolva tartja a Bluetootht, a telefon emlékezni fog arra, hogy a következő alkalommal, amikor Repülős üzemmódban van, bekapcsolva tartsa a funkciót." + + "A Bluetooth bekapcsolva marad" - "A telefon bekapcsolva tartja a Bluetootht Repülős üzemmódban. Kapcsolja ki a Bluetootht, ha nem szeretné, hogy bekapcsolva maradjon." + + "A Wi-Fi és a Bluetooth bekapcsolva marad" - "A telefon bekapcsolva tartja a Wi‑Fi-t és a Bluetootht Repülős üzemmódban. Ha nem szeretné, hogy bekapcsolva maradjon a Wi-Fi és a Bluetooth, kapcsolja ki őket." + + diff --git a/android/app/res/values-hy/strings.xml b/android/app/res/values-hy/strings.xml index af488cef809..92bde6c9be0 100644 --- a/android/app/res/values-hy/strings.xml +++ b/android/app/res/values-hy/strings.xml @@ -130,9 +130,12 @@ "4 ԳԲ-ից մեծ ֆայլերը հնարավոր չէ փոխանցել" "Միանալ Bluetooth-ին" "Bluetooth-ը միացված է ավիառեժիմում" - "Եթե Bluetooth-ը միացված թողնեք, հաջորդ անգամ այն ավտոմատ միացված կմնա ավիառեժիմում" + + "Bluetooth-ը կմնա միացված" - "Ավիառեժիմում Bluetooth-ը միացված կմնա։ Ցանկության դեպքում կարող եք անջատել Bluetooth-ը։" + + "Wi-Fi-ը և Bluetooth-ը մնում են միացված" - "Ավիառեժիմում Wi-Fi-ը և Bluetooth-ը միացված կմնան։ Ցանկության դեպքում կարող եք անջատել Wi-Fi-ը և Bluetooth-ը։" + + diff --git a/android/app/res/values-in/strings.xml b/android/app/res/values-in/strings.xml index 5aeac7db04e..aef3d7ebb82 100644 --- a/android/app/res/values-in/strings.xml +++ b/android/app/res/values-in/strings.xml @@ -130,9 +130,12 @@ "File yang berukuran lebih dari 4GB tidak dapat ditransfer" "Hubungkan ke Bluetooth" "Bluetooth aktif dalam mode pesawat" - "Jika Bluetooth tetap diaktifkan, ponsel akan ingat untuk tetap mengaktifkannya saat berikutnya ponsel Anda disetel ke mode pesawat" + + "Bluetooth tetap aktif" - "Ponsel akan mengingat untuk tetap mengaktifkan Bluetooth dalam mode pesawat. Nonaktifkan jika Anda tidak ingin Bluetooth terus aktif." + + "Wi-Fi dan Bluetooth tetap aktif" - "Ponsel akan mengingat untuk tetap mengaktifkan Wi-Fi dan Bluetooth dalam mode pesawat. Nonaktifkan jika Anda tidak ingin Wi-Fi dan Bluetooth terus aktif." + + diff --git a/android/app/res/values-is/strings.xml b/android/app/res/values-is/strings.xml index eecd43f453b..e0b29c65a3b 100644 --- a/android/app/res/values-is/strings.xml +++ b/android/app/res/values-is/strings.xml @@ -130,9 +130,12 @@ "Ekki er hægt að flytja skrár sem eru stærri en 4 GB" "Tengjast við Bluetooth" "Kveikt á Bluetooth í flugstillingu" - "Ef þú hefur kveikt á Bluetooth mun síminn muna að hafa kveikt á því næst þegar þú stillir á flugstillingu" + + "Áfram kveikt á Bluetooth" - "Síminn man að hafa kveikt á Bluetooth í flugstillingu. Slökktu á Bluetooth ef þú vilt ekki hafa kveikt á því." + + "Áfram verður kveikt á Wi-Fi og Bluetooth" - "Síminn man að hafa kveikt á Wi-Fi og Bluetooth í flugstillingu. Slökktu á Wi-Fi og Bluetooth ef þú vilt ekki hafa kveikt á þessu." + + diff --git a/android/app/res/values-it/strings.xml b/android/app/res/values-it/strings.xml index 289a8e572d7..5c02e81f0bb 100644 --- a/android/app/res/values-it/strings.xml +++ b/android/app/res/values-it/strings.xml @@ -130,9 +130,9 @@ "Impossibile trasferire file con dimensioni superiori a 4 GB" "Connettiti a Bluetooth" "Bluetooth attivo in modalità aereo" - "Se tieni attivo il Bluetooth, il telefono ricorderà di tenerlo attivo la prossima volta che sarai in modalità aereo" + "Se tieni attivo il Bluetooth, il dispositivo memorizza che dovrà tenerlo attivo la prossima volta che sarai in modalità aereo" "Il Bluetooth rimane attivo" - "Il telefono memorizza che deve tenere attivo il Bluetooth in modalità aereo. Disattiva il Bluetooth se non vuoi tenerlo attivo." + "Il dispositivo memorizza che deve tenere attivo il Bluetooth in modalità aereo. Disattiva il Bluetooth se non vuoi tenerlo attivo." "Wi-Fi e Bluetooth rimangono attivi" - "Il telefono memorizza che deve tenere attivi il Wi‑Fi e il Bluetooth in modalità aereo. Disattiva il Wi-Fi e il Bluetooth se non vuoi tenerli attivi." + "Il dispositivo memorizza che deve tenere attivi il Wi‑Fi e il Bluetooth in modalità aereo. Disattiva il Wi-Fi e il Bluetooth se non vuoi tenerli attivi." diff --git a/android/app/res/values-iw/strings.xml b/android/app/res/values-iw/strings.xml index 5b6c45a60a1..b3b2df4ce99 100644 --- a/android/app/res/values-iw/strings.xml +++ b/android/app/res/values-iw/strings.xml @@ -130,9 +130,12 @@ "‏לא ניתן להעביר קבצים שגדולים מ-4GB" "‏התחברות באמצעות Bluetooth" "‏חיבור ה-Bluetooth מופעל במצב טיסה" - "‏אם חיבור ה-Bluetooth נשאר מופעל, הטלפון יזכור להשאיר אותו מופעל בפעם הבאה שהוא יועבר למצב טיסה" + + "‏Bluetooth יישאר מופעל" - "‏חיבור ה-Bluetooth בטלפון יישאר מופעל במצב טיסה. אפשר להשבית את ה-Bluetooth אם לא רוצים שהוא יפעל." + + "‏חיבורי ה-Wi‑Fi וה-Bluetooth יישארו מופעלים" - "‏חיבורי ה-Wi‑Fi וה-Bluetooth בטלפון יישארו מופעלים במצב טיסה. אפשר להשבית את ה-Wi-Fi וה-Bluetooth אם לא רוצים שהם יפעלו." + + diff --git a/android/app/res/values-ja/strings.xml b/android/app/res/values-ja/strings.xml index 80ca7afc69e..6c04d4ede90 100644 --- a/android/app/res/values-ja/strings.xml +++ b/android/app/res/values-ja/strings.xml @@ -130,9 +130,12 @@ "4 GB を超えるファイルは転送できません" "Bluetooth に接続する" "機内モードで Bluetooth を ON にする" - "Bluetooth を ON にしておくと、次に機内モードになったときも ON のままになります" + + "Bluetooth を ON にしておく" - "機内モードでも、スマートフォンの Bluetooth は ON のままになります。Bluetooth を ON にしたくない場合は OFF にしてください。" + + "Wi-Fi と Bluetooth を ON のままにする" - "機内モードでも、スマートフォンの Wi-Fi と Bluetooth は ON のままになります。Wi-Fi と Bluetooth を ON にしたくない場合は OFF にしてください。" + + diff --git a/android/app/res/values-ka/strings.xml b/android/app/res/values-ka/strings.xml index 7eec41ad237..40fbeb66290 100644 --- a/android/app/res/values-ka/strings.xml +++ b/android/app/res/values-ka/strings.xml @@ -130,9 +130,12 @@ "4 გბაიტზე დიდი მოცულობის ფაილების გადატანა ვერ მოხერხდება" "Bluetooth-თან დაკავშირება" "Bluetooth ჩართულია თვითმფრინავის რეჟიმში" - "თუ Bluetooth-ს ჩართულს დატოვებთ, თქვენი ტელეფონი დაიმახსოვრებს და ჩართულს დატოვებს მას, როდესაც შემდეგ ჯერზე თვითმფრინავის რეჟიმში იქნებით" + + "Bluetooth რᲩება Ჩართული" - "თქვენს ტელეფონს ემახსოვრება, რომ Bluetooth ჩართული უნდა იყოს თვითმფრინავის რეჟიმში. გამორთეთ Bluetooth, თუ არ გსურთ, რომ ის ჩართული იყოს." + + "Wi-Fi და Bluetooth ჩართული დარჩება" - "თქვენს ტელეფონს ემახსოვრება, რომ Wi‑Fi და Bluetooth ჩართული უნდა იყოს თვითმფრინავის რეჟიმში. გამორთეთ Wi-Fi და Bluetooth, თუ არ გსურთ, რომ ისინი ჩართული იყოს." + + diff --git a/android/app/res/values-kk/strings.xml b/android/app/res/values-kk/strings.xml index 2280615c58c..1d691ab1c72 100644 --- a/android/app/res/values-kk/strings.xml +++ b/android/app/res/values-kk/strings.xml @@ -130,9 +130,12 @@ "Көлемі 4 ГБ-тан асатын файлдар тасымалданбайды" "Bluetooth-қа қосылу" "Bluetooth ұшақ режимінде қосулы" - "Bluetooth-ты қосулы қалдырсаңыз, келесі жолы ұшақ режиміне ауысқанда да ол қосылып тұрады." + + "Bluetooth қосулы болады" - "Bluetooth ұшақ режимінде қосылып тұрады. Қаласаңыз, оны өшіріп қоюыңызға болады." + + "Wi-Fi мен Bluetooth қосулы тұрады" - "Wi‑Fi мен Bluetooth ұшақ режимінде қосылып тұрады. Қаласаңыз, оларды өшіріп қоюыңызға болады." + + diff --git a/android/app/res/values-km/strings.xml b/android/app/res/values-km/strings.xml index b69eeb07c08..120b380017c 100644 --- a/android/app/res/values-km/strings.xml +++ b/android/app/res/values-km/strings.xml @@ -130,9 +130,12 @@ "ឯកសារ​ដែល​មាន​ទំហំ​ធំ​ជាង 4 GB មិន​អាចផ្ទេរ​បាន​ទេ" "ភ្ជាប់​ប៊្លូធូស" "បើកប៊្លូធូស​នៅក្នុង​មុខងារពេលជិះយន្តហោះ" - "ប្រសិនបើអ្នក​បើកប៊្លូធូស នោះទូរសព្ទ​របស់អ្នកនឹង​ចាំថាត្រូវបើកវា នៅលើកក្រោយ​ដែលអ្នកស្ថិតក្នុង​មុខងារពេលជិះយន្តហោះ" + + "ប៊្លូធូសបន្តបើក" - "ទូរសព្ទរបស់អ្នក​ចាំថាត្រូវបើកប៊្លូធូស​នៅក្នុង​មុខងារពេលជិះយន្តហោះ។ បិទប៊្លូធូស ប្រសិនបើអ្នក​មិនចង់បើកទេ។" + + "Wi-Fi និងប៊្លូធូស​បន្តបើក" - "ទូរសព្ទរបស់អ្នក​ចាំថាត្រូវបើក Wi-Fi និងប៊្លូធូស​នៅក្នុង​មុខងារពេលជិះយន្តហោះ។ បិទ Wi-Fi និង​ប៊្លូធូស ប្រសិនបើអ្នក​មិនចង់បើកទេ។" + + diff --git a/android/app/res/values-kn/strings.xml b/android/app/res/values-kn/strings.xml index d7a5cbecc34..1049c0ef8df 100644 --- a/android/app/res/values-kn/strings.xml +++ b/android/app/res/values-kn/strings.xml @@ -78,7 +78,7 @@ "ಫೈಲ್‌ ಅಸ್ತಿತ್ವದಲ್ಲಿಲ್ಲ. \n" "ದಯವಿಟ್ಟು ನಿರೀಕ್ಷಿಸಿ…" "ಬ್ಲೂಟೂತ್‌ ಆನ್‌ ಮಾಡಲಾಗುತ್ತಿದೆ…" - "ಫೈಲ್‌ ಸ್ವೀಕರಿಸಲಾಗುತ್ತದೆ. ಅಧಿಸೂಚನೆ ಫಲಕದಲ್ಲಿ ಪ್ರಗತಿಯನ್ನು ಪರಿಶೀಲಿಸಿ." + "ಫೈಲ್‌ ಸ್ವೀಕರಿಸಲಾಗುತ್ತದೆ. ನೋಟಿಫಿಕೇಶನ್ ಫಲಕದಲ್ಲಿ ಪ್ರಗತಿಯನ್ನು ಪರಿಶೀಲಿಸಿ." "ಫೈಲ್‌ ಸ್ವೀಕರಿಸಲು ಸಾಧ್ಯವಿಲ್ಲ." "\"%1$s\" ರಿಂದ ಫೈಲ್‌ ಸ್ವೀಕರಿಸುವುದನ್ನು ನಿಲ್ಲಿಸಲಾಗಿದೆ" "\"%1$s\" ಇವರಿಗೆ ಫೈಲ್‌‌ ಕಳುಹಿಸಲಾಗುತ್ತಿದೆ" @@ -130,9 +130,12 @@ "4GB ಗಿಂತ ದೊಡ್ಡದಾದ ಫೈಲ್‌ಗಳನ್ನು ವರ್ಗಾಯಿಸಲು ಸಾಧ್ಯವಿಲ್ಲ" "ಬ್ಲೂಟೂತ್‌ಗೆ ಕನೆಕ್ಟ್ ಮಾಡಿ" "ಏರ್‌ಪ್ಲೇನ್ ಮೋಡ್‌ನಲ್ಲಿ ಬ್ಲೂಟೂತ್ ಆನ್ ಆಗಿದೆ" - "ನೀವು ಬ್ಲೂಟೂತ್ ಆನ್ ಆಗಿರಿಸಿದರೆ, ಮುಂದಿನ ಬಾರಿ ನೀವು ಏರ್‌ಪ್ಲೇನ್ ಮೋಡ್‌ನಲ್ಲಿರುವಾಗ ಅದನ್ನು ಆನ್ ಆಗಿರಿಸಿಕೊಳ್ಳುವುದನ್ನು ನಿಮ್ಮ ಫೋನ್ ನೆನಪಿಸಿಕೊಳ್ಳುತ್ತದೆ" + + "ಬ್ಲೂಟೂತ್ ಆನ್ ಆಗಿರುತ್ತದೆ" - "ಏರ್‌ಪ್ಲೇನ್ ಮೋಡ್‌ನಲ್ಲಿ ಬ್ಲೂಟೂತ್ ಆನ್ ಆಗಿರಿಸಿಕೊಳ್ಳುವುದನ್ನು ನಿಮ್ಮ ಫೋನ್ ನೆನಪಿಸಿಕೊಳ್ಳುತ್ತದೆ. ಬ್ಲೂಟೂತ್ ಆನ್ ಆಗಿರಿಸಲು ನೀವು ಬಯಸದಿದ್ದರೆ ಅದನ್ನು ಆಫ್ ಮಾಡಿ." + + "ವೈ-ಫೈ ಮತ್ತು ಬ್ಲೂಟೂತ್ ಆನ್ ಆಗಿರುತ್ತದೆ" - "ಏರ್‌ಪ್ಲೇನ್ ಮೋಡ್‌ನಲ್ಲಿ ವೈಫೈ ಮತ್ತು ಬ್ಲೂಟೂತ್ ಆನ್ ಆಗಿರಿಸಿಕೊಳ್ಳುವುದನ್ನು ನಿಮ್ಮ ಫೋನ್ ನೆನಪಿಸಿಕೊಳ್ಳುತ್ತದೆ. ವೈಫೈ ಮತ್ತು ಬ್ಲೂಟೂತ್ ಆನ್ ಆಗಿರಿಸಲು ನೀವು ಬಯಸದಿದ್ದರೆ ಅವುಗಳನ್ನು ಆಫ್ ಮಾಡಿ." + + diff --git a/android/app/res/values-ko/strings.xml b/android/app/res/values-ko/strings.xml index 2a6bcea99de..e21a971d50b 100644 --- a/android/app/res/values-ko/strings.xml +++ b/android/app/res/values-ko/strings.xml @@ -130,9 +130,12 @@ "4GB보다 큰 파일은 전송할 수 없습니다" "블루투스에 연결" "비행기 모드에서 블루투스 사용 설정" - "블루투스를 켜진 상태로 유지하면 다음에 비행기 모드를 사용할 때도 블루투스 연결이 유지됩니다." + + "블루투스가 켜진 상태로 유지됨" - "휴대전화가 비행기 모드에서 블루투스를 켜진 상태로 유지합니다. 유지하지 않으려면 블루투스를 사용 중지하세요." + + "Wi-Fi 및 블루투스 계속 사용" - "휴대전화가 비행기 모드에서 Wi-Fi 및 블루투스를 켜진 상태로 유지합니다. 유지하지 않으려면 Wi-Fi와 블루투스를 사용 중지하세요." + + diff --git a/android/app/res/values-ky/strings.xml b/android/app/res/values-ky/strings.xml index 4f1f7a1826f..2241ee7d153 100644 --- a/android/app/res/values-ky/strings.xml +++ b/android/app/res/values-ky/strings.xml @@ -130,9 +130,12 @@ "4Гб чоң файлдарды өткөрүү мүмкүн эмес" "Bluetooth\'га туташуу" "Учак режиминде Bluetooth күйүк" - "Эгер Bluetooth күйүк бойдон калса, кийинки жолу учак режимине өткөнүңүздө телефонуңуз аны эстеп калат" + + "Bluetooth күйүк бойдон калат" - "Телефонуңуз учак режиминде Bluetooth\'га туташкан бойдон калат. Кааласаңыз, Bluetooth\'ду өчүрүп койсоңуз болот." + + "Wi-Fi менен Bluetooth күйүк бойдон калат" - "Телефонуңуз учак режиминде Wi‑Fi\'га жана Bluetooth\'га туташкан бойдон калат. Кааласаңыз, Wi-Fi менен Bluetooth\'ду өчүрүп койсоңуз болот." + + diff --git a/android/app/res/values-lo/strings.xml b/android/app/res/values-lo/strings.xml index 9c60428aa9e..eb805e312ac 100644 --- a/android/app/res/values-lo/strings.xml +++ b/android/app/res/values-lo/strings.xml @@ -130,9 +130,12 @@ "ບໍ່ສາມາດໂອນຍ້າຍໄຟລ໌ທີ່ໃຫຍກວ່າ 4GB ໄດ້" "ເຊື່ອມຕໍ່ກັບ Bluetooth" "ເປີດ Bluetooth ໃນໂໝດຢູ່ໃນຍົນ" - "ຫາກທ່ານເປີດ Bluetooth ປະໄວ້, ໂທລະສັບຂອງທ່ານຈະຈື່ວ່າຕ້ອງເປີດ Wi‑Fi ໃນເທື່ອຕໍ່ໄປທີ່ທ່ານຢູ່ໃນໂໝດຢູ່ໃນຍົນ" + + "Bluetooth ເປີດຢູ່" - "ໂທລະສັບຂອງທ່ານຈື່ວ່າຈະຕ້ອງເປີດ Bluetooth ປະໄວ້ໃນໂໝດຢູ່ໃນຍົນ. ປິດ Bluetooth ຫາກທ່ານບໍ່ຕ້ອງການໃຫ້ເປີດປະໄວ້." + + "Wi-Fi ແລະ Bluetooth ຈະເປີດປະໄວ້" - "ໂທລະສັບຂອງທ່ານຈື່ວ່າຈະຕ້ອງເປີດ Wi-Fi ແລະ Bluetooth ປະໄວ້ໃນໂໝດຢູ່ໃນຍົນ. ປິດ Wi-Fi ແລະ Bluetooth ຫາກທ່ານບໍ່ຕ້ອງການໃຫ້ເປີດປະໄວ້." + + diff --git a/android/app/res/values-lt/strings.xml b/android/app/res/values-lt/strings.xml index de0c13f5930..c72b5034136 100644 --- a/android/app/res/values-lt/strings.xml +++ b/android/app/res/values-lt/strings.xml @@ -130,9 +130,12 @@ "Negalima perkelti didesnių nei 4 GB failų" "Prisijungti prie „Bluetooth“" "„Bluetooth“ ryšys įjungtas lėktuvo režimu" - "Jei paliksite „Bluetooth“ ryšį įjungtą, telefonas, prisimins palikti jį įjungtą, kai kitą kartą įjungsite lėktuvo režimą" + + "„Bluetooth“ liks įjungtas" - "Telefonas prisimena, kad naudojant lėktuvo režimą reikia palikti įjungtą „Bluetooth“ ryšį. Išjunkite „Bluetooth“, jei nenorite, kad jis liktų įjungtas." + + "„Wi‑Fi“ ir „Bluetooth“ ryšys lieka įjungtas" - "Telefonas prisimena, kad lėktuvo režimu reikia palikti įjungtą „Wi‑Fi“ ir „Bluetooth“ ryšį. Išjunkite „Wi-Fi“ ir „Bluetooth“, jei nenorite, kad jie liktų įjungti." + + diff --git a/android/app/res/values-lv/strings.xml b/android/app/res/values-lv/strings.xml index eee75d98490..be0e6bd77fe 100644 --- a/android/app/res/values-lv/strings.xml +++ b/android/app/res/values-lv/strings.xml @@ -130,9 +130,12 @@ "Nevar pārsūtīt failus, kas lielāki par 4 GB." "Izveidot savienojumu ar Bluetooth" "Tehnoloģija Bluetooth lidojuma režīmā paliek ieslēgta" - "Ja Bluetooth savienojums paliks ieslēgts, tālrunī tas paliks ieslēgts arī nākamreiz, kad ieslēgsiet lidojuma režīmu." + + "Bluetooth savienojums joprojām ir ieslēgts" - "Lidojuma režīmā tālrunī joprojām būs ieslēgts Bluetooth savienojums. Izslēdziet Bluetooth savienojumu, ja nevēlaties, lai tas paliktu ieslēgts." + + "Wi-Fi savienojums un tehnoloģija Bluetooth paliek ieslēgta" - "Lidojuma režīmā tālrunī joprojām būs ieslēgti Wi-Fi un Bluetooth savienojumi. Izslēdziet Wi-Fi un Bluetooth savienojumus, ja nevēlaties, lai tie paliktu ieslēgti." + + diff --git a/android/app/res/values-mk/strings.xml b/android/app/res/values-mk/strings.xml index d7f99077e44..08262ad4386 100644 --- a/android/app/res/values-mk/strings.xml +++ b/android/app/res/values-mk/strings.xml @@ -130,9 +130,12 @@ "Не може да се пренесуваат датотеки поголеми од 4 GB" "Поврзи се со Bluetooth" "Вклучен Bluetooth во авионски режим" - "Ако го оставите Bluetooth вклучен, телефонот ќе запомни да го остави вклучен до следниот пат кога ќе бидете во авионски режим" + + "Bluetooth останува вклучен" - "Телефонот помни да го задржи Bluetooth вклучен во авионски режим. Исклучете го Bluetooth ако не сакате да остане вклучен." + + "Wi-Fi и Bluetooth остануваат вклучени" - "Телефонот помни да ги задржи Wi‑Fi и Bluetooth вклучени во авионски режим. Исклучете ги Wi-Fi и Bluetooth ако не сакате да бидат вклучени." + + diff --git a/android/app/res/values-ml/strings.xml b/android/app/res/values-ml/strings.xml index e0f76f43f2c..5c25b079044 100644 --- a/android/app/res/values-ml/strings.xml +++ b/android/app/res/values-ml/strings.xml @@ -130,9 +130,12 @@ "4GB-യിൽ കൂടുതലുള്ള ഫയലുകൾ കൈമാറാനാവില്ല" "Bluetooth-ലേക്ക് കണക്‌റ്റ് ചെയ്യുക" "ഫ്ലൈറ്റ് മോഡിൽ Bluetooth ഓണാണ്" - "Bluetooth ഓണാക്കി വച്ചാൽ, അടുത്ത തവണ നിങ്ങൾ ഫ്ലൈറ്റ് മോഡിൽ ആയിരിക്കുമ്പോൾ നിങ്ങളുടെ ഫോൺ അത് ഓണാക്കി വയ്ക്കാൻ ഓർക്കും" + + "Bluetooth ഓണാക്കിയ നിലയിൽ തുടരും" - "ഫ്ലൈറ്റ് മോഡിലായിരിക്കുമ്പോൾ Bluetooth ഓണാക്കി വയ്ക്കാൻ നിങ്ങളുടെ ഫോൺ ഓർമ്മിക്കുന്നു. Bluetooth ഓണാക്കി വയ്ക്കാൻ താൽപ്പര്യമില്ലെങ്കിൽ അത് ഓഫാക്കുക." + + "വൈഫൈ, Bluetooth എന്നിവ ഓണായ നിലയിൽ തുടരും" - "ഫ്ലൈറ്റ് മോഡിലായിരിക്കുമ്പോൾ വൈഫൈ, Bluetooth എന്നിവ ഓണാക്കി വയ്ക്കാൻ നിങ്ങളുടെ ഫോൺ ഓർമ്മിക്കുന്നു. വൈഫൈ, Bluetooth എന്നിവ ഓണാക്കി വയ്‌ക്കാൻ താൽപ്പര്യമില്ലെങ്കിൽ അവ ഓഫാക്കുക." + + diff --git a/android/app/res/values-mn/strings.xml b/android/app/res/values-mn/strings.xml index b39de67f03e..ee54f6b5513 100644 --- a/android/app/res/values-mn/strings.xml +++ b/android/app/res/values-mn/strings.xml @@ -130,9 +130,12 @@ "4ГБ-с дээш хэмжээтэй файлыг шилжүүлэх боломжгүй" "Bluetooth-тэй холбогдох" "Нислэгийн горимд Bluetooth асаалттай" - "Хэрэв та Bluetooth-г асаалттай байлгавал таныг дараагийн удаа нислэгийн горимд байх үед утас тань үүнийг асаалттай байлгахыг санана" + + "Bluetooth асаалттай хэвээр байна" - "Таны утас Bluetooth-г нислэгийн горимд асаалттай байлгахыг санана. Хэрэв та асаалттай байлгахыг хүсэхгүй байгаа бол Bluetooth-г унтрааж болно." + + "Wi-Fi болон Bluetooth асаалттай хэвээр байна" - "Таны утас Wi-Fi болон Bluetooth-г нислэгийн горимд асаалттай байлгахыг санана. Хэрэв та асаалттай байлгахыг хүсэхгүй байгаа бол Wi-Fi болон Bluetooth-г унтрааж болно." + + diff --git a/android/app/res/values-mr/strings.xml b/android/app/res/values-mr/strings.xml index f45a9a55dd6..a57e33d174b 100644 --- a/android/app/res/values-mr/strings.xml +++ b/android/app/res/values-mr/strings.xml @@ -130,9 +130,12 @@ "4 GB हून मोठ्या फाइल ट्रान्सफर करता येणार नाहीत" "ब्लूटूथशी कनेक्ट करा" "विमान मोडमध्ये ब्लूटूथ सुरू आहे" - "तुम्ही ब्लूटूथ सुरू ठेवल्यास, पुढील वेळी विमान मोडमध्ये असाल, तेव्हा तुमचा फोन ते सुरू ठेवण्याचे लक्षात ठेवेल" + + "ब्लूटूथ सुरू राहते" - "तुमचा फोन विमान मोडमध्ये ब्लूटूथ सुरू ठेवण्याचे लक्षात ठेवतो. तुम्हाला ब्लूटूथ सुरू ठेवायचे नसल्यास ते बंद करा." + + "वाय-फाय आणि ब्लूटूथ सुरू राहते" - "तुमचा फोन विमान मोडमध्ये वाय-फाय आणि ब्लूटूथ सुरू ठेवण्याचे लक्षात ठेवतो. तुम्हाला वाय-फाय आणि ब्लूटूथ सुरू ठेवायचे नसल्यास ते बंद करा." + + diff --git a/android/app/res/values-ms/strings.xml b/android/app/res/values-ms/strings.xml index 53064c86969..a78231e161b 100644 --- a/android/app/res/values-ms/strings.xml +++ b/android/app/res/values-ms/strings.xml @@ -130,9 +130,12 @@ "Fail lebih besar daripada 4GB tidak boleh dipindahkan" "Sambung ke Bluetooth" "Bluetooth dihidupkan dalam mod pesawat" - "Jika anda terus menghidupkan Bluetooth, telefon anda akan ingat untuk membiarkan Bluetooth hidup pada kali seterusnya telefon anda berada dalam mod pesawat" + + "Bluetooth kekal dihidupkan" - "Telefon anda diingatkan untuk terus menghidupkan Bluetooth dalam mod pesawat. Matikan Bluetooth jika anda tidak mahu Bluetooth sentiasa hidup." + + "Wi-Fi dan Bluetooth kekal dihidupkan" - "Telefon anda diingatkan untuk terus menghidupkan Wi-Fi dan Bluetooth dalam mod pesawat. Matikan Wi-Fi dan Bluetooth jika anda tidak mahu Wi-Fi dan Bluetooth sentiasa hidup." + + diff --git a/android/app/res/values-my/strings.xml b/android/app/res/values-my/strings.xml index fb9a38360b1..4861a13c8ed 100644 --- a/android/app/res/values-my/strings.xml +++ b/android/app/res/values-my/strings.xml @@ -130,9 +130,12 @@ "4GB ထက်ပိုကြီးသည့် ဖိုင်များကို လွှဲပြောင်းမရနိုင်ပါ" "ဘလူးတုသ်သို့ ချိတ်ဆက်ရန်" "လေယာဉ်ပျံမုဒ်တွင် ဘလူးတုသ် ပွင့်နေသည်" - "ဘလူးတုသ် ဆက်ဖွင့်ထားပါက နောက်တစ်ကြိမ်လေယာဉ်ပျံမုဒ် သုံးချိန်တွင် ၎င်းဆက်ဖွင့်ရန် သင့်ဖုန်းက မှတ်ထားမည်။" + + "ဘလူးတုသ် ဆက်ပွင့်နေသည်" - "လေယာဉ်ပျံမုဒ်သုံးစဉ် ဘလူးတုသ် ဆက်ဖွင့်ထားရန် သင့်ဖုန်းက မှတ်မိသည်။ ဘလူးတုသ် ဆက်ဖွင့်မထားလိုပါက ပိတ်နိုင်သည်။" + + "Wi-Fi နှင့် ဘလူးတုသ် ဆက်ဖွင့်ထားသည်" - "လေယာဉ်ပျံမုဒ်သုံးစဉ် Wi-Fi နှင့် ဘလူးတုသ် ဆက်ဖွင့်ထားရန် သင့်ဖုန်းက မှတ်မိသည်။ Wi-Fi နှင့် ဘလူးတုသ် ဆက်ဖွင့်မထားလိုပါက ပိတ်နိုင်သည်။" + + diff --git a/android/app/res/values-nb/strings.xml b/android/app/res/values-nb/strings.xml index 3ff0bbc8fad..b87195712e1 100644 --- a/android/app/res/values-nb/strings.xml +++ b/android/app/res/values-nb/strings.xml @@ -130,9 +130,12 @@ "Filer som er større enn 4 GB, kan ikke overføres" "Koble til Bluetooth" "Bluetooth er på i flymodus" - "Hvis du lar Bluetooth være på, husker telefonen dette til den neste gangen du bruker flymodus" + + "Bluetooth blir værende på" - "Telefonen husker at Bluetooth skal være på i flymodus. Slå av Bluetooth hvis du ikke vil at det skal være på." + + "Wifi og Bluetooth holdes påslått" - "Telefonen husker at wifi og Bluetooth skal være på i flymodus. Slå av wifi og Bluetooth hvis du ikke vil at de skal være på." + + diff --git a/android/app/res/values-ne/strings.xml b/android/app/res/values-ne/strings.xml index eccb49f4077..239a5c6b51a 100644 --- a/android/app/res/values-ne/strings.xml +++ b/android/app/res/values-ne/strings.xml @@ -130,9 +130,12 @@ "४ जि.बि. भन्दा ठूला फाइलहरूलाई स्थानान्तरण गर्न सकिँदैन" "ब्लुटुथमा कनेक्ट गर्नुहोस्" "हवाइजहाज मोडमा ब्लुटुथ अन राखियोस्" - "तपाईंले ब्लुटुथ अन राखिराख्नुभयो भने तपाईंले आफ्नो फोन अर्को पटक हवाइजहाज मोडमा लैजाँदा तपाईंको फोनले ब्लुटुथ अन राख्नु पर्ने कुरा याद गर्छ" + + "ब्लुटुथ अन रहन्छ" - "तपाईंको फोन अर्को पटक हवाइजहाज मोडमा लैजाँदा तपाईंको फोनले ब्लुटुथ अन राख्नु पर्ने कुरा याद गर्छ तपाईं ब्लुटुथ अन भइनरहोस् भन्ने चाहनुहुन्छ भने ब्लुटुथ अफ गर्नुहोस्।" + + "Wi-Fi र ब्लुटुथ अन रहिरहने छन्" - "हवाइजहाज मोडमा पनि तपाईंको फोनको Wi-Fi र ब्लुटुथ अन नै रहिरहने छन्। तपाईं Wi-Fi र ब्लुटुथ अन भइनरहोस् भन्ने चाहनुहुन्छ भने तिनलाई अफ गर्नुहोस्।" + + diff --git a/android/app/res/values-nl/strings.xml b/android/app/res/values-nl/strings.xml index da9a3110f37..170aefdf9f4 100644 --- a/android/app/res/values-nl/strings.xml +++ b/android/app/res/values-nl/strings.xml @@ -130,9 +130,12 @@ "Bestanden groter dan 4 GB kunnen niet worden overgedragen" "Verbinding maken met bluetooth" "Bluetooth aan in de vliegtuigmodus" - "Als je bluetooth laat aanstaan, onthoudt je telefoon dit en blijft bluetooth aanstaan als je de vliegtuigmodus weer aanzet" + + "Bluetooth blijft aan" - "Bluetooth op je telefoon blijft aan in de vliegtuigmodus. Zet bluetooth uit als je niet wilt dat dit aan blijft." + + "Wifi en bluetooth blijven aan" - "Wifi en bluetooth op je telefoon blijven aan in de vliegtuigmodus. Zet wifi en bluetooth uit als je niet wilt dat ze aan blijven." + + diff --git a/android/app/res/values-or/strings.xml b/android/app/res/values-or/strings.xml index 08e68d7097c..032412ec30c 100644 --- a/android/app/res/values-or/strings.xml +++ b/android/app/res/values-or/strings.xml @@ -130,9 +130,12 @@ "4GBରୁ ବଡ଼ ଫାଇଲ୍‌ଗୁଡ଼ିକୁ ଟ୍ରାନ୍ସଫର୍‌ କରାଯାଇପାରିବ ନାହିଁ" "ବ୍ଲୁଟୁଥ୍ ସହ ସଂଯୋଗ କରନ୍ତୁ" "ଏୟାରପ୍ଲେନ ମୋଡରେ ବ୍ଲୁଟୁଥ ଚାଲୁ ଅଛି" - "ଯଦି ଆପଣ ବ୍ଲୁଟୁଥକୁ ଚାଲୁ ରଖନ୍ତି, ତେବେ ଆପଣ ପରବର୍ତ୍ତୀ ଥର ଏୟାରପ୍ଲେନ ମୋଡରେ ଥିବା ସମୟରେ ଆପଣଙ୍କ ଫୋନ ଏହାକୁ ଚାଲୁ ରଖିବା ପାଇଁ ମନେ ରଖିବ" + + "ବ୍ଲୁଟୁଥ ଚାଲୁ ରହେ" - "ଆପଣଙ୍କ ଫୋନ ଏୟାରପ୍ଲେନ ମୋଡରେ ବ୍ଲୁଟୁଥକୁ ଚାଲୁ ରଖିବା ପାଇଁ ମନେ ରଖେ। ଯଦି ଆପଣ ବ୍ଲୁଟୁଥ ଚାଲୁ ରଖିବାକୁ ଚାହାଁନ୍ତି ନାହିଁ ତେବେ ଏହାକୁ ବନ୍ଦ କରନ୍ତୁ।" + + "ୱାଇ-ଫାଇ ଏବଂ ବ୍ଲୁଟୁଥ ଚାଲୁ ରହେ" - "ଆପଣଙ୍କ ଫୋନ ଏୟାରପ୍ଲେନ ମୋଡରେ ୱାଇ-ଫାଇ ଏବଂ ବ୍ଲୁଟୁଥକୁ ଚାଲୁ ରଖିବା ପାଇଁ ମନେ ରଖେ। ଯଦି ଆପଣ ୱାଇ-ଫାଇ ଏବଂ ବ୍ଲୁଟୁଥ ଚାଲୁ ରଖିବାକୁ ଚାହାଁନ୍ତି ନାହିଁ ତେବେ ସେଗୁଡ଼ିକୁ ବନ୍ଦ କରନ୍ତୁ।" + + diff --git a/android/app/res/values-pa/strings.xml b/android/app/res/values-pa/strings.xml index 84c78ced7cc..accc6fb93cb 100644 --- a/android/app/res/values-pa/strings.xml +++ b/android/app/res/values-pa/strings.xml @@ -130,9 +130,12 @@ "4GB ਤੋਂ ਜ਼ਿਆਦਾ ਵੱਡੀਆਂ ਫ਼ਾਈਲਾਂ ਨੂੰ ਟ੍ਰਾਂਸਫ਼ਰ ਨਹੀਂ ਕੀਤਾ ਜਾ ਸਕਦਾ" "ਬਲੂਟੁੱਥ ਨਾਲ ਕਨੈਕਟ ਕਰੋ" "ਹਵਾਈ-ਜਹਾਜ਼ ਮੋਡ ਵਿੱਚ ਬਲੂਟੁੱਥ ਚਾਲੂ ਹੈ" - "ਜੇ ਤੁਸੀਂ ਬਲੂਟੁੱਥ ਨੂੰ ਚਾਲੂ ਰੱਖਦੇ ਹੋ, ਤਾਂ ਅਗਲੀ ਵਾਰ ਤੁਹਾਡਾ ਫ਼ੋਨ ਹਵਾਈ-ਜਹਾਜ਼ ਮੋਡ ਵਿੱਚ ਹੋਣ \'ਤੇ ਤੁਹਾਡਾ ਫ਼ੋਨ ਇਸਨੂੰ ਚਾਲੂ ਰੱਖਣਾ ਯਾਦ ਰੱਖੇਗਾ" + + "ਬਲੂਟੁੱਥ ਚਾਲੂ ਰਹਿੰਦਾ ਹੈ" - "ਤੁਹਾਡਾ ਫ਼ੋਨ ਹਵਾਈ-ਜਹਾਜ਼ ਮੋਡ ਵਿੱਚ ਬਲੂਟੁੱਥ ਨੂੰ ਚਾਲੂ ਰੱਖਣਾ ਯਾਦ ਰੱਖਦਾ ਹੈ। ਜੇ ਤੁਸੀਂ ਇਸਨੂੰ ਚਾਲੂ ਨਹੀਂ ਰੱਖਣਾ ਚਾਹੁੰਦੇ, ਤਾਂ ਬਲੂਟੁੱਥ ਨੂੰ ਬੰਦ ਕਰੋ।" + + "ਵਾਈ-ਫਾਈ ਅਤੇ ਬਲੂਟੁੱਥ ਚਾਲੂ ਰਹਿੰਦੇ ਹਨ" - "ਤੁਹਾਡਾ ਫ਼ੋਨ ਹਵਾਈ-ਜਹਾਜ਼ ਮੋਡ ਵਿੱਚ ਵਾਈ-ਫਾਈ ਅਤੇ ਬਲੂਟੁੱਥ ਨੂੰ ਚਾਲੂ ਰੱਖਣਾ ਯਾਦ ਰੱਖਦਾ ਹੈ। ਜੇ ਤੁਸੀਂ ਇਨ੍ਹਾਂ ਨੂੰ ਚਾਲੂ ਨਹੀਂ ਰੱਖਣਾ ਚਾਹੁੰਦੇ, ਤਾਂ ਵਾਈ-ਫਾਈ ਅਤੇ ਬਲੂਟੁੱਥ ਨੂੰ ਬੰਦ ਕਰੋ।" + + diff --git a/android/app/res/values-pl/strings.xml b/android/app/res/values-pl/strings.xml index 1db2aa19cc5..2f35fbfc2f0 100644 --- a/android/app/res/values-pl/strings.xml +++ b/android/app/res/values-pl/strings.xml @@ -130,9 +130,12 @@ "Nie można przenieść plików przekraczających 4 GB" "Nawiązywanie połączeń przez Bluetooth" "Bluetooth włączony w trybie samolotowym" - "Jeśli pozostawisz włączony Bluetooth, telefon zachowa się podobnie przy kolejnym przejściu w tryb samolotowy" + + "Bluetooth pozostanie włączony" - "Bluetooth na telefonie pozostaje włączony w trybie samolotowym. Wyłącz Bluetooth, jeśli nie chcesz, żeby pozostawał włączony." + + "Wi-Fi i Bluetooth pozostają włączone" - "Wi-Fi i Bluetooth na telefonie pozostają włączone w trybie samolotowym. Wyłącz Wi-Fi i Bluetooth, jeśli nie chcesz, żeby funkcje te pozostawały włączone." + + diff --git a/android/app/res/values-pt-rPT/strings.xml b/android/app/res/values-pt-rPT/strings.xml index 35b530a2032..f0bd98677dc 100644 --- a/android/app/res/values-pt-rPT/strings.xml +++ b/android/app/res/values-pt-rPT/strings.xml @@ -130,9 +130,9 @@ "Não é possível transferir os ficheiros com mais de 4 GB." "Ligar ao Bluetooth" "Bluetooth ativado no modo de avião" - "Se mantiver o Bluetooth ativado, o telemóvel vai lembrar-se de o manter ativado da próxima vez que estiver no modo de avião" + "Se mantiver o Bluetooth ativado, o dispositivo vai lembrar-se de o manter ativado da próxima vez que estiver no modo de avião" "O Bluetooth mantém-se ativado" - "O seu telemóvel mantém o Bluetooth ativado no modo de avião. Desative o Bluetooth se não quiser que fique ativado." + "O seu dispositivo lembra-se de manter o Bluetooth ativado no modo de avião. Desative o Bluetooth se não quiser que fique ativado." "O Wi-Fi e o Bluetooth mantêm-se ativados" - "O seu telemóvel mantém o Wi-Fi e o Bluetooth ativados no modo de avião. Desative o Wi-Fi e o Bluetooth se não quiser que fiquem ativados." + "O seu dispositivo lembra-se de manter o Wi-Fi e o Bluetooth ativados no modo de avião. Desative o Wi-Fi e o Bluetooth se não quiser que fiquem ativados." diff --git a/android/app/res/values-pt/strings.xml b/android/app/res/values-pt/strings.xml index b7e878172a2..c8dbf2b569f 100644 --- a/android/app/res/values-pt/strings.xml +++ b/android/app/res/values-pt/strings.xml @@ -130,9 +130,12 @@ "Não é possível transferir arquivos maiores que 4 GB" "Conectar ao Bluetooth" "Bluetooth ativado no modo avião" - "Se você escolher manter o Bluetooth ativado, essa configuração vai ser aplicada na próxima vez que usar o modo avião" + + "O Bluetooth fica ativado" - "O smartphone vai manter o Bluetooth ativado no modo avião. Ele pode ser desativado manualmente se você preferir." + + "O Wi-Fi e o Bluetooth ficam ativados" - "O smartphone vai manter o Wi-Fi e o Bluetooth ativados no modo avião. Eles podem ser desativados manualmente se você preferir." + + diff --git a/android/app/res/values-ro/strings.xml b/android/app/res/values-ro/strings.xml index 42d968415ad..f2807c6c355 100644 --- a/android/app/res/values-ro/strings.xml +++ b/android/app/res/values-ro/strings.xml @@ -130,9 +130,12 @@ "Fișierele mai mari de 4 GB nu pot fi transferate" "Conectează-te la Bluetooth" "Bluetooth activat în modul Avion" - "Dacă păstrezi Bluetooth activat, telefonul tău va reține să-l păstreze activat data viitoare când ești în modul Avion" + + "Bluetooth rămâne activat" - "Telefonul reține să păstreze Bluetooth activat în modul Avion. Dezactivează Bluetooth dacă nu vrei să rămână activat." + + "Wi-Fi și Bluetooth rămân activate" - "Telefonul reține să păstreze funcțiile Wi-Fi și Bluetooth activate în modul Avion. Dezactivează Wi-Fi și Bluetooth dacă nu vrei să rămână activate." + + diff --git a/android/app/res/values-ru/strings.xml b/android/app/res/values-ru/strings.xml index 9519a3a37f1..f3a7ff53948 100644 --- a/android/app/res/values-ru/strings.xml +++ b/android/app/res/values-ru/strings.xml @@ -130,9 +130,12 @@ "Можно перенести только файлы размером до 4 ГБ." "Подключиться по Bluetooth" "Функция Bluetooth будет включена в режиме полета" - "Если не отключить функцию Bluetooth, в следующий раз она останется включенной в режиме полета." + + "Функция Bluetooth остается включенной" - "Функция Bluetooth останется включенной в режиме полета. Вы можете отключить ее, если хотите." + + "Функции Wi‑Fi и Bluetooth остаются включенными" - "Wi‑Fi и Bluetooth останутся включенными в режиме полета. Вы можете отключить их, если хотите." + + diff --git a/android/app/res/values-si/strings.xml b/android/app/res/values-si/strings.xml index 2757685fa62..e560e6bb315 100644 --- a/android/app/res/values-si/strings.xml +++ b/android/app/res/values-si/strings.xml @@ -130,9 +130,12 @@ "4GBට වඩා විශාල ගොනු මාරු කළ නොහැකිය" "බ්ලූටූත් වෙත සබඳින්න" "අහස්යානා ආකාරයේ බ්ලූටූත් ක්‍රියාත්මකයි" - "ඔබ බ්ලූටූත් ක්‍රියාත්මක කර තබා ගන්නේ නම්, ඔබ අහස්යානා ආකාරයේ සිටින මීළඟ වතාවේ එය ක්‍රියාත්මක කිරීමට ඔබේ දුරකථනයට මතක තිබෙනු ඇත." + + "බ්ලූටූත් ක්‍රියාත්මකව පවතී" - "ඔබේ දුරකථනයට අහස්යානා ආකාරයේ බ්ලූටූත් ක්‍රියාත්මකව තබා ගැනීමට මතකයි. ඔබට බ්ලූටූත් ක්‍රියාත්මක වීමට අවශ්‍ය නොවේ නම් එය ක්‍රියාවිරහිත කරන්න." + + "Wi-Fi සහ බ්ලූටූත් ක්‍රියාත්මකව පවතී" - "ඔබේ දුරකථනයට අහස්යානා ආකාරයේ Wi-Fi සහ බ්ලූටූත් ක්‍රියාත්මකව තබා ගැනීමට මතකයි. Wi-Fi සහ බ්ලූටූත් ඒවා ක්‍රියාත්මක වීමට ඔබට අවශ්‍ය නැතිනම් ක්‍රියා විරහිත කරන්න." + + diff --git a/android/app/res/values-sk/strings.xml b/android/app/res/values-sk/strings.xml index 4b1c9782df2..b127a82d3ef 100644 --- a/android/app/res/values-sk/strings.xml +++ b/android/app/res/values-sk/strings.xml @@ -130,9 +130,12 @@ "Súbory väčšie ako 4 GB sa nedajú preniesť" "Pripojiť k zariadeniu Bluetooth" "Rozhranie Bluetooth bude v režime v lietadle zapnuté" - "Ak ponecháte rozhranie Bluetooth zapnuté, váš telefón si zapamätá, že ho má ponechať zapnuté pri ďalšom aktivovaní režimu v lietadle" + + "Rozhranie Bluetooth zostane zapnuté" - "Telefón si pamätá, aby v režime v lietadle nevypínal rozhranie Bluetooth. Ak ho nechcete ponechať zapnuté, vypnite ho." + + "Wi‑Fi a Bluetooth zostanú zapnuté" - "Telefón si pamätá, aby v režime v lietadle nevypínal Wi‑Fi ani Bluetooth. Ak ich nechcete ponechať zapnuté, vypnite ich." + + diff --git a/android/app/res/values-sl/strings.xml b/android/app/res/values-sl/strings.xml index 696e4260fc7..5ad91342a33 100644 --- a/android/app/res/values-sl/strings.xml +++ b/android/app/res/values-sl/strings.xml @@ -130,9 +130,12 @@ "Datotek, večjih od 4 GB, ni mogoče prenesti" "Povezovanje z Bluetoothom" "Bluetooth je vklopljen v načinu za letalo" - "Če pustite Bluetooth vklopljen, bo telefon ob naslednjem preklopu na način za letalo pustil Bluetooth vklopljen." + + "Bluetooth ostane vklopljen" - "Telefon v načinu za letalo pusti Bluetooth vklopljen. Če ne želite, da ostane vklopljen, izklopite vmesnik Bluetooth." + + "Wi-Fi in Bluetooth ostaneta vklopljena" - "Telefon v načinu za letalo pusti Wi-Fi in Bluetooth vklopljena. Če ne želite, da Wi-Fi in Bluetooth ostaneta vklopljena, ju izklopite." + + diff --git a/android/app/res/values-sq/strings.xml b/android/app/res/values-sq/strings.xml index 16a94408ba8..79f548588b3 100644 --- a/android/app/res/values-sq/strings.xml +++ b/android/app/res/values-sq/strings.xml @@ -130,9 +130,12 @@ "Skedarët më të mëdhenj se 4 GB nuk mund të transferohen" "Lidhu me Bluetooth" "Bluetooth-i aktiv në modalitetin e aeroplanit" - "Nëse e mban Bluetooth-in të aktivizuar, telefoni yt do të kujtohet ta mbajë atë të aktivizuar herën tjetër kur të jesh në modalitetin e aeroplanit" + + "Bluetooth qëndron i aktivizuar" - "Telefoni yt kujtohet që ta mbajë Bluetooth-in të aktivizuar në modalitetin e aeroplanit. Çaktivizo Bluetooth-in nëse nuk dëshiron që të qëndrojë i aktivizuar." + + "Wi-Fi dhe Bluetooth-i qëndrojnë aktivë" - "Telefoni yt kujtohet që ta mbajë Wi-Fi dhe Bluetooth-in të aktivizuar në modalitetin e aeroplanit. Çaktivizo Wi-Fi dhe Bluetooth-in nëse nuk dëshiron që të qëndrojnë aktivë." + + diff --git a/android/app/res/values-sr/strings.xml b/android/app/res/values-sr/strings.xml index 1ead9d5024b..44277d78622 100644 --- a/android/app/res/values-sr/strings.xml +++ b/android/app/res/values-sr/strings.xml @@ -130,9 +130,12 @@ "Не могу да се преносе датотеке веће од 4 GB" "Повежи са Bluetooth-ом" "Bluetooth је укључен у режиму рада у авиону" - "Ако одлучите да не искључујете Bluetooth, телефон ће запамтити да га не искључује следећи пут када будете у режиму рада у авиону" + + "Bluetooth се не искључује" - "Телефон памти да не треба да искључује Bluetooth у режиму рада у авиону. Искључите Bluetooth ако не желите да остане укључен." + + "WiFi и Bluetooth остају укључени" - "Телефон памти да не треба да искључује WiFi и Bluetooth у режиму рада у авиону. Искључите WiFi и Bluetooth ако не желите да остану укључени." + + diff --git a/android/app/res/values-sv/strings.xml b/android/app/res/values-sv/strings.xml index 12678538125..e46be12a9e7 100644 --- a/android/app/res/values-sv/strings.xml +++ b/android/app/res/values-sv/strings.xml @@ -130,9 +130,12 @@ "Det går inte att överföra filer som är större än 4 GB" "Anslut till Bluetooth" "Håll Bluetooth aktiverat i flygplansläge" - "Om du håller wifi aktiverat kommer telefonen ihåg att hålla det aktiverat nästa gång du använder flygplansläge." + + "Bluetooth förblir aktiverat" - "Telefonen kommer ihåg att hålla Bluetooth aktiverat i flygplansläge. Inaktivera Bluetooth om du inte vill att det ska hållas aktiverat." + + "Wifi och Bluetooth ska vara aktiverade" - "Telefonen kommer ihåg att hålla wifi och Bluetooth aktiverade i flygplansläge. Du kan inaktivera wifi och Bluetooth om du inte vill hålla dem aktiverade." + + diff --git a/android/app/res/values-sw/strings.xml b/android/app/res/values-sw/strings.xml index 4ebf5cccfc2..8a83f0f6b12 100644 --- a/android/app/res/values-sw/strings.xml +++ b/android/app/res/values-sw/strings.xml @@ -130,9 +130,12 @@ "Haiwezi kutuma faili zinazozidi GB 4" "Unganisha kwenye Bluetooth" "Bluetooth itawashwa katika hali ya ndegeni" - "Usipozima Bluetooth, simu yako itakumbuka kuiwasha wakati mwingine unapokuwa katika hali ya ndegeni" + + "Bluetooth itaendelea kuwaka" - "Simu yako itaendelea kuwasha Bluetooth katika hali ya ndegeni. Zima Bluetooth iwapo hutaki iendelee kuwaka." + + "Wi-Fi na Bluetooth zitaendelea kuwaka" - "Simu yako itaendelea kuwasha Wi-Fi na Bluetooth ukiwa katika hali ya ndegeni. Zima Wi-Fi na Bluetooth ikiwa hutaki ziendelee kuwaka." + + diff --git a/android/app/res/values-ta/strings.xml b/android/app/res/values-ta/strings.xml index ffd800cf343..76e95005131 100644 --- a/android/app/res/values-ta/strings.xml +++ b/android/app/res/values-ta/strings.xml @@ -130,9 +130,12 @@ "4ஜி.பை.க்கு மேலிருக்கும் ஃபைல்களை இடமாற்ற முடியாது" "புளூடூத் உடன் இணை" "விமானப் பயன்முறையில் புளூடூத்தை இயக்குதல்" - "புளூடூத்தை இயக்கத்தில் வைத்திருந்தால், அடுத்த முறை நீங்கள் விமானப் பயன்முறையைப் பயன்படுத்தும்போது உங்கள் மொபைல் புளூடூத்தை இயக்கத்தில் வைக்கும்" + + "புளூடூத் இயக்கத்திலேயே இருக்கும்" - "விமானப் பயன்முறையில் புளூடூத்தை உங்கள் மொபைல் இயக்கத்திலேயே வைத்திருக்கும். புளூடூத்தை இயக்க விரும்பவில்லை என்றால் அதை முடக்கவும்." + + "வைஃபையும் புளூடூத்தும் இயக்கத்திலேயே இருத்தல்" - "விமானப் பயன்முறையில் வைஃபையையும் புளூடூத்தையும் உங்கள் மொபைல் இயக்கத்திலேயே வைத்திருக்கும். வைஃபை மற்றும் புளூடூத்தை இயக்க விரும்பவில்லை என்றால் அவற்றை முடக்கவும்." + + diff --git a/android/app/res/values-te/strings.xml b/android/app/res/values-te/strings.xml index 513e12b95e9..488d53f8992 100644 --- a/android/app/res/values-te/strings.xml +++ b/android/app/res/values-te/strings.xml @@ -130,9 +130,12 @@ "4GB కన్నా పెద్ద ఫైళ్లు బదిలీ చేయబడవు" "బ్లూటూత్‌కు కనెక్ట్ చేయి" "విమానం మోడ్‌లో బ్లూటూత్ ఆన్ చేయబడింది" - "మీరు బ్లూటూత్‌ను ఆన్‌లో ఉంచినట్లయితే, మీరు తదుపరిసారి విమానం మోడ్‌లో ఉన్నప్పుడు దాన్ని ఆన్‌లో ఉంచాలని మీ ఫోన్ గుర్తుంచుకుంటుంది" + + "బ్లూటూత్ ఆన్‌లో ఉంటుంది" - "విమానం మోడ్‌లో బ్లూటూత్ ఆన్‌లో ఉంచాలని మీ ఫోన్ గుర్తుంచుకుంటుంది. బ్లూటూత్ ఆన్‌లో ఉండకూడదనుకుంటే దాన్ని ఆఫ్ చేయండి." + + "Wi-Fi, బ్లూటూత్ ఆన్‌లో ఉంటాయి" - "మీ ఫోన్ విమానం మోడ్‌లో Wi‑Fiని, బ్లూటూత్‌ని ఆన్‌లో ఉంచాలని గుర్తుంచుకుంటుంది. Wi-Fi, బ్లూటూత్ ఆన్‌లో ఉండకూడదనుకుంటే వాటిని ఆఫ్ చేయండి." + + diff --git a/android/app/res/values-th/strings.xml b/android/app/res/values-th/strings.xml index 91763b102a0..55c465d1196 100644 --- a/android/app/res/values-th/strings.xml +++ b/android/app/res/values-th/strings.xml @@ -130,9 +130,12 @@ "โอนไฟล์ที่มีขนาดใหญ่กว่า 4 GB ไม่ได้" "เชื่อมต่อบลูทูธ" "บลูทูธเปิดอยู่ในโหมดบนเครื่องบิน" - "หากเปิดบลูทูธไว้ โทรศัพท์จะจำว่าต้องเปิดบลูทูธในครั้งถัดไปที่คุณอยู่ในโหมดบนเครื่องบิน" + + "บลูทูธเปิดอยู่" - "โทรศัพท์จำว่าจะต้องเปิดบลูทูธไว้ในโหมดบนเครื่องบิน ปิดบลูทูธหากคุณไม่ต้องการให้เปิดไว้" + + "Wi-Fi และบลูทูธยังเปิดอยู่" - "โทรศัพท์จำว่าจะต้องเปิด Wi-Fi และบลูทูธไว้ในโหมดบนเครื่องบิน ปิด Wi-Fi และบลูทูธหากคุณไม่ต้องการให้เปิดไว้" + + diff --git a/android/app/res/values-tl/strings.xml b/android/app/res/values-tl/strings.xml index 93c6a90be2f..cbded17d4fa 100644 --- a/android/app/res/values-tl/strings.xml +++ b/android/app/res/values-tl/strings.xml @@ -130,9 +130,12 @@ "Hindi maililipat ang mga file na mas malaki sa 4GB" "Kumonekta sa Bluetooth" "Naka-on ang Bluetooth sa airplane mode" - "Kung papanatilihin mong naka-on ang Bluetooth, tatandaan ng iyong telepono na panatilihin itong naka-on sa susunod na nasa airplane mode ka" + + "Mananatiling naka-on ang Bluetooth" - "Tinatandaan ng iyong telepono na panatilihing naka-on ang Bluetooth habang nasa airplane mode. I-off ang Bluetooth kung ayaw mo itong manatiling naka-on." + + "Mananatiling naka-on ang Wi-Fi at Bluetooth" - "Tinatandaan ng iyong telepono na panatilihing naka-on ang Wi-Fi at Bluetooth habang nasa airplane mode. I-off ang Wi-Fi at Bluetooth kung ayaw mong manatiling naka-on ang mga ito." + + diff --git a/android/app/res/values-tr/strings.xml b/android/app/res/values-tr/strings.xml index c1a650f337c..60ae75f5ba2 100644 --- a/android/app/res/values-tr/strings.xml +++ b/android/app/res/values-tr/strings.xml @@ -130,9 +130,12 @@ "4 GB\'tan büyük dosyalar aktarılamaz" "Bluetooth\'a bağlan" "Uçak modundayken Bluetooth açık" - "Kablosuz bağlantıyı açık tutarsanız telefonunuz, daha sonra tekrar uçak modunda olduğunuzda kablosuz bağlantıyı açık tutar" + + "Bluetooth açık kalır" - "Telefonunuz, uçak modundayken Bluetooth\'u açık tutmayı hatırlar. Açık kalmasını istemiyorsanız Bluetooth\'u kapatın." + + "Kablosuz bağlantı ve Bluetooth açık kalır" - "Telefonunuz, uçak modundayken kablosuz bağlantıyı ve Bluetooth\'u açık tutmayı hatırlar. Açık kalmasını istemiyorsanız kablosuz bağlantıyı ve Bluetooth\'u kapatın." + + diff --git a/android/app/res/values-uk/strings.xml b/android/app/res/values-uk/strings.xml index 348ae4c3adb..15698f516f3 100644 --- a/android/app/res/values-uk/strings.xml +++ b/android/app/res/values-uk/strings.xml @@ -130,9 +130,12 @@ "Не можна перенести файли, більші за 4 ГБ" "Підключитися до Bluetooth" "Bluetooth увімкнено в режимі польоту" - "Якщо ви не вимкнете Bluetooth на телефоні, ця функція залишатиметься ввімкненою під час наступного використання режиму польоту" + + "Bluetooth не буде вимкнено" - "У режимі польоту функція Bluetooth на телефоні залишатиметься ввімкненою. За бажання її можна вимкнути." + + "Wi-Fi і Bluetooth залишаються ввімкненими" - "У режимі польоту функції Wi-Fi і Bluetooth на телефоні залишатимуться ввімкненими. За бажання їх можна вимкнути." + + diff --git a/android/app/res/values-ur/strings.xml b/android/app/res/values-ur/strings.xml index c8d8480f46f..d0a98565193 100644 --- a/android/app/res/values-ur/strings.xml +++ b/android/app/res/values-ur/strings.xml @@ -130,9 +130,12 @@ "‏4GB سے بڑی فائلیں منتقل نہیں کی جا سکتیں" "بلوٹوتھ سے منسلک کریں" "ہوائی جہاز وضع میں بلوٹوتھ آن ہے" - "اگر آپ بلوٹوتھ کو آن رکھتے ہیں تو آپ کا فون آپ کے اگلی مرتبہ ہوائی جہاز وضع میں ہونے پر اسے آن رکھنا یاد رکھے گا" + + "بلوٹوتھ آن رہتا ہے" - "آپ کا فون ہوائی جہاز وضع میں بلوٹوتھ کو آن رکھنا یاد رکھتا ہے۔ اگر آپ نہیں چاہتے ہیں کہ بلوٹوتھ آن رہے تو اسے آف کریں۔" + + "‏Wi-Fi اور بلوٹوتھ آن رہنے دیں" - "‏آپ کا فون ہوائی جہاز وضع میں Wi-Fi اور بلوٹوتھ کو آن رکھنا یاد رکھتا ہے۔ اگر آپ نہیں چاہتے ہیں کہ Wi-Fi اور بلوٹوتھ آن رہیں تو انہیں آف کریں۔" + + diff --git a/android/app/res/values-uz/strings.xml b/android/app/res/values-uz/strings.xml index f0f22bd7ac3..057813aa624 100644 --- a/android/app/res/values-uz/strings.xml +++ b/android/app/res/values-uz/strings.xml @@ -130,9 +130,12 @@ "4 GBdan katta hajmli videolar o‘tkazilmaydi" "Bluetoothga ulanish" "Bluetooth parvoz rejimida yoniq" - "Bluetooth yoniq qolsa, telefon keyingi safar parvoz rejimida ham uni yoniq qoldiradi." + + "Bluetooth yoniq turadi" - "Telefoningiz parvoz rejimida Bluetooth yoqilganini eslab qoladi. Yoniq qolmasligi uchun Bluetooth aloqasini oʻchiring." + + "Wi-Fi va Bluetooth yoniq qoladi" - "Telefoningiz parvoz rejimida Wi‑Fi va Bluetooth yoqilganini eslab qoladi. Yoniq qolmasligi uchun Wi-Fi va Bluetooth aloqasini oʻchiring." + + diff --git a/android/app/res/values-vi/strings.xml b/android/app/res/values-vi/strings.xml index 55ceb7c126a..b3cef943ef5 100644 --- a/android/app/res/values-vi/strings.xml +++ b/android/app/res/values-vi/strings.xml @@ -130,9 +130,12 @@ "Không thể chuyển những tệp lớn hơn 4 GB" "Kết nối với Bluetooth" "Bluetooth đang bật ở chế độ trên máy bay" - "Nếu bạn không tắt Bluetooth, điện thoại sẽ luôn bật Bluetooth vào lần tiếp theo bạn dùng chế độ trên máy bay" + + "Bluetooth luôn bật" - "Điện thoại của bạn sẽ luôn bật Bluetooth ở chế độ trên máy bay. Nếu không muốn như vậy thì bạn có thể tắt Bluetooth." + + "Wi-Fi và Bluetooth vẫn đang bật" - "Điện thoại của bạn sẽ luôn bật Wi-Fi và Bluetooth ở chế độ trên máy bay. Tắt Wi-Fi và Bluetooth nếu bạn không muốn tiếp tục bật." + + diff --git a/android/app/res/values-zh-rCN/strings.xml b/android/app/res/values-zh-rCN/strings.xml index 05bc8d23ad5..1262f0ea21c 100644 --- a/android/app/res/values-zh-rCN/strings.xml +++ b/android/app/res/values-zh-rCN/strings.xml @@ -130,9 +130,12 @@ "无法传输 4GB 以上的文件" "连接到蓝牙" "在飞行模式下蓝牙保持开启状态" - "如果您不关闭蓝牙,那么您下次进入飞行模式时手机将记住保持开启蓝牙" + + "蓝牙保持开启状态" - "在飞行模式下手机将记住保持开启蓝牙。如果您不想保持开启和蓝牙,请关闭蓝牙。" + + "WLAN 和蓝牙保持开启状态" - "在飞行模式下手机将记住保持开启 WLAN 和蓝牙。如果您不想保持开启 WLAN 和蓝牙,请关闭 WLAN 和蓝牙。" + + diff --git a/android/app/res/values-zh-rHK/strings.xml b/android/app/res/values-zh-rHK/strings.xml index 4ae1ceedeaa..8275cef234d 100644 --- a/android/app/res/values-zh-rHK/strings.xml +++ b/android/app/res/values-zh-rHK/strings.xml @@ -130,9 +130,12 @@ "無法轉移 4 GB 以上的檔案" "連接藍牙" "在飛航模式中保持藍牙開啟" - "如果你不關閉藍牙,下次手機進入飛行模式時,藍牙將保持開啟" + + "保持藍牙連線" - "手機會記得在飛行模式下保持藍牙開啟。如果你不希望保持開啟,請關閉藍牙。" + + "Wi-Fi 和藍牙保持開啟" - "手機會記得在飛行模式下保持 Wi-Fi 及藍牙開啟。如果你不希望保持開啟,請關閉 Wi-Fi 及藍牙。" + + diff --git a/android/app/res/values-zh-rTW/strings.xml b/android/app/res/values-zh-rTW/strings.xml index 9626544969d..e3ab7f9277c 100644 --- a/android/app/res/values-zh-rTW/strings.xml +++ b/android/app/res/values-zh-rTW/strings.xml @@ -130,9 +130,12 @@ "無法轉移大於 4GB 的檔案" "使用藍牙連線" "在飛航模式下保持藍牙開啟狀態" - "如果不關閉藍牙,下次手機進入飛航模式時,藍牙將保持開啟" + + "藍牙會保持開啟狀態" - "手機會記得在飛航模式下保持藍牙開啟。如果不要保持開啟,請關閉藍牙。" + + "Wi-Fi 和藍牙會保持開啟狀態" - "手機會記得在飛航模式下保持 Wi-Fi 和藍牙開啟。如果不要保持開啟,請關閉 Wi-Fi 和藍牙。" + + diff --git a/android/app/res/values-zu/strings.xml b/android/app/res/values-zu/strings.xml index 3d6d007846f..3949f2ee5ce 100644 --- a/android/app/res/values-zu/strings.xml +++ b/android/app/res/values-zu/strings.xml @@ -130,9 +130,12 @@ "Amafayela amakhulu kuno-4GB awakwazi ukudluliselwa" "Xhumeka ku-Bluetooth" "I-Bluetooth ivuliwe kumodi yendiza" - "Uma ugcina i-Wi‑Fi ivuliwe, ifoni yakho izokhumbula ukuyigcina ivuliwe ngesikhathi esilandelayo uma ukumodi yendiza." + + "I-Bluetooth ihlala ivuliwe" - "Ifoni yakho ikhumbula ukugcina i-Bluetooth ivuliwe kumodi yendiza. Vala i-Bluetooth uma ungafuni ukuthi ihlale ivuliwe." + + "I-Wi-Fi ne-Bluetooth kuhlala kuvuliwe" - "Ifoni yakho ikhumbula ukugcina i-Wi-Fi ne-Bluetooth kuvuliwe kumodi yendiza. Vala i-Wi-Fi ne-Bluetooth uma ungafuni ukuthi ihlale ivuliwe." + + -- GitLab From 85fdd54fbf5b636efc58c6648934cf5575a247c0 Mon Sep 17 00:00:00 2001 From: Bill Yi Date: Tue, 16 May 2023 14:34:03 -0700 Subject: [PATCH 0075/2405] Import translations. DO NOT MERGE ANYWHERE Auto-generated-cl: translation import Change-Id: I1deec78d297b64d87c15935ce2e6d51f13118dc0 --- android/app/res/values-af/strings.xml | 9 ++++++--- android/app/res/values-am/strings.xml | 9 ++++++--- android/app/res/values-ar/strings.xml | 9 ++++++--- android/app/res/values-as/strings.xml | 9 ++++++--- android/app/res/values-az/strings.xml | 9 ++++++--- android/app/res/values-b+sr+Latn/strings.xml | 9 ++++++--- android/app/res/values-be/strings.xml | 9 ++++++--- android/app/res/values-bg/strings.xml | 9 ++++++--- android/app/res/values-bn/strings.xml | 9 ++++++--- android/app/res/values-bs/strings.xml | 9 ++++++--- android/app/res/values-ca/strings.xml | 9 ++++++--- android/app/res/values-cs/strings.xml | 9 ++++++--- android/app/res/values-da/strings.xml | 9 ++++++--- android/app/res/values-de/strings.xml | 9 ++++++--- android/app/res/values-el/strings.xml | 9 ++++++--- android/app/res/values-en-rAU/strings.xml | 9 ++++++--- android/app/res/values-en-rCA/strings.xml | 6 +++--- android/app/res/values-en-rGB/strings.xml | 9 ++++++--- android/app/res/values-en-rIN/strings.xml | 9 ++++++--- android/app/res/values-en-rXC/strings.xml | 6 +++--- android/app/res/values-es-rUS/strings.xml | 9 ++++++--- android/app/res/values-es/strings.xml | 9 ++++++--- android/app/res/values-et/strings.xml | 9 ++++++--- android/app/res/values-eu/strings.xml | 9 ++++++--- android/app/res/values-fa/strings.xml | 9 ++++++--- android/app/res/values-fi/strings.xml | 9 ++++++--- android/app/res/values-fr-rCA/strings.xml | 9 ++++++--- android/app/res/values-fr/strings.xml | 9 ++++++--- android/app/res/values-gl/strings.xml | 9 ++++++--- android/app/res/values-gu/strings.xml | 9 ++++++--- android/app/res/values-hi/strings.xml | 9 ++++++--- android/app/res/values-hr/strings.xml | 9 ++++++--- android/app/res/values-hu/strings.xml | 9 ++++++--- android/app/res/values-hy/strings.xml | 9 ++++++--- android/app/res/values-in/strings.xml | 9 ++++++--- android/app/res/values-is/strings.xml | 9 ++++++--- android/app/res/values-it/strings.xml | 6 +++--- android/app/res/values-iw/strings.xml | 9 ++++++--- android/app/res/values-ja/strings.xml | 9 ++++++--- android/app/res/values-ka/strings.xml | 9 ++++++--- android/app/res/values-kk/strings.xml | 9 ++++++--- android/app/res/values-km/strings.xml | 9 ++++++--- android/app/res/values-kn/strings.xml | 11 +++++++---- android/app/res/values-ko/strings.xml | 9 ++++++--- android/app/res/values-ky/strings.xml | 9 ++++++--- android/app/res/values-lo/strings.xml | 9 ++++++--- android/app/res/values-lt/strings.xml | 9 ++++++--- android/app/res/values-lv/strings.xml | 9 ++++++--- android/app/res/values-mk/strings.xml | 9 ++++++--- android/app/res/values-ml/strings.xml | 9 ++++++--- android/app/res/values-mn/strings.xml | 9 ++++++--- android/app/res/values-mr/strings.xml | 9 ++++++--- android/app/res/values-ms/strings.xml | 9 ++++++--- android/app/res/values-my/strings.xml | 9 ++++++--- android/app/res/values-nb/strings.xml | 9 ++++++--- android/app/res/values-ne/strings.xml | 9 ++++++--- android/app/res/values-nl/strings.xml | 9 ++++++--- android/app/res/values-or/strings.xml | 9 ++++++--- android/app/res/values-pa/strings.xml | 9 ++++++--- android/app/res/values-pl/strings.xml | 9 ++++++--- android/app/res/values-pt-rPT/strings.xml | 6 +++--- android/app/res/values-pt/strings.xml | 9 ++++++--- android/app/res/values-ro/strings.xml | 9 ++++++--- android/app/res/values-ru/strings.xml | 9 ++++++--- android/app/res/values-si/strings.xml | 9 ++++++--- android/app/res/values-sk/strings.xml | 9 ++++++--- android/app/res/values-sl/strings.xml | 9 ++++++--- android/app/res/values-sq/strings.xml | 9 ++++++--- android/app/res/values-sr/strings.xml | 9 ++++++--- android/app/res/values-sv/strings.xml | 9 ++++++--- android/app/res/values-sw/strings.xml | 9 ++++++--- android/app/res/values-ta/strings.xml | 9 ++++++--- android/app/res/values-te/strings.xml | 9 ++++++--- android/app/res/values-th/strings.xml | 9 ++++++--- android/app/res/values-tl/strings.xml | 9 ++++++--- android/app/res/values-tr/strings.xml | 9 ++++++--- android/app/res/values-uk/strings.xml | 9 ++++++--- android/app/res/values-ur/strings.xml | 9 ++++++--- android/app/res/values-uz/strings.xml | 9 ++++++--- android/app/res/values-vi/strings.xml | 9 ++++++--- android/app/res/values-zh-rCN/strings.xml | 9 ++++++--- android/app/res/values-zh-rHK/strings.xml | 9 ++++++--- android/app/res/values-zh-rTW/strings.xml | 9 ++++++--- android/app/res/values-zu/strings.xml | 9 ++++++--- 84 files changed, 493 insertions(+), 253 deletions(-) diff --git a/android/app/res/values-af/strings.xml b/android/app/res/values-af/strings.xml index b48fae73814..892d9e29243 100644 --- a/android/app/res/values-af/strings.xml +++ b/android/app/res/values-af/strings.xml @@ -130,9 +130,12 @@ "Lêers groter as 4 GB kan nie oorgedra word nie" "Koppel aan Bluetooth" "Bluetooth is aan in vliegtuigmodus" - "As jy Bluetooth aangeskakel hou, sal jou foon onthou om dit aan te hou wanneer jy weer in vliegtuigmodus is" + + "Bluetooth bly aan" - "Jou foon onthou om Bluetooth aangeskakel te hou in vliegtuigmodus. Skakel Bluetooth af as jy nie wil hê dit moet aan bly nie." + + "Wi-fi en Bluetooth bly aan" - "Jou foon onthou om wi‑fi en Bluetooth aan te hou in vliegtuigmodus. Skakel wi-fi en Bluetooth af as jy nie wil het hulle moet aan bly nie." + + diff --git a/android/app/res/values-am/strings.xml b/android/app/res/values-am/strings.xml index 6b8449e5f6c..0225a9c74ac 100644 --- a/android/app/res/values-am/strings.xml +++ b/android/app/res/values-am/strings.xml @@ -130,9 +130,12 @@ "ከ4 ጊባ በላይ የሆኑ ፋይሎች ሊዛወሩ አይችሉም" "ከብሉቱዝ ጋር ተገናኝ" "ብሉቱዝ በአውሮፕላን ሁነታ ላይ በርቷል" - "ብሉቱዝን አብርተው ካቆዩ በቀጣይ ጊዜ በአውሮፕላን ሁነታ ውስጥ ሲሆኑ ስልክዎ እሱን አብርቶ ማቆየቱን ያስታውሳል" + + "ብሉቱዝ በርቶ ይቆያል" - "ስልክዎ ብሉቱዝን በአውሮፕላን ሁነታ ውስጥ አብርቶ ማቆየትን ያስታውሳል። በርቶ እንዲቆይ ካልፈለጉ ብሉቱዝን ያጥፉት።" + + "Wi-Fi እና ብሉቱዝ በርተው ይቆያሉ" - "ስልክዎ Wi-Fiን እና ብሉቱዝን በአውሮፕላን ሁነታ ውስጥ አብርቶ ማቆየትን ያስታውሳል። በርተው እንዲቆዩ ካልፈለጉ Wi-Fi እና ብሉቱዝን ያጥፏቸው።" + + diff --git a/android/app/res/values-ar/strings.xml b/android/app/res/values-ar/strings.xml index c6f7396342c..185a98d45d6 100644 --- a/android/app/res/values-ar/strings.xml +++ b/android/app/res/values-ar/strings.xml @@ -130,9 +130,12 @@ "يتعذّر نقل الملفات التي يزيد حجمها عن 4 غيغابايت" "الاتصال ببلوتوث" "تقنية البلوتوث مفعّلة في \"وضع الطيران\"" - "إذا واصلت تفعيل تقنية البلوتوث، سيتذكر هاتفك إبقاءها مفعَّلة في المرة القادمة التي تفعِّل فيها \"وضع الطيران\"." + + "تظل تقنية البلوتوث مفعّلة" - "يتذكر هاتفك الاحتفاظ بتقنية البلوتوث مفعَّلة في \"وضع الطيران\". يمكنك إيقاف تقنية البلوتوث إذا لم تكن تريد مواصلة تفعيلها." + + "‏تظل شبكة Wi‑Fi وتقنية البلوتوث مفعَّلتَين." - "‏يتذكر هاتفك الاحتفاظ بشبكة Wi‑Fi وتقنية البلوتوث مفعَّلتَين في \"وضع الطيران\". يمكنك إيقاف شبكة Wi‑Fi وتقنية البلوتوث إذا لم تكن تريد مواصلة تفعيلهما." + + diff --git a/android/app/res/values-as/strings.xml b/android/app/res/values-as/strings.xml index bcc4a27c942..8ea69c7a586 100644 --- a/android/app/res/values-as/strings.xml +++ b/android/app/res/values-as/strings.xml @@ -130,9 +130,12 @@ "৪ জি. বি. তকৈ ডাঙৰ ফাইল স্থানান্তৰ কৰিব নোৱাৰি" "ব্লুটুথৰ সৈতে সংযোগ কৰক" "এয়াৰপ্লেন ম’ডত ব্লুটুথ অন হৈ থাকিব" - "আপুনি যদি ব্লুটুথ অন কৰি ৰাখে, পৰৱৰ্তী সময়ত আপুনি এয়াৰপ্লেন ম’ড ব্যৱহাৰ কৰিলে আপোনাৰ ফ’নটোৱে এয়া অন কৰি ৰাখিবলৈ মনত ৰাখিব" + + "ব্লুটুথ অন হৈ থাকে" - "আপোনাৰ ফ’নটোৱে এয়াৰপ্লেন ম’ডত ব্লুটুথ অন ৰাখিবলৈ মনত ৰাখে। আপুনি যদি ব্লুটুথ অন হৈ থকাটো নিবিচাৰে, তেন্তে ইয়াক অফ কৰক।" + + "ৱাই-ফাই আৰু ব্লুটুথ অন হৈ থাকে" - "আপোনাৰ ফ’নটোৱে এয়াৰপ্লেন ম’ডত ৱাই-ফাই আৰু ব্লুটুথ অন ৰাখিবলৈ মনত ৰাখে। আপুনি ৱাই-ফাই আৰু ব্লুটুথ অন হৈ থকাটো নিবিচাৰিলে সেইবোৰ অফ কৰক।" + + diff --git a/android/app/res/values-az/strings.xml b/android/app/res/values-az/strings.xml index ec63e9583da..b14eab4ff33 100644 --- a/android/app/res/values-az/strings.xml +++ b/android/app/res/values-az/strings.xml @@ -130,9 +130,12 @@ "4GB-dən böyük olan faylları köçürmək mümkün deyil" "Bluetooth\'a qoşulun" "Bluetooth təyyarə rejimində aktivdir" - "Bluetooth\'u aktiv saxlasanız, növbəti dəfə təyyarə rejimində olduqda telefonunuz onu aktiv saxlayacaq" + + "Bluetooth aktiv qalacaq" - "Telefonunuz təyyarə rejimində Bluetooth\'u aktiv saxlayacaq. Aktiv qalmasını istəmirsinizsə, Bluetooth\'u deaktiv edin." + + "Wi-Fi və Bluetooth aktiv qalır" - "Telefonunuz təyyarə rejimində Wi‑Fi və Bluetooth\'u aktiv saxlayacaq. Aktiv qalmasını istəmirsinizsə, Wi-Fi və Bluetooth\'u deaktiv edin." + + diff --git a/android/app/res/values-b+sr+Latn/strings.xml b/android/app/res/values-b+sr+Latn/strings.xml index e9548e2f298..8a06f3ec2c3 100644 --- a/android/app/res/values-b+sr+Latn/strings.xml +++ b/android/app/res/values-b+sr+Latn/strings.xml @@ -130,9 +130,12 @@ "Ne mogu da se prenose datoteke veće od 4 GB" "Poveži sa Bluetooth-om" "Bluetooth je uključen u režimu rada u avionu" - "Ako odlučite da ne isključujete Bluetooth, telefon će zapamtiti da ga ne isključuje sledeći put kada budete u režimu rada u avionu" + + "Bluetooth se ne isključuje" - "Telefon pamti da ne treba da isključuje Bluetooth u režimu rada u avionu. Isključite Bluetooth ako ne želite da ostane uključen." + + "WiFi i Bluetooth ostaju uključeni" - "Telefon pamti da ne treba da isključuje WiFi i Bluetooth u režimu rada u avionu. Isključite WiFi i Bluetooth ako ne želite da ostanu uključeni." + + diff --git a/android/app/res/values-be/strings.xml b/android/app/res/values-be/strings.xml index ca6767e4a83..b4124f80d6f 100644 --- a/android/app/res/values-be/strings.xml +++ b/android/app/res/values-be/strings.xml @@ -130,9 +130,12 @@ "Немагчыма перадаць файлы, большыя за 4 ГБ" "Падключыцца да Bluetooth" "У рэжыме палёту Bluetooth уключаны" - "Калі вы не выключыце Bluetooth, падчас наступнага пераходу ў рэжым палёту тэлефон будзе захоўваць яго ўключаным" + + "Bluetooth застаецца ўключаным" - "На тэлефоне ў рэжыме палёту Bluetooth застанецца ўключаным, але вы можаце выключыць яго." + + "Wi-Fi і Bluetooth застаюцца ўключанымі" - "На тэлефоне ў рэжыме палёту сетка Wi‑Fi і Bluetooth будуць заставацца ўключанымі, але вы можаце выключыць іх." + + diff --git a/android/app/res/values-bg/strings.xml b/android/app/res/values-bg/strings.xml index 22d88eb0591..0e0d24261d2 100644 --- a/android/app/res/values-bg/strings.xml +++ b/android/app/res/values-bg/strings.xml @@ -130,9 +130,12 @@ "Файловете с размер над 4 ГБ не могат да бъдат прехвърлени" "Свързване с Bluetooth" "Функцията за Bluetooth е включена в самолетния режим" - "Ако не изключите функцията за Bluetooth, телефонът ви ще я остави активна следващия път, когато използвате самолетния режим" + + "Функцията за Bluetooth няма да се изключи" - "Функцията за Bluetooth ще бъде включена, докато телефонът ви е в самолетен режим. Ако не искате това, изключете я." + + "Функциите за Wi-Fi и Bluetooth няма да бъдат изключени" - "Функциите за Wi‑Fi и Bluetooth ще бъдат включени, докато телефонът ви е в самолетен режим. Ако не искате това, изключете ги." + + diff --git a/android/app/res/values-bn/strings.xml b/android/app/res/values-bn/strings.xml index e83784183fc..95d354d40b6 100644 --- a/android/app/res/values-bn/strings.xml +++ b/android/app/res/values-bn/strings.xml @@ -130,9 +130,12 @@ "৪GB থেকে বড় ফটো ট্রান্সফার করা যাবে না" "ব্লুটুথের সাথে কানেক্ট করুন" "\'বিমান মোড\'-এ থাকাকালীন ব্লুটুথ চালু থাকে" - "আপনি ওয়াই-ফাই চালু রাখলে, আপনি এরপর \'বিমান মোডে\' থাকলে আপনার ফোন এটি চালু রাখবে" + + "ব্লুটুথ চালু থাকে" - "\'বিমান মোড\'-এ থাকাকালীন আপনার ফোন ব্লুটুথ চালু রাখে। আপনি ব্লুটুথ চালু না রাখতে চাইলে এটি বন্ধ করুন।" + + "ওয়াই-ফাই ও ব্লুটুথ চালু থাকে" - "\'বিমান মোড\'-এ থাকাকালীন আপনার ফোন ওয়াই-ফাই ও ব্লুটুথ চালু রাখে। আপনি যদি ওয়াই-ফাই এবং ব্লুটুথ চালু রাখতে না চান, সেগুলি বন্ধ করে দিন।" + + diff --git a/android/app/res/values-bs/strings.xml b/android/app/res/values-bs/strings.xml index f21cce84a95..28429a36306 100644 --- a/android/app/res/values-bs/strings.xml +++ b/android/app/res/values-bs/strings.xml @@ -130,9 +130,12 @@ "Nije moguće prenijeti fajlove veće od 4 GB" "Poveži se na Bluetooth" "Bluetooth je uključen u načinu rada u avionu" - "Ako ostavite Bluetooth uključenim, telefon će zapamtiti da ga ostavi uključenog sljedeći put kada budete u načinu rada u avionu" + + "Bluetooth ostaje uključen" - "Telefon pamti da Bluetooth treba biti uključen u načinu rada u avionu. Isključite Bluetooth ako ne želite da ostane uključen." + + "WiFi i Bluetooth ostaju uključeni" - "Telefon pamti da WiFi i Bluetooth trebaju biti uključeni u načinu rada u avionu. Isključite WiFi i Bluetooth ako ne želite da ostanu uključeni." + + diff --git a/android/app/res/values-ca/strings.xml b/android/app/res/values-ca/strings.xml index b476c4e0761..fe765e13640 100644 --- a/android/app/res/values-ca/strings.xml +++ b/android/app/res/values-ca/strings.xml @@ -130,9 +130,12 @@ "No es poden transferir fitxers més grans de 4 GB" "Connecta el Bluetooth" "El Bluetooth està activat en mode d\'avió" - "Si tens activat el Bluetooth, el telèfon recordarà mantenir-lo així la pròxima vegada que utilitzis el mode d\'avió" + + "El Bluetooth es mantindrà activat" - "El telèfon recorda mantenir el Bluetooth activat en mode d\'avió. Desactiva el Bluetooth si no vols que es quedi activat." + + "La Wi‑Fi i el Bluetooth es mantenen activats" - "El telèfon recorda mantenir la Wi‑Fi i el Bluetooth activats en mode d\'avió. Desactiva la Wi‑Fi i el Bluetooth si no vols que es quedin activats." + + diff --git a/android/app/res/values-cs/strings.xml b/android/app/res/values-cs/strings.xml index 09dc67bbb06..c2d1a87658a 100644 --- a/android/app/res/values-cs/strings.xml +++ b/android/app/res/values-cs/strings.xml @@ -130,9 +130,12 @@ "Soubory větší než 4 GB nelze přenést" "Připojit k Bluetooth" "Zapnutý Bluetooth v režimu Letadlo" - "Pokud Bluetooth necháte zapnutý, telefon si zapamatuje, že ho má příště v režimu Letadlo ponechat zapnutý" + + "Bluetooth zůstane zapnutý" - "Telefon si pamatuje, že má v režimu Letadlo ponechat zapnutý Bluetooth. Pokud nechcete, aby Bluetooth zůstal zapnutý, vypněte ho." + + "Wi-Fi a Bluetooth zůstávají zapnuté" - "Telefon si pamatuje, že má v režimu Letadlo ponechat zapnutou Wi-Fi a Bluetooth. Pokud nechcete, aby Wi-Fi a Bluetooth zůstaly zapnuté, vypněte je." + + diff --git a/android/app/res/values-da/strings.xml b/android/app/res/values-da/strings.xml index 47f0b5405c2..1cbd768e721 100644 --- a/android/app/res/values-da/strings.xml +++ b/android/app/res/values-da/strings.xml @@ -130,9 +130,12 @@ "File, der er større end 4 GB, kan ikke overføres" "Opret forbindelse til Bluetooth" "Bluetooth er aktiveret i flytilstand" - "Hvis du holder Bluetooth aktiveret, sørger din telefon for, at Bluetooth forbliver aktiveret, næste gang du sætter den til flytilstand" + + "Bluetooth forbliver aktiveret" - "Din telefon beholder Bluetooth aktiveret i flytilstand. Deaktiver Bluetooth, hvis du ikke vil have, at det forbliver aktiveret." + + "Wi-Fi og Bluetooth forbliver aktiveret" - "Din telefon husker at holde Wi-Fi og Bluetooth aktiveret i flytilstand. Deaktiver Wi-Fi og Bluetooth, hvis du ikke vil have, at de forbliver aktiveret." + + diff --git a/android/app/res/values-de/strings.xml b/android/app/res/values-de/strings.xml index 7d9ade34d72..afbb8b200f0 100644 --- a/android/app/res/values-de/strings.xml +++ b/android/app/res/values-de/strings.xml @@ -130,9 +130,12 @@ "Dateien mit mehr als 4 GB können nicht übertragen werden" "Mit Bluetooth verbinden" "Bluetooth im Flugmodus eingeschaltet" - "Wenn du Bluetooth nicht ausschaltest, bleibt es eingeschaltet, wenn du das nächste Mal in den Flugmodus wechselst" + + "Bluetooth bleibt aktiviert" - "Auf deinem Smartphone bleibt Bluetooth im Flugmodus eingeschaltet. Schalte Bluetooth aus, wenn du das nicht möchtest." + + "WLAN und Bluetooth bleiben eingeschaltet" - "Auf deinem Smartphone bleiben WLAN und Bluetooth im Flugmodus eingeschaltet. Schalte sie aus, wenn du das nicht möchtest." + + diff --git a/android/app/res/values-el/strings.xml b/android/app/res/values-el/strings.xml index 36ebd165d3d..1ff16ce3ae0 100644 --- a/android/app/res/values-el/strings.xml +++ b/android/app/res/values-el/strings.xml @@ -130,9 +130,12 @@ "Δεν είναι δυνατή η μεταφορά αρχείων που ξεπερνούν τα 4 GB" "Σύνδεση σε Bluetooth" "Bluetooth ενεργοποιημένο σε λειτουργία πτήσης" - "Αν διατηρήσετε το Bluetooth ενεργοποιημένο, το τηλέφωνό σας θα θυμάται να το διατηρήσει ενεργοποιημένο την επόμενη φορά που θα βρεθεί σε λειτουργία πτήσης" + + "Το Bluetooth παραμένει ενεργό" - "Το τηλέφωνο θυμάται να διατηρεί ενεργοποιημένο το Bluetooth σε λειτουργία πτήσης. Απενεργοποιήστε το Bluetooth αν δεν θέλετε να παραμένει ενεργοποιημένο." + + "Το Wi-Fi και το Bluetooth παραμένουν ενεργοποιημένα" - "Το τηλέφωνο θυμάται να διατηρεί ενεργοποιημένο το Wi‑Fi και το Bluetooth σε λειτουργία πτήσης. Απενεργοποιήστε το Wi-Fi και το Bluetooth αν δεν θέλετε να παραμένουν ενεργοποιημένα." + + diff --git a/android/app/res/values-en-rAU/strings.xml b/android/app/res/values-en-rAU/strings.xml index 6db8bfaf7c0..80d35500087 100644 --- a/android/app/res/values-en-rAU/strings.xml +++ b/android/app/res/values-en-rAU/strings.xml @@ -130,9 +130,12 @@ "Files bigger than 4 GB cannot be transferred" "Connect to Bluetooth" "Bluetooth on in aeroplane mode" - "If you keep Bluetooth on, your phone will remember to keep it on the next time that you\'re in aeroplane mode" + + "Bluetooth stays on" - "Your phone remembers to keep Bluetooth on in aeroplane mode. Turn off Bluetooth if you don\'t want it to stay on." + + "Wi-Fi and Bluetooth stay on" - "Your phone remembers to keep Wi-Fi and Bluetooth on in aeroplane mode. Turn off Wi-Fi and Bluetooth if you don\'t want them to stay on." + + diff --git a/android/app/res/values-en-rCA/strings.xml b/android/app/res/values-en-rCA/strings.xml index 545853f2c55..45bedcd3f3c 100644 --- a/android/app/res/values-en-rCA/strings.xml +++ b/android/app/res/values-en-rCA/strings.xml @@ -130,9 +130,9 @@ "Files bigger than 4GB cannot be transferred" "Connect to Bluetooth" "Bluetooth on in Airplane mode" - "If you keep Bluetooth on, your phone will remember to keep it on the next time you\'re in Airplane mode" + "If you keep Bluetooth on, your device will remember to keep it on the next time you\'re in airplane mode" "Bluetooth stays on" - "Your phone remembers to keep Bluetooth on in Airplane mode. Turn off Bluetooth if you don\'t want it to stay on." + "Your device remembers to keep Bluetooth on in airplane mode. Turn off Bluetooth if you don\'t want it to stay on." "Wi-Fi and Bluetooth stay on" - "Your phone remembers to keep Wi-Fi and Bluetooth on in Airplane mode. Turn off Wi-Fi and Bluetooth if you don\'t want them to stay on." + "Your device remembers to keep Wi-Fi and Bluetooth on in airplane mode. Turn off Wi-Fi and Bluetooth if you don\'t want them to stay on." diff --git a/android/app/res/values-en-rGB/strings.xml b/android/app/res/values-en-rGB/strings.xml index 6db8bfaf7c0..80d35500087 100644 --- a/android/app/res/values-en-rGB/strings.xml +++ b/android/app/res/values-en-rGB/strings.xml @@ -130,9 +130,12 @@ "Files bigger than 4 GB cannot be transferred" "Connect to Bluetooth" "Bluetooth on in aeroplane mode" - "If you keep Bluetooth on, your phone will remember to keep it on the next time that you\'re in aeroplane mode" + + "Bluetooth stays on" - "Your phone remembers to keep Bluetooth on in aeroplane mode. Turn off Bluetooth if you don\'t want it to stay on." + + "Wi-Fi and Bluetooth stay on" - "Your phone remembers to keep Wi-Fi and Bluetooth on in aeroplane mode. Turn off Wi-Fi and Bluetooth if you don\'t want them to stay on." + + diff --git a/android/app/res/values-en-rIN/strings.xml b/android/app/res/values-en-rIN/strings.xml index 6db8bfaf7c0..80d35500087 100644 --- a/android/app/res/values-en-rIN/strings.xml +++ b/android/app/res/values-en-rIN/strings.xml @@ -130,9 +130,12 @@ "Files bigger than 4 GB cannot be transferred" "Connect to Bluetooth" "Bluetooth on in aeroplane mode" - "If you keep Bluetooth on, your phone will remember to keep it on the next time that you\'re in aeroplane mode" + + "Bluetooth stays on" - "Your phone remembers to keep Bluetooth on in aeroplane mode. Turn off Bluetooth if you don\'t want it to stay on." + + "Wi-Fi and Bluetooth stay on" - "Your phone remembers to keep Wi-Fi and Bluetooth on in aeroplane mode. Turn off Wi-Fi and Bluetooth if you don\'t want them to stay on." + + diff --git a/android/app/res/values-en-rXC/strings.xml b/android/app/res/values-en-rXC/strings.xml index ab3c717f0ef..ec88c80e1b4 100644 --- a/android/app/res/values-en-rXC/strings.xml +++ b/android/app/res/values-en-rXC/strings.xml @@ -130,9 +130,9 @@ "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‎‎‎‏‏‏‎‏‏‏‏‏‏‏‎‏‏‎‏‏‏‏‎‎‎‎‏‎‏‏‏‎‏‏‏‎‏‏‏‎‎‎‏‎‏‎‏‎‎‏‏‎‎‎‎‏‎‎‎‏‎‎‏‏‎‎‏‎‏‎‎‎‏‎‏‎‎Files bigger than 4GB cannot be transferred‎‏‎‎‏‎" "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‎‎‎‏‏‏‎‏‏‏‏‏‎‏‎‎‎‎‎‎‎‏‏‎‎‎‎‎‏‎‏‎‏‏‎‏‎‏‎‏‎‎‏‎‏‎‎‎‎‎‏‏‎‏‎‎‏‏‎‏‏‎‏‎‏‏‎‏‏‎‏‎‎‎‏‎Connect to Bluetooth‎‏‎‎‏‎" "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‎‎‎‏‏‏‎‏‏‏‏‏‏‏‎‏‏‏‏‏‏‏‏‏‎‏‎‏‎‎‎‏‏‎‎‏‏‏‎‎‎‏‏‏‏‎‎‏‎‎‏‎‏‎‎‎‏‎‎‏‏‎‏‏‎‏‎‎‎‎‏‏‎‏‎‎‎Bluetooth on in airplane mode‎‏‎‎‏‎" - "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‎‎‎‏‏‏‎‏‏‏‏‏‏‏‏‏‎‏‎‎‏‎‏‏‎‏‎‏‏‏‏‏‏‎‎‎‎‎‎‎‎‎‎‏‎‎‎‎‎‏‏‏‏‏‎‏‏‏‎‎‏‏‎‏‎‏‎‏‎‏‏‎‎‎‎‏‎If you keep Bluetooth on, your phone will remember to keep it on the next time you\'re in airplane mode‎‏‎‎‏‎" + "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‎‎‎‏‏‏‎‏‏‏‏‏‏‏‎‏‎‏‎‏‏‎‎‏‏‎‏‏‏‎‎‏‎‎‏‏‎‏‏‎‏‎‎‎‏‏‏‎‎‎‏‎‏‏‏‏‏‏‎‎‏‏‏‏‎‏‎‏‏‎‏‏‎‎‎‏‎If you keep Bluetooth on, your device will remember to keep it on the next time you\'re in airplane mode‎‏‎‎‏‎" "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‎‎‎‏‏‏‎‏‏‏‎‎‎‏‎‎‎‏‏‎‏‎‎‎‏‏‏‎‏‏‏‏‎‎‎‎‎‎‏‎‎‏‏‏‏‎‎‏‏‏‎‎‎‏‏‏‎‏‏‎‎‎‏‏‏‎‏‏‎‎Bluetooth stays on‎‏‎‎‏‎" - "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‎‎‎‏‏‏‎‏‏‏‏‏‏‏‏‎‎‎‏‏‎‎‎‏‏‏‏‏‎‎‎‏‎‏‏‏‎‏‏‏‏‏‏‏‏‎‏‏‎‎‎‎‎‏‏‏‏‏‏‎‎‏‎‏‎‎‎‏‏‏‏‎‏‏‎‏‎Your phone remembers to keep Bluetooth on in airplane mode. Turn off Bluetooth if you don\'t want it to stay on.‎‏‎‎‏‎" + "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‎‎‎‏‏‏‎‏‏‏‏‏‎‏‏‎‎‏‎‏‏‏‎‏‏‎‏‎‏‎‎‎‎‏‏‎‏‏‏‎‏‏‏‏‎‏‎‏‎‎‏‎‎‎‎‏‏‎‎‎‏‏‏‎‏‏‎‎‏‏‎‏‎‎‏‎Your device remembers to keep Bluetooth on in airplane mode. Turn off Bluetooth if you don\'t want it to stay on.‎‏‎‎‏‎" "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‎‎‎‏‏‏‎‏‏‏‏‏‏‏‎‏‎‎‎‎‏‏‎‎‏‎‏‏‏‎‏‎‏‎‎‏‎‎‎‎‏‎‎‎‏‏‎‏‏‏‏‎‎‏‎‎‏‎‏‏‏‎‎‎‎‎‏‎‏‏‏‏‏‏‎‎‎Wi-Fi and Bluetooth stay on‎‏‎‎‏‎" - "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‎‎‎‏‏‏‎‏‏‏‏‏‎‏‎‎‎‎‏‎‎‏‎‏‏‎‏‏‎‏‎‎‏‏‎‎‏‎‎‏‏‎‏‏‎‎‎‎‎‎‎‎‎‏‏‏‏‎‎‎‎‏‎‎‏‏‏‎‎‎‎‎‏‎‎‎Your phone remembers to keep Wi-Fi and Bluetooth on in airplane mode. Turn off Wi-Fi and Bluetooth if you don\'t want them to stay on.‎‏‎‎‏‎" + "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‎‎‎‏‏‏‎‏‏‏‏‏‏‏‏‎‏‏‎‎‏‏‏‎‏‎‏‏‏‎‏‏‎‏‎‎‎‏‏‏‏‎‎‎‎‎‏‎‏‎‏‏‏‎‎‏‏‎‏‏‎‎‎‏‏‏‏‎‎‎‏‏‏‏‏‎‎Your device remembers to keep Wi-Fi and Bluetooth on in airplane mode. Turn off Wi-Fi and Bluetooth if you don\'t want them to stay on.‎‏‎‎‏‎" diff --git a/android/app/res/values-es-rUS/strings.xml b/android/app/res/values-es-rUS/strings.xml index 9969588c3b7..696a6b83ae4 100644 --- a/android/app/res/values-es-rUS/strings.xml +++ b/android/app/res/values-es-rUS/strings.xml @@ -130,9 +130,12 @@ "No se pueden transferir los archivos de más de 4 GB" "Conectarse a Bluetooth" "Bluetooth activado en modo de avión" - "Si mantienes el Bluetooth activado, el teléfono lo dejará activado la próxima vez que actives el modo de avión" + + "El Bluetooth permanece activado" - "El teléfono dejará activado el Bluetooth en el modo de avión. Desactívalo si no quieres que permanezca activado." + + "El Wi-Fi y el Bluetooth permanecen activados" - "El teléfono dejará activado el Wi-Fi y el Bluetooth en el modo de avión. Si no quieres que permanezcan activados, desactívalos." + + diff --git a/android/app/res/values-es/strings.xml b/android/app/res/values-es/strings.xml index 59550d79099..58e607d4744 100644 --- a/android/app/res/values-es/strings.xml +++ b/android/app/res/values-es/strings.xml @@ -130,9 +130,12 @@ "No se pueden transferir archivos de más de 4 GB" "Conectarse a un dispositivo Bluetooth" "Bluetooth activado en modo Avión" - "Si dejas el Bluetooth activado, tu teléfono se acordará de mantenerlo así la próxima vez que uses el modo Avión" + + "El Bluetooth permanece activado" - "Tu teléfono se acordará de mantener activado el Bluetooth en modo Avión. Desactiva el Bluetooth si no quieres que permanezca activado." + + "El Wi-Fi y el Bluetooth permanecen activados" - "Tu teléfono se acordará de mantener activados el Wi-Fi y el Bluetooth en modo Avión. Desactívalos si no quieres que permanezcan activados." + + diff --git a/android/app/res/values-et/strings.xml b/android/app/res/values-et/strings.xml index 95163ce8d2b..96a0b2e9fd7 100644 --- a/android/app/res/values-et/strings.xml +++ b/android/app/res/values-et/strings.xml @@ -130,9 +130,12 @@ "Faile, mis on üle 4 GB, ei saa üle kanda" "Ühenda Bluetoothiga" "Bluetooth on lennukirežiimis sisse lülitatud" - "Kui hoiate Bluetoothi sisselülitatuna, jätab telefon teie valiku meelde ja kasutab seda järgmisel korral lennukirežiimi aktiveerimisel." + + "Bluetooth jääb sisselülitatuks" - "Teie telefon hoiab Bluetoothi lennukirežiimis sisselülitatuna. Lülitage Bluetooth välja, kui te ei soovi, et see oleks sisse lülitatud." + + "WiFi ja Bluetoothi jäävad sisselülitatuks" - "Teie telefon hoiab WiFi ja Bluetoothi lennukirežiimis sisselülitatuna. Lülitage WiFi ja Bluetooth välja, kui te ei soovi, et need oleksid sisse lülitatud." + + diff --git a/android/app/res/values-eu/strings.xml b/android/app/res/values-eu/strings.xml index 72a8773ed4c..f7190e2b9d3 100644 --- a/android/app/res/values-eu/strings.xml +++ b/android/app/res/values-eu/strings.xml @@ -130,9 +130,12 @@ "Ezin dira transferitu 4 GB baino gehiagoko fitxategiak" "Konektatu Bluetoothera" "Bluetootha aktibatuta mantentzen da hegaldi moduan" - "Bluetootha aktibatuta utziz gero, hura aktibatuta mantentzeaz gogoratuko da telefonoa hegaldi modua erabiltzen duzun hurrengoan" + + "Bluetootha aktibatuta mantenduko da" - "Hegaldi moduan, Bluetootha aktibatuta mantentzeaz gogoratzen da telefonoa. Halakorik nahi ez baduzu, desaktiba ezazu zuk zeuk." + + "Wifia eta Bluetootha aktibatuta mantentzen dira" - "Hegaldi moduan, wifia eta Bluetootha aktibatuta mantentzeaz gogoratzen da telefonoa. Halakorik nahi ez baduzu, desaktiba itzazu zuk zeuk." + + diff --git a/android/app/res/values-fa/strings.xml b/android/app/res/values-fa/strings.xml index a6234d2ef37..726b2b1fd4f 100644 --- a/android/app/res/values-fa/strings.xml +++ b/android/app/res/values-fa/strings.xml @@ -130,9 +130,12 @@ "فایل‌های بزرگ‌تر از ۴ گیگابایت نمی‌توانند منتقل شوند" "اتصال به بلوتوث" "بلوتوث در «حالت هواپیما» روشن باشد" - "اگر بلوتوث را روشن نگه دارید، تلفنتان به‌یاد خواهد داشت تا دفعه بعدی که در «حالت هواپیما» هستید آن را روشن نگه دارد" + + "بلوتوث روشن بماند" - "تلفنتان به‌یاد می‌آورد که بلوتوث را در «حالت هواپیما» روشن نگه دارد. اگر نمی‌خواهید بلوتوث روشن بماند، آن را خاموش کنید." + + "‏‫Wi-Fi و بلوتوث روشن بماند" - "‏تلفنتان به‌یاد می‌آورد که Wi-Fi و بلوتوث را در «حالت هواپیما» روشن نگه دارد. اگر نمی‌خواهید Wi-Fi و بلوتوث روشن بمانند، آن‌ها را خاموش کنید." + + diff --git a/android/app/res/values-fi/strings.xml b/android/app/res/values-fi/strings.xml index 7df0835d2ee..6ec8a4d8d29 100644 --- a/android/app/res/values-fi/strings.xml +++ b/android/app/res/values-fi/strings.xml @@ -130,9 +130,12 @@ "Yli 4 Gt:n kokoisia tiedostoja ei voi siirtää." "Muodosta Bluetooth-yhteys" "Bluetooth päällä lentokonetilassa" - "Jos pidät Bluetooth-yhteyden päällä, puhelin pitää sen päällä, kun seuraavan kerran olet lentokonetilassa" + + "Bluetooth pysyy päällä" - "Puhelimen Bluetooth pysyy päällä lentokonetilassa. Voit halutessasi laittaa Bluetooth-yhteyden pois päältä." + + "Wi-Fi ja Bluetooth pysyvät päällä" - "Puhelimen Wi-Fi-yhteys ja Bluetooth pysyvät päällä lentokonetilassa. Voit halutessasi laittaa ne pois päältä." + + diff --git a/android/app/res/values-fr-rCA/strings.xml b/android/app/res/values-fr-rCA/strings.xml index a31fd1f34d3..3cc879dc709 100644 --- a/android/app/res/values-fr-rCA/strings.xml +++ b/android/app/res/values-fr-rCA/strings.xml @@ -130,9 +130,12 @@ "Les fichiers dépassant 4 Go ne peuvent pas être transférés" "Connexion au Bluetooth" "Bluetooth activé en mode Avion" - "Si vous laissez le Bluetooth activé, votre téléphone se souviendra qu\'il doit le laisser activé la prochaine fois que vous serez en mode Avion" + + "Le Bluetooth reste activé" - "Votre téléphone se souvient de garder le Bluetooth activé en mode Avion. Désactivez le Bluetooth si vous ne souhaitez pas qu\'il reste activé." + + "Le Wi-Fi et le Bluetooth restent activés" - "Votre téléphone se souvient de garder le Wi-Fi et le Bluetooth activés en mode Avion. Désactivez le Wi-Fi et le Bluetooth si vous ne souhaitez pas qu\'ils restent activés." + + diff --git a/android/app/res/values-fr/strings.xml b/android/app/res/values-fr/strings.xml index c21ab432091..b80558ee009 100644 --- a/android/app/res/values-fr/strings.xml +++ b/android/app/res/values-fr/strings.xml @@ -130,9 +130,12 @@ "Impossible de transférer les fichiers supérieurs à 4 Go" "Se connecter au Bluetooth" "Bluetooth activé en mode Avion" - "Si vous laissez le Bluetooth activé, votre téléphone s\'en souviendra et le Bluetooth restera activé la prochaine fois que vous serez en mode Avion" + + "Le Bluetooth reste activé" - "Le Bluetooth restera activé en mode Avion. Vous pouvez le désactiver si vous le souhaitez." + + "Le Wi-Fi et le Bluetooth restent activés" - "Le Wi‑Fi et le Bluetooth de votre téléphone resteront activés en mode Avion. Vous pouvez les désactivez si vous le souhaitez." + + diff --git a/android/app/res/values-gl/strings.xml b/android/app/res/values-gl/strings.xml index 65c367f494d..9f2fe3dbcbc 100644 --- a/android/app/res/values-gl/strings.xml +++ b/android/app/res/values-gl/strings.xml @@ -130,9 +130,12 @@ "Non se poden transferir ficheiros de máis de 4 GB" "Conectar ao Bluetooth" "Bluetooth activado no modo avión" - "Se mantés o Bluetooth activado, o teléfono lembrará que ten que deixalo nese estado a próxima vez que esteas no modo avión" + + "O Bluetooth permanece activado" - "O teu teléfono lembrará manter o Bluetooth activado no modo avión. Se non queres que permaneza nese estado, desactívao." + + "A wifi e o Bluetooth permanecen activados" - "O teu teléfono lembrará manter a wifi e o Bluetooth activados no modo avión. Se non queres que permanezan nese estado, desactívaos." + + diff --git a/android/app/res/values-gu/strings.xml b/android/app/res/values-gu/strings.xml index d33df6b00b7..2ff5809472b 100644 --- a/android/app/res/values-gu/strings.xml +++ b/android/app/res/values-gu/strings.xml @@ -130,9 +130,12 @@ "4GB કરતા મોટી ફાઇલ ટ્રાન્સફર કરી શકાતી નથી" "બ્લૂટૂથ સાથે કનેક્ટ કરો" "એરપ્લેન મોડમાં બ્લૂટૂથ ચાલુ છે" - "જો તમે બ્લૂટૂથ ચાલુ રાખો, તો તમે જ્યારે આગલી વખતે એરપ્લેન મોડ પર જશો, ત્યારે તમારો ફોન તેને ચાલુ રાખવાનું યાદ રાખશે" + + "બ્લૂટૂથ ચાલુ રહેશે" - "તમારો ફોન બ્લૂટૂથને એરપ્લેન મોડમાં ચાલુ રાખવાનું યાદ રાખે છે. જો તમે બ્લૂટૂથ ચાલુ રાખવા માગતા ન હો, તો તેને બંધ કરો." + + "વાઇ-ફાઇ અને બ્લૂટૂથ ચાલુ રહે છે" - "તમારો ફોન વાઇ-ફાઇ અને બ્લૂટૂથને એરપ્લેન મોડમાં ચાલુ રાખવાનું યાદ રાખે છે. જો તમે વાઇ-ફાઇ અને બ્લૂટૂથ ચાલુ રાખવા માગતા ન હો, તો તેને બંધ કરો." + + diff --git a/android/app/res/values-hi/strings.xml b/android/app/res/values-hi/strings.xml index 829042394ea..e57a75de5bf 100644 --- a/android/app/res/values-hi/strings.xml +++ b/android/app/res/values-hi/strings.xml @@ -130,9 +130,12 @@ "4 जीबी से बड़ी फ़ाइलें ट्रांसफ़र नहीं की जा सकतीं" "ब्लूटूथ से कनेक्ट करें" "हवाई जहाज़ मोड में ब्लूटूथ चालू है" - "ब्लूटूथ चालू रखने पर आपका फ़ोन, अगली बार हवाई जहाज़ मोड चालू होने पर भी ब्लूटूथ चालू रखेगा" + + "ब्लूटूथ चालू रहता है" - "हवाई जहाज़ मोड में भी, आपका फ़ोन ब्लूटूथ चालू रखता है. अगर ब्लूटूथ चालू नहीं रखना है, तो उसे बंद कर दें." + + "वाई-फ़ाई और ब्लूटूथ चालू रहते हैं" - "हवाई जहाज़ मोड में भी, आपका फ़ोन वाई-फ़ाई और ब्लूटूथ को चालू रखता है. अगर आपको वाई-फ़ाई और ब्लूटूथ चालू नहीं रखना है, तो उन्हें बंद कर दें." + + diff --git a/android/app/res/values-hr/strings.xml b/android/app/res/values-hr/strings.xml index f660c0ba248..9369aa96d02 100644 --- a/android/app/res/values-hr/strings.xml +++ b/android/app/res/values-hr/strings.xml @@ -130,9 +130,12 @@ "Datoteke veće od 4 GB ne mogu se prenijeti" "Povezivanje s Bluetoothom" "Bluetooth je uključen u načinu rada u zrakoplovu" - "Ako Bluetooth ostane uključen, telefon će zapamtiti da treba ostati uključen u načinu rada u zrakoplovu" + + "Bluetooth ostaje uključen" - "Telefon će zapamtiti da Bluetooth treba ostati uključen u načinu rada u zrakoplovu. Isključite Bluetooth ako ne želite da ostane uključen." + + "Wi-Fi i Bluetooth ostat će uključeni" - "Telefon će zapamtiti da Wi‑Fi i Bluetooth trebaju ostati uključeni u načinu rada u zrakoplovu. Uključite Wi-Fi i Bluetooth ako ne želite da ostanu uključeni." + + diff --git a/android/app/res/values-hu/strings.xml b/android/app/res/values-hu/strings.xml index 85a1c3ecd85..0e97f2707a4 100644 --- a/android/app/res/values-hu/strings.xml +++ b/android/app/res/values-hu/strings.xml @@ -130,9 +130,12 @@ "A 4 GB-nál nagyobb fájlokat nem lehet átvinni" "Csatlakozás Bluetooth-eszközhöz" "Bluetooth bekapcsolva Repülős üzemmódban" - "Ha bekapcsolva tartja a Bluetootht, a telefon emlékezni fog arra, hogy a következő alkalommal, amikor Repülős üzemmódban van, bekapcsolva tartsa a funkciót." + + "A Bluetooth bekapcsolva marad" - "A telefon bekapcsolva tartja a Bluetootht Repülős üzemmódban. Kapcsolja ki a Bluetootht, ha nem szeretné, hogy bekapcsolva maradjon." + + "A Wi-Fi és a Bluetooth bekapcsolva marad" - "A telefon bekapcsolva tartja a Wi‑Fi-t és a Bluetootht Repülős üzemmódban. Ha nem szeretné, hogy bekapcsolva maradjon a Wi-Fi és a Bluetooth, kapcsolja ki őket." + + diff --git a/android/app/res/values-hy/strings.xml b/android/app/res/values-hy/strings.xml index af488cef809..92bde6c9be0 100644 --- a/android/app/res/values-hy/strings.xml +++ b/android/app/res/values-hy/strings.xml @@ -130,9 +130,12 @@ "4 ԳԲ-ից մեծ ֆայլերը հնարավոր չէ փոխանցել" "Միանալ Bluetooth-ին" "Bluetooth-ը միացված է ավիառեժիմում" - "Եթե Bluetooth-ը միացված թողնեք, հաջորդ անգամ այն ավտոմատ միացված կմնա ավիառեժիմում" + + "Bluetooth-ը կմնա միացված" - "Ավիառեժիմում Bluetooth-ը միացված կմնա։ Ցանկության դեպքում կարող եք անջատել Bluetooth-ը։" + + "Wi-Fi-ը և Bluetooth-ը մնում են միացված" - "Ավիառեժիմում Wi-Fi-ը և Bluetooth-ը միացված կմնան։ Ցանկության դեպքում կարող եք անջատել Wi-Fi-ը և Bluetooth-ը։" + + diff --git a/android/app/res/values-in/strings.xml b/android/app/res/values-in/strings.xml index 5aeac7db04e..aef3d7ebb82 100644 --- a/android/app/res/values-in/strings.xml +++ b/android/app/res/values-in/strings.xml @@ -130,9 +130,12 @@ "File yang berukuran lebih dari 4GB tidak dapat ditransfer" "Hubungkan ke Bluetooth" "Bluetooth aktif dalam mode pesawat" - "Jika Bluetooth tetap diaktifkan, ponsel akan ingat untuk tetap mengaktifkannya saat berikutnya ponsel Anda disetel ke mode pesawat" + + "Bluetooth tetap aktif" - "Ponsel akan mengingat untuk tetap mengaktifkan Bluetooth dalam mode pesawat. Nonaktifkan jika Anda tidak ingin Bluetooth terus aktif." + + "Wi-Fi dan Bluetooth tetap aktif" - "Ponsel akan mengingat untuk tetap mengaktifkan Wi-Fi dan Bluetooth dalam mode pesawat. Nonaktifkan jika Anda tidak ingin Wi-Fi dan Bluetooth terus aktif." + + diff --git a/android/app/res/values-is/strings.xml b/android/app/res/values-is/strings.xml index eecd43f453b..e0b29c65a3b 100644 --- a/android/app/res/values-is/strings.xml +++ b/android/app/res/values-is/strings.xml @@ -130,9 +130,12 @@ "Ekki er hægt að flytja skrár sem eru stærri en 4 GB" "Tengjast við Bluetooth" "Kveikt á Bluetooth í flugstillingu" - "Ef þú hefur kveikt á Bluetooth mun síminn muna að hafa kveikt á því næst þegar þú stillir á flugstillingu" + + "Áfram kveikt á Bluetooth" - "Síminn man að hafa kveikt á Bluetooth í flugstillingu. Slökktu á Bluetooth ef þú vilt ekki hafa kveikt á því." + + "Áfram verður kveikt á Wi-Fi og Bluetooth" - "Síminn man að hafa kveikt á Wi-Fi og Bluetooth í flugstillingu. Slökktu á Wi-Fi og Bluetooth ef þú vilt ekki hafa kveikt á þessu." + + diff --git a/android/app/res/values-it/strings.xml b/android/app/res/values-it/strings.xml index 289a8e572d7..5c02e81f0bb 100644 --- a/android/app/res/values-it/strings.xml +++ b/android/app/res/values-it/strings.xml @@ -130,9 +130,9 @@ "Impossibile trasferire file con dimensioni superiori a 4 GB" "Connettiti a Bluetooth" "Bluetooth attivo in modalità aereo" - "Se tieni attivo il Bluetooth, il telefono ricorderà di tenerlo attivo la prossima volta che sarai in modalità aereo" + "Se tieni attivo il Bluetooth, il dispositivo memorizza che dovrà tenerlo attivo la prossima volta che sarai in modalità aereo" "Il Bluetooth rimane attivo" - "Il telefono memorizza che deve tenere attivo il Bluetooth in modalità aereo. Disattiva il Bluetooth se non vuoi tenerlo attivo." + "Il dispositivo memorizza che deve tenere attivo il Bluetooth in modalità aereo. Disattiva il Bluetooth se non vuoi tenerlo attivo." "Wi-Fi e Bluetooth rimangono attivi" - "Il telefono memorizza che deve tenere attivi il Wi‑Fi e il Bluetooth in modalità aereo. Disattiva il Wi-Fi e il Bluetooth se non vuoi tenerli attivi." + "Il dispositivo memorizza che deve tenere attivi il Wi‑Fi e il Bluetooth in modalità aereo. Disattiva il Wi-Fi e il Bluetooth se non vuoi tenerli attivi." diff --git a/android/app/res/values-iw/strings.xml b/android/app/res/values-iw/strings.xml index 5b6c45a60a1..b3b2df4ce99 100644 --- a/android/app/res/values-iw/strings.xml +++ b/android/app/res/values-iw/strings.xml @@ -130,9 +130,12 @@ "‏לא ניתן להעביר קבצים שגדולים מ-4GB" "‏התחברות באמצעות Bluetooth" "‏חיבור ה-Bluetooth מופעל במצב טיסה" - "‏אם חיבור ה-Bluetooth נשאר מופעל, הטלפון יזכור להשאיר אותו מופעל בפעם הבאה שהוא יועבר למצב טיסה" + + "‏Bluetooth יישאר מופעל" - "‏חיבור ה-Bluetooth בטלפון יישאר מופעל במצב טיסה. אפשר להשבית את ה-Bluetooth אם לא רוצים שהוא יפעל." + + "‏חיבורי ה-Wi‑Fi וה-Bluetooth יישארו מופעלים" - "‏חיבורי ה-Wi‑Fi וה-Bluetooth בטלפון יישארו מופעלים במצב טיסה. אפשר להשבית את ה-Wi-Fi וה-Bluetooth אם לא רוצים שהם יפעלו." + + diff --git a/android/app/res/values-ja/strings.xml b/android/app/res/values-ja/strings.xml index 80ca7afc69e..6c04d4ede90 100644 --- a/android/app/res/values-ja/strings.xml +++ b/android/app/res/values-ja/strings.xml @@ -130,9 +130,12 @@ "4 GB を超えるファイルは転送できません" "Bluetooth に接続する" "機内モードで Bluetooth を ON にする" - "Bluetooth を ON にしておくと、次に機内モードになったときも ON のままになります" + + "Bluetooth を ON にしておく" - "機内モードでも、スマートフォンの Bluetooth は ON のままになります。Bluetooth を ON にしたくない場合は OFF にしてください。" + + "Wi-Fi と Bluetooth を ON のままにする" - "機内モードでも、スマートフォンの Wi-Fi と Bluetooth は ON のままになります。Wi-Fi と Bluetooth を ON にしたくない場合は OFF にしてください。" + + diff --git a/android/app/res/values-ka/strings.xml b/android/app/res/values-ka/strings.xml index 7eec41ad237..40fbeb66290 100644 --- a/android/app/res/values-ka/strings.xml +++ b/android/app/res/values-ka/strings.xml @@ -130,9 +130,12 @@ "4 გბაიტზე დიდი მოცულობის ფაილების გადატანა ვერ მოხერხდება" "Bluetooth-თან დაკავშირება" "Bluetooth ჩართულია თვითმფრინავის რეჟიმში" - "თუ Bluetooth-ს ჩართულს დატოვებთ, თქვენი ტელეფონი დაიმახსოვრებს და ჩართულს დატოვებს მას, როდესაც შემდეგ ჯერზე თვითმფრინავის რეჟიმში იქნებით" + + "Bluetooth რᲩება Ჩართული" - "თქვენს ტელეფონს ემახსოვრება, რომ Bluetooth ჩართული უნდა იყოს თვითმფრინავის რეჟიმში. გამორთეთ Bluetooth, თუ არ გსურთ, რომ ის ჩართული იყოს." + + "Wi-Fi და Bluetooth ჩართული დარჩება" - "თქვენს ტელეფონს ემახსოვრება, რომ Wi‑Fi და Bluetooth ჩართული უნდა იყოს თვითმფრინავის რეჟიმში. გამორთეთ Wi-Fi და Bluetooth, თუ არ გსურთ, რომ ისინი ჩართული იყოს." + + diff --git a/android/app/res/values-kk/strings.xml b/android/app/res/values-kk/strings.xml index 2280615c58c..1d691ab1c72 100644 --- a/android/app/res/values-kk/strings.xml +++ b/android/app/res/values-kk/strings.xml @@ -130,9 +130,12 @@ "Көлемі 4 ГБ-тан асатын файлдар тасымалданбайды" "Bluetooth-қа қосылу" "Bluetooth ұшақ режимінде қосулы" - "Bluetooth-ты қосулы қалдырсаңыз, келесі жолы ұшақ режиміне ауысқанда да ол қосылып тұрады." + + "Bluetooth қосулы болады" - "Bluetooth ұшақ режимінде қосылып тұрады. Қаласаңыз, оны өшіріп қоюыңызға болады." + + "Wi-Fi мен Bluetooth қосулы тұрады" - "Wi‑Fi мен Bluetooth ұшақ режимінде қосылып тұрады. Қаласаңыз, оларды өшіріп қоюыңызға болады." + + diff --git a/android/app/res/values-km/strings.xml b/android/app/res/values-km/strings.xml index b69eeb07c08..120b380017c 100644 --- a/android/app/res/values-km/strings.xml +++ b/android/app/res/values-km/strings.xml @@ -130,9 +130,12 @@ "ឯកសារ​ដែល​មាន​ទំហំ​ធំ​ជាង 4 GB មិន​អាចផ្ទេរ​បាន​ទេ" "ភ្ជាប់​ប៊្លូធូស" "បើកប៊្លូធូស​នៅក្នុង​មុខងារពេលជិះយន្តហោះ" - "ប្រសិនបើអ្នក​បើកប៊្លូធូស នោះទូរសព្ទ​របស់អ្នកនឹង​ចាំថាត្រូវបើកវា នៅលើកក្រោយ​ដែលអ្នកស្ថិតក្នុង​មុខងារពេលជិះយន្តហោះ" + + "ប៊្លូធូសបន្តបើក" - "ទូរសព្ទរបស់អ្នក​ចាំថាត្រូវបើកប៊្លូធូស​នៅក្នុង​មុខងារពេលជិះយន្តហោះ។ បិទប៊្លូធូស ប្រសិនបើអ្នក​មិនចង់បើកទេ។" + + "Wi-Fi និងប៊្លូធូស​បន្តបើក" - "ទូរសព្ទរបស់អ្នក​ចាំថាត្រូវបើក Wi-Fi និងប៊្លូធូស​នៅក្នុង​មុខងារពេលជិះយន្តហោះ។ បិទ Wi-Fi និង​ប៊្លូធូស ប្រសិនបើអ្នក​មិនចង់បើកទេ។" + + diff --git a/android/app/res/values-kn/strings.xml b/android/app/res/values-kn/strings.xml index d7a5cbecc34..1049c0ef8df 100644 --- a/android/app/res/values-kn/strings.xml +++ b/android/app/res/values-kn/strings.xml @@ -78,7 +78,7 @@ "ಫೈಲ್‌ ಅಸ್ತಿತ್ವದಲ್ಲಿಲ್ಲ. \n" "ದಯವಿಟ್ಟು ನಿರೀಕ್ಷಿಸಿ…" "ಬ್ಲೂಟೂತ್‌ ಆನ್‌ ಮಾಡಲಾಗುತ್ತಿದೆ…" - "ಫೈಲ್‌ ಸ್ವೀಕರಿಸಲಾಗುತ್ತದೆ. ಅಧಿಸೂಚನೆ ಫಲಕದಲ್ಲಿ ಪ್ರಗತಿಯನ್ನು ಪರಿಶೀಲಿಸಿ." + "ಫೈಲ್‌ ಸ್ವೀಕರಿಸಲಾಗುತ್ತದೆ. ನೋಟಿಫಿಕೇಶನ್ ಫಲಕದಲ್ಲಿ ಪ್ರಗತಿಯನ್ನು ಪರಿಶೀಲಿಸಿ." "ಫೈಲ್‌ ಸ್ವೀಕರಿಸಲು ಸಾಧ್ಯವಿಲ್ಲ." "\"%1$s\" ರಿಂದ ಫೈಲ್‌ ಸ್ವೀಕರಿಸುವುದನ್ನು ನಿಲ್ಲಿಸಲಾಗಿದೆ" "\"%1$s\" ಇವರಿಗೆ ಫೈಲ್‌‌ ಕಳುಹಿಸಲಾಗುತ್ತಿದೆ" @@ -130,9 +130,12 @@ "4GB ಗಿಂತ ದೊಡ್ಡದಾದ ಫೈಲ್‌ಗಳನ್ನು ವರ್ಗಾಯಿಸಲು ಸಾಧ್ಯವಿಲ್ಲ" "ಬ್ಲೂಟೂತ್‌ಗೆ ಕನೆಕ್ಟ್ ಮಾಡಿ" "ಏರ್‌ಪ್ಲೇನ್ ಮೋಡ್‌ನಲ್ಲಿ ಬ್ಲೂಟೂತ್ ಆನ್ ಆಗಿದೆ" - "ನೀವು ಬ್ಲೂಟೂತ್ ಆನ್ ಆಗಿರಿಸಿದರೆ, ಮುಂದಿನ ಬಾರಿ ನೀವು ಏರ್‌ಪ್ಲೇನ್ ಮೋಡ್‌ನಲ್ಲಿರುವಾಗ ಅದನ್ನು ಆನ್ ಆಗಿರಿಸಿಕೊಳ್ಳುವುದನ್ನು ನಿಮ್ಮ ಫೋನ್ ನೆನಪಿಸಿಕೊಳ್ಳುತ್ತದೆ" + + "ಬ್ಲೂಟೂತ್ ಆನ್ ಆಗಿರುತ್ತದೆ" - "ಏರ್‌ಪ್ಲೇನ್ ಮೋಡ್‌ನಲ್ಲಿ ಬ್ಲೂಟೂತ್ ಆನ್ ಆಗಿರಿಸಿಕೊಳ್ಳುವುದನ್ನು ನಿಮ್ಮ ಫೋನ್ ನೆನಪಿಸಿಕೊಳ್ಳುತ್ತದೆ. ಬ್ಲೂಟೂತ್ ಆನ್ ಆಗಿರಿಸಲು ನೀವು ಬಯಸದಿದ್ದರೆ ಅದನ್ನು ಆಫ್ ಮಾಡಿ." + + "ವೈ-ಫೈ ಮತ್ತು ಬ್ಲೂಟೂತ್ ಆನ್ ಆಗಿರುತ್ತದೆ" - "ಏರ್‌ಪ್ಲೇನ್ ಮೋಡ್‌ನಲ್ಲಿ ವೈಫೈ ಮತ್ತು ಬ್ಲೂಟೂತ್ ಆನ್ ಆಗಿರಿಸಿಕೊಳ್ಳುವುದನ್ನು ನಿಮ್ಮ ಫೋನ್ ನೆನಪಿಸಿಕೊಳ್ಳುತ್ತದೆ. ವೈಫೈ ಮತ್ತು ಬ್ಲೂಟೂತ್ ಆನ್ ಆಗಿರಿಸಲು ನೀವು ಬಯಸದಿದ್ದರೆ ಅವುಗಳನ್ನು ಆಫ್ ಮಾಡಿ." + + diff --git a/android/app/res/values-ko/strings.xml b/android/app/res/values-ko/strings.xml index 2a6bcea99de..e21a971d50b 100644 --- a/android/app/res/values-ko/strings.xml +++ b/android/app/res/values-ko/strings.xml @@ -130,9 +130,12 @@ "4GB보다 큰 파일은 전송할 수 없습니다" "블루투스에 연결" "비행기 모드에서 블루투스 사용 설정" - "블루투스를 켜진 상태로 유지하면 다음에 비행기 모드를 사용할 때도 블루투스 연결이 유지됩니다." + + "블루투스가 켜진 상태로 유지됨" - "휴대전화가 비행기 모드에서 블루투스를 켜진 상태로 유지합니다. 유지하지 않으려면 블루투스를 사용 중지하세요." + + "Wi-Fi 및 블루투스 계속 사용" - "휴대전화가 비행기 모드에서 Wi-Fi 및 블루투스를 켜진 상태로 유지합니다. 유지하지 않으려면 Wi-Fi와 블루투스를 사용 중지하세요." + + diff --git a/android/app/res/values-ky/strings.xml b/android/app/res/values-ky/strings.xml index 4f1f7a1826f..2241ee7d153 100644 --- a/android/app/res/values-ky/strings.xml +++ b/android/app/res/values-ky/strings.xml @@ -130,9 +130,12 @@ "4Гб чоң файлдарды өткөрүү мүмкүн эмес" "Bluetooth\'га туташуу" "Учак режиминде Bluetooth күйүк" - "Эгер Bluetooth күйүк бойдон калса, кийинки жолу учак режимине өткөнүңүздө телефонуңуз аны эстеп калат" + + "Bluetooth күйүк бойдон калат" - "Телефонуңуз учак режиминде Bluetooth\'га туташкан бойдон калат. Кааласаңыз, Bluetooth\'ду өчүрүп койсоңуз болот." + + "Wi-Fi менен Bluetooth күйүк бойдон калат" - "Телефонуңуз учак режиминде Wi‑Fi\'га жана Bluetooth\'га туташкан бойдон калат. Кааласаңыз, Wi-Fi менен Bluetooth\'ду өчүрүп койсоңуз болот." + + diff --git a/android/app/res/values-lo/strings.xml b/android/app/res/values-lo/strings.xml index 9c60428aa9e..eb805e312ac 100644 --- a/android/app/res/values-lo/strings.xml +++ b/android/app/res/values-lo/strings.xml @@ -130,9 +130,12 @@ "ບໍ່ສາມາດໂອນຍ້າຍໄຟລ໌ທີ່ໃຫຍກວ່າ 4GB ໄດ້" "ເຊື່ອມຕໍ່ກັບ Bluetooth" "ເປີດ Bluetooth ໃນໂໝດຢູ່ໃນຍົນ" - "ຫາກທ່ານເປີດ Bluetooth ປະໄວ້, ໂທລະສັບຂອງທ່ານຈະຈື່ວ່າຕ້ອງເປີດ Wi‑Fi ໃນເທື່ອຕໍ່ໄປທີ່ທ່ານຢູ່ໃນໂໝດຢູ່ໃນຍົນ" + + "Bluetooth ເປີດຢູ່" - "ໂທລະສັບຂອງທ່ານຈື່ວ່າຈະຕ້ອງເປີດ Bluetooth ປະໄວ້ໃນໂໝດຢູ່ໃນຍົນ. ປິດ Bluetooth ຫາກທ່ານບໍ່ຕ້ອງການໃຫ້ເປີດປະໄວ້." + + "Wi-Fi ແລະ Bluetooth ຈະເປີດປະໄວ້" - "ໂທລະສັບຂອງທ່ານຈື່ວ່າຈະຕ້ອງເປີດ Wi-Fi ແລະ Bluetooth ປະໄວ້ໃນໂໝດຢູ່ໃນຍົນ. ປິດ Wi-Fi ແລະ Bluetooth ຫາກທ່ານບໍ່ຕ້ອງການໃຫ້ເປີດປະໄວ້." + + diff --git a/android/app/res/values-lt/strings.xml b/android/app/res/values-lt/strings.xml index de0c13f5930..c72b5034136 100644 --- a/android/app/res/values-lt/strings.xml +++ b/android/app/res/values-lt/strings.xml @@ -130,9 +130,12 @@ "Negalima perkelti didesnių nei 4 GB failų" "Prisijungti prie „Bluetooth“" "„Bluetooth“ ryšys įjungtas lėktuvo režimu" - "Jei paliksite „Bluetooth“ ryšį įjungtą, telefonas, prisimins palikti jį įjungtą, kai kitą kartą įjungsite lėktuvo režimą" + + "„Bluetooth“ liks įjungtas" - "Telefonas prisimena, kad naudojant lėktuvo režimą reikia palikti įjungtą „Bluetooth“ ryšį. Išjunkite „Bluetooth“, jei nenorite, kad jis liktų įjungtas." + + "„Wi‑Fi“ ir „Bluetooth“ ryšys lieka įjungtas" - "Telefonas prisimena, kad lėktuvo režimu reikia palikti įjungtą „Wi‑Fi“ ir „Bluetooth“ ryšį. Išjunkite „Wi-Fi“ ir „Bluetooth“, jei nenorite, kad jie liktų įjungti." + + diff --git a/android/app/res/values-lv/strings.xml b/android/app/res/values-lv/strings.xml index eee75d98490..be0e6bd77fe 100644 --- a/android/app/res/values-lv/strings.xml +++ b/android/app/res/values-lv/strings.xml @@ -130,9 +130,12 @@ "Nevar pārsūtīt failus, kas lielāki par 4 GB." "Izveidot savienojumu ar Bluetooth" "Tehnoloģija Bluetooth lidojuma režīmā paliek ieslēgta" - "Ja Bluetooth savienojums paliks ieslēgts, tālrunī tas paliks ieslēgts arī nākamreiz, kad ieslēgsiet lidojuma režīmu." + + "Bluetooth savienojums joprojām ir ieslēgts" - "Lidojuma režīmā tālrunī joprojām būs ieslēgts Bluetooth savienojums. Izslēdziet Bluetooth savienojumu, ja nevēlaties, lai tas paliktu ieslēgts." + + "Wi-Fi savienojums un tehnoloģija Bluetooth paliek ieslēgta" - "Lidojuma režīmā tālrunī joprojām būs ieslēgti Wi-Fi un Bluetooth savienojumi. Izslēdziet Wi-Fi un Bluetooth savienojumus, ja nevēlaties, lai tie paliktu ieslēgti." + + diff --git a/android/app/res/values-mk/strings.xml b/android/app/res/values-mk/strings.xml index d7f99077e44..08262ad4386 100644 --- a/android/app/res/values-mk/strings.xml +++ b/android/app/res/values-mk/strings.xml @@ -130,9 +130,12 @@ "Не може да се пренесуваат датотеки поголеми од 4 GB" "Поврзи се со Bluetooth" "Вклучен Bluetooth во авионски режим" - "Ако го оставите Bluetooth вклучен, телефонот ќе запомни да го остави вклучен до следниот пат кога ќе бидете во авионски режим" + + "Bluetooth останува вклучен" - "Телефонот помни да го задржи Bluetooth вклучен во авионски режим. Исклучете го Bluetooth ако не сакате да остане вклучен." + + "Wi-Fi и Bluetooth остануваат вклучени" - "Телефонот помни да ги задржи Wi‑Fi и Bluetooth вклучени во авионски режим. Исклучете ги Wi-Fi и Bluetooth ако не сакате да бидат вклучени." + + diff --git a/android/app/res/values-ml/strings.xml b/android/app/res/values-ml/strings.xml index e0f76f43f2c..5c25b079044 100644 --- a/android/app/res/values-ml/strings.xml +++ b/android/app/res/values-ml/strings.xml @@ -130,9 +130,12 @@ "4GB-യിൽ കൂടുതലുള്ള ഫയലുകൾ കൈമാറാനാവില്ല" "Bluetooth-ലേക്ക് കണക്‌റ്റ് ചെയ്യുക" "ഫ്ലൈറ്റ് മോഡിൽ Bluetooth ഓണാണ്" - "Bluetooth ഓണാക്കി വച്ചാൽ, അടുത്ത തവണ നിങ്ങൾ ഫ്ലൈറ്റ് മോഡിൽ ആയിരിക്കുമ്പോൾ നിങ്ങളുടെ ഫോൺ അത് ഓണാക്കി വയ്ക്കാൻ ഓർക്കും" + + "Bluetooth ഓണാക്കിയ നിലയിൽ തുടരും" - "ഫ്ലൈറ്റ് മോഡിലായിരിക്കുമ്പോൾ Bluetooth ഓണാക്കി വയ്ക്കാൻ നിങ്ങളുടെ ഫോൺ ഓർമ്മിക്കുന്നു. Bluetooth ഓണാക്കി വയ്ക്കാൻ താൽപ്പര്യമില്ലെങ്കിൽ അത് ഓഫാക്കുക." + + "വൈഫൈ, Bluetooth എന്നിവ ഓണായ നിലയിൽ തുടരും" - "ഫ്ലൈറ്റ് മോഡിലായിരിക്കുമ്പോൾ വൈഫൈ, Bluetooth എന്നിവ ഓണാക്കി വയ്ക്കാൻ നിങ്ങളുടെ ഫോൺ ഓർമ്മിക്കുന്നു. വൈഫൈ, Bluetooth എന്നിവ ഓണാക്കി വയ്‌ക്കാൻ താൽപ്പര്യമില്ലെങ്കിൽ അവ ഓഫാക്കുക." + + diff --git a/android/app/res/values-mn/strings.xml b/android/app/res/values-mn/strings.xml index b39de67f03e..ee54f6b5513 100644 --- a/android/app/res/values-mn/strings.xml +++ b/android/app/res/values-mn/strings.xml @@ -130,9 +130,12 @@ "4ГБ-с дээш хэмжээтэй файлыг шилжүүлэх боломжгүй" "Bluetooth-тэй холбогдох" "Нислэгийн горимд Bluetooth асаалттай" - "Хэрэв та Bluetooth-г асаалттай байлгавал таныг дараагийн удаа нислэгийн горимд байх үед утас тань үүнийг асаалттай байлгахыг санана" + + "Bluetooth асаалттай хэвээр байна" - "Таны утас Bluetooth-г нислэгийн горимд асаалттай байлгахыг санана. Хэрэв та асаалттай байлгахыг хүсэхгүй байгаа бол Bluetooth-г унтрааж болно." + + "Wi-Fi болон Bluetooth асаалттай хэвээр байна" - "Таны утас Wi-Fi болон Bluetooth-г нислэгийн горимд асаалттай байлгахыг санана. Хэрэв та асаалттай байлгахыг хүсэхгүй байгаа бол Wi-Fi болон Bluetooth-г унтрааж болно." + + diff --git a/android/app/res/values-mr/strings.xml b/android/app/res/values-mr/strings.xml index f45a9a55dd6..a57e33d174b 100644 --- a/android/app/res/values-mr/strings.xml +++ b/android/app/res/values-mr/strings.xml @@ -130,9 +130,12 @@ "4 GB हून मोठ्या फाइल ट्रान्सफर करता येणार नाहीत" "ब्लूटूथशी कनेक्ट करा" "विमान मोडमध्ये ब्लूटूथ सुरू आहे" - "तुम्ही ब्लूटूथ सुरू ठेवल्यास, पुढील वेळी विमान मोडमध्ये असाल, तेव्हा तुमचा फोन ते सुरू ठेवण्याचे लक्षात ठेवेल" + + "ब्लूटूथ सुरू राहते" - "तुमचा फोन विमान मोडमध्ये ब्लूटूथ सुरू ठेवण्याचे लक्षात ठेवतो. तुम्हाला ब्लूटूथ सुरू ठेवायचे नसल्यास ते बंद करा." + + "वाय-फाय आणि ब्लूटूथ सुरू राहते" - "तुमचा फोन विमान मोडमध्ये वाय-फाय आणि ब्लूटूथ सुरू ठेवण्याचे लक्षात ठेवतो. तुम्हाला वाय-फाय आणि ब्लूटूथ सुरू ठेवायचे नसल्यास ते बंद करा." + + diff --git a/android/app/res/values-ms/strings.xml b/android/app/res/values-ms/strings.xml index 53064c86969..a78231e161b 100644 --- a/android/app/res/values-ms/strings.xml +++ b/android/app/res/values-ms/strings.xml @@ -130,9 +130,12 @@ "Fail lebih besar daripada 4GB tidak boleh dipindahkan" "Sambung ke Bluetooth" "Bluetooth dihidupkan dalam mod pesawat" - "Jika anda terus menghidupkan Bluetooth, telefon anda akan ingat untuk membiarkan Bluetooth hidup pada kali seterusnya telefon anda berada dalam mod pesawat" + + "Bluetooth kekal dihidupkan" - "Telefon anda diingatkan untuk terus menghidupkan Bluetooth dalam mod pesawat. Matikan Bluetooth jika anda tidak mahu Bluetooth sentiasa hidup." + + "Wi-Fi dan Bluetooth kekal dihidupkan" - "Telefon anda diingatkan untuk terus menghidupkan Wi-Fi dan Bluetooth dalam mod pesawat. Matikan Wi-Fi dan Bluetooth jika anda tidak mahu Wi-Fi dan Bluetooth sentiasa hidup." + + diff --git a/android/app/res/values-my/strings.xml b/android/app/res/values-my/strings.xml index fb9a38360b1..4861a13c8ed 100644 --- a/android/app/res/values-my/strings.xml +++ b/android/app/res/values-my/strings.xml @@ -130,9 +130,12 @@ "4GB ထက်ပိုကြီးသည့် ဖိုင်များကို လွှဲပြောင်းမရနိုင်ပါ" "ဘလူးတုသ်သို့ ချိတ်ဆက်ရန်" "လေယာဉ်ပျံမုဒ်တွင် ဘလူးတုသ် ပွင့်နေသည်" - "ဘလူးတုသ် ဆက်ဖွင့်ထားပါက နောက်တစ်ကြိမ်လေယာဉ်ပျံမုဒ် သုံးချိန်တွင် ၎င်းဆက်ဖွင့်ရန် သင့်ဖုန်းက မှတ်ထားမည်။" + + "ဘလူးတုသ် ဆက်ပွင့်နေသည်" - "လေယာဉ်ပျံမုဒ်သုံးစဉ် ဘလူးတုသ် ဆက်ဖွင့်ထားရန် သင့်ဖုန်းက မှတ်မိသည်။ ဘလူးတုသ် ဆက်ဖွင့်မထားလိုပါက ပိတ်နိုင်သည်။" + + "Wi-Fi နှင့် ဘလူးတုသ် ဆက်ဖွင့်ထားသည်" - "လေယာဉ်ပျံမုဒ်သုံးစဉ် Wi-Fi နှင့် ဘလူးတုသ် ဆက်ဖွင့်ထားရန် သင့်ဖုန်းက မှတ်မိသည်။ Wi-Fi နှင့် ဘလူးတုသ် ဆက်ဖွင့်မထားလိုပါက ပိတ်နိုင်သည်။" + + diff --git a/android/app/res/values-nb/strings.xml b/android/app/res/values-nb/strings.xml index 3ff0bbc8fad..b87195712e1 100644 --- a/android/app/res/values-nb/strings.xml +++ b/android/app/res/values-nb/strings.xml @@ -130,9 +130,12 @@ "Filer som er større enn 4 GB, kan ikke overføres" "Koble til Bluetooth" "Bluetooth er på i flymodus" - "Hvis du lar Bluetooth være på, husker telefonen dette til den neste gangen du bruker flymodus" + + "Bluetooth blir værende på" - "Telefonen husker at Bluetooth skal være på i flymodus. Slå av Bluetooth hvis du ikke vil at det skal være på." + + "Wifi og Bluetooth holdes påslått" - "Telefonen husker at wifi og Bluetooth skal være på i flymodus. Slå av wifi og Bluetooth hvis du ikke vil at de skal være på." + + diff --git a/android/app/res/values-ne/strings.xml b/android/app/res/values-ne/strings.xml index eccb49f4077..239a5c6b51a 100644 --- a/android/app/res/values-ne/strings.xml +++ b/android/app/res/values-ne/strings.xml @@ -130,9 +130,12 @@ "४ जि.बि. भन्दा ठूला फाइलहरूलाई स्थानान्तरण गर्न सकिँदैन" "ब्लुटुथमा कनेक्ट गर्नुहोस्" "हवाइजहाज मोडमा ब्लुटुथ अन राखियोस्" - "तपाईंले ब्लुटुथ अन राखिराख्नुभयो भने तपाईंले आफ्नो फोन अर्को पटक हवाइजहाज मोडमा लैजाँदा तपाईंको फोनले ब्लुटुथ अन राख्नु पर्ने कुरा याद गर्छ" + + "ब्लुटुथ अन रहन्छ" - "तपाईंको फोन अर्को पटक हवाइजहाज मोडमा लैजाँदा तपाईंको फोनले ब्लुटुथ अन राख्नु पर्ने कुरा याद गर्छ तपाईं ब्लुटुथ अन भइनरहोस् भन्ने चाहनुहुन्छ भने ब्लुटुथ अफ गर्नुहोस्।" + + "Wi-Fi र ब्लुटुथ अन रहिरहने छन्" - "हवाइजहाज मोडमा पनि तपाईंको फोनको Wi-Fi र ब्लुटुथ अन नै रहिरहने छन्। तपाईं Wi-Fi र ब्लुटुथ अन भइनरहोस् भन्ने चाहनुहुन्छ भने तिनलाई अफ गर्नुहोस्।" + + diff --git a/android/app/res/values-nl/strings.xml b/android/app/res/values-nl/strings.xml index da9a3110f37..170aefdf9f4 100644 --- a/android/app/res/values-nl/strings.xml +++ b/android/app/res/values-nl/strings.xml @@ -130,9 +130,12 @@ "Bestanden groter dan 4 GB kunnen niet worden overgedragen" "Verbinding maken met bluetooth" "Bluetooth aan in de vliegtuigmodus" - "Als je bluetooth laat aanstaan, onthoudt je telefoon dit en blijft bluetooth aanstaan als je de vliegtuigmodus weer aanzet" + + "Bluetooth blijft aan" - "Bluetooth op je telefoon blijft aan in de vliegtuigmodus. Zet bluetooth uit als je niet wilt dat dit aan blijft." + + "Wifi en bluetooth blijven aan" - "Wifi en bluetooth op je telefoon blijven aan in de vliegtuigmodus. Zet wifi en bluetooth uit als je niet wilt dat ze aan blijven." + + diff --git a/android/app/res/values-or/strings.xml b/android/app/res/values-or/strings.xml index 08e68d7097c..032412ec30c 100644 --- a/android/app/res/values-or/strings.xml +++ b/android/app/res/values-or/strings.xml @@ -130,9 +130,12 @@ "4GBରୁ ବଡ଼ ଫାଇଲ୍‌ଗୁଡ଼ିକୁ ଟ୍ରାନ୍ସଫର୍‌ କରାଯାଇପାରିବ ନାହିଁ" "ବ୍ଲୁଟୁଥ୍ ସହ ସଂଯୋଗ କରନ୍ତୁ" "ଏୟାରପ୍ଲେନ ମୋଡରେ ବ୍ଲୁଟୁଥ ଚାଲୁ ଅଛି" - "ଯଦି ଆପଣ ବ୍ଲୁଟୁଥକୁ ଚାଲୁ ରଖନ୍ତି, ତେବେ ଆପଣ ପରବର୍ତ୍ତୀ ଥର ଏୟାରପ୍ଲେନ ମୋଡରେ ଥିବା ସମୟରେ ଆପଣଙ୍କ ଫୋନ ଏହାକୁ ଚାଲୁ ରଖିବା ପାଇଁ ମନେ ରଖିବ" + + "ବ୍ଲୁଟୁଥ ଚାଲୁ ରହେ" - "ଆପଣଙ୍କ ଫୋନ ଏୟାରପ୍ଲେନ ମୋଡରେ ବ୍ଲୁଟୁଥକୁ ଚାଲୁ ରଖିବା ପାଇଁ ମନେ ରଖେ। ଯଦି ଆପଣ ବ୍ଲୁଟୁଥ ଚାଲୁ ରଖିବାକୁ ଚାହାଁନ୍ତି ନାହିଁ ତେବେ ଏହାକୁ ବନ୍ଦ କରନ୍ତୁ।" + + "ୱାଇ-ଫାଇ ଏବଂ ବ୍ଲୁଟୁଥ ଚାଲୁ ରହେ" - "ଆପଣଙ୍କ ଫୋନ ଏୟାରପ୍ଲେନ ମୋଡରେ ୱାଇ-ଫାଇ ଏବଂ ବ୍ଲୁଟୁଥକୁ ଚାଲୁ ରଖିବା ପାଇଁ ମନେ ରଖେ। ଯଦି ଆପଣ ୱାଇ-ଫାଇ ଏବଂ ବ୍ଲୁଟୁଥ ଚାଲୁ ରଖିବାକୁ ଚାହାଁନ୍ତି ନାହିଁ ତେବେ ସେଗୁଡ଼ିକୁ ବନ୍ଦ କରନ୍ତୁ।" + + diff --git a/android/app/res/values-pa/strings.xml b/android/app/res/values-pa/strings.xml index 84c78ced7cc..accc6fb93cb 100644 --- a/android/app/res/values-pa/strings.xml +++ b/android/app/res/values-pa/strings.xml @@ -130,9 +130,12 @@ "4GB ਤੋਂ ਜ਼ਿਆਦਾ ਵੱਡੀਆਂ ਫ਼ਾਈਲਾਂ ਨੂੰ ਟ੍ਰਾਂਸਫ਼ਰ ਨਹੀਂ ਕੀਤਾ ਜਾ ਸਕਦਾ" "ਬਲੂਟੁੱਥ ਨਾਲ ਕਨੈਕਟ ਕਰੋ" "ਹਵਾਈ-ਜਹਾਜ਼ ਮੋਡ ਵਿੱਚ ਬਲੂਟੁੱਥ ਚਾਲੂ ਹੈ" - "ਜੇ ਤੁਸੀਂ ਬਲੂਟੁੱਥ ਨੂੰ ਚਾਲੂ ਰੱਖਦੇ ਹੋ, ਤਾਂ ਅਗਲੀ ਵਾਰ ਤੁਹਾਡਾ ਫ਼ੋਨ ਹਵਾਈ-ਜਹਾਜ਼ ਮੋਡ ਵਿੱਚ ਹੋਣ \'ਤੇ ਤੁਹਾਡਾ ਫ਼ੋਨ ਇਸਨੂੰ ਚਾਲੂ ਰੱਖਣਾ ਯਾਦ ਰੱਖੇਗਾ" + + "ਬਲੂਟੁੱਥ ਚਾਲੂ ਰਹਿੰਦਾ ਹੈ" - "ਤੁਹਾਡਾ ਫ਼ੋਨ ਹਵਾਈ-ਜਹਾਜ਼ ਮੋਡ ਵਿੱਚ ਬਲੂਟੁੱਥ ਨੂੰ ਚਾਲੂ ਰੱਖਣਾ ਯਾਦ ਰੱਖਦਾ ਹੈ। ਜੇ ਤੁਸੀਂ ਇਸਨੂੰ ਚਾਲੂ ਨਹੀਂ ਰੱਖਣਾ ਚਾਹੁੰਦੇ, ਤਾਂ ਬਲੂਟੁੱਥ ਨੂੰ ਬੰਦ ਕਰੋ।" + + "ਵਾਈ-ਫਾਈ ਅਤੇ ਬਲੂਟੁੱਥ ਚਾਲੂ ਰਹਿੰਦੇ ਹਨ" - "ਤੁਹਾਡਾ ਫ਼ੋਨ ਹਵਾਈ-ਜਹਾਜ਼ ਮੋਡ ਵਿੱਚ ਵਾਈ-ਫਾਈ ਅਤੇ ਬਲੂਟੁੱਥ ਨੂੰ ਚਾਲੂ ਰੱਖਣਾ ਯਾਦ ਰੱਖਦਾ ਹੈ। ਜੇ ਤੁਸੀਂ ਇਨ੍ਹਾਂ ਨੂੰ ਚਾਲੂ ਨਹੀਂ ਰੱਖਣਾ ਚਾਹੁੰਦੇ, ਤਾਂ ਵਾਈ-ਫਾਈ ਅਤੇ ਬਲੂਟੁੱਥ ਨੂੰ ਬੰਦ ਕਰੋ।" + + diff --git a/android/app/res/values-pl/strings.xml b/android/app/res/values-pl/strings.xml index 1db2aa19cc5..2f35fbfc2f0 100644 --- a/android/app/res/values-pl/strings.xml +++ b/android/app/res/values-pl/strings.xml @@ -130,9 +130,12 @@ "Nie można przenieść plików przekraczających 4 GB" "Nawiązywanie połączeń przez Bluetooth" "Bluetooth włączony w trybie samolotowym" - "Jeśli pozostawisz włączony Bluetooth, telefon zachowa się podobnie przy kolejnym przejściu w tryb samolotowy" + + "Bluetooth pozostanie włączony" - "Bluetooth na telefonie pozostaje włączony w trybie samolotowym. Wyłącz Bluetooth, jeśli nie chcesz, żeby pozostawał włączony." + + "Wi-Fi i Bluetooth pozostają włączone" - "Wi-Fi i Bluetooth na telefonie pozostają włączone w trybie samolotowym. Wyłącz Wi-Fi i Bluetooth, jeśli nie chcesz, żeby funkcje te pozostawały włączone." + + diff --git a/android/app/res/values-pt-rPT/strings.xml b/android/app/res/values-pt-rPT/strings.xml index 35b530a2032..f0bd98677dc 100644 --- a/android/app/res/values-pt-rPT/strings.xml +++ b/android/app/res/values-pt-rPT/strings.xml @@ -130,9 +130,9 @@ "Não é possível transferir os ficheiros com mais de 4 GB." "Ligar ao Bluetooth" "Bluetooth ativado no modo de avião" - "Se mantiver o Bluetooth ativado, o telemóvel vai lembrar-se de o manter ativado da próxima vez que estiver no modo de avião" + "Se mantiver o Bluetooth ativado, o dispositivo vai lembrar-se de o manter ativado da próxima vez que estiver no modo de avião" "O Bluetooth mantém-se ativado" - "O seu telemóvel mantém o Bluetooth ativado no modo de avião. Desative o Bluetooth se não quiser que fique ativado." + "O seu dispositivo lembra-se de manter o Bluetooth ativado no modo de avião. Desative o Bluetooth se não quiser que fique ativado." "O Wi-Fi e o Bluetooth mantêm-se ativados" - "O seu telemóvel mantém o Wi-Fi e o Bluetooth ativados no modo de avião. Desative o Wi-Fi e o Bluetooth se não quiser que fiquem ativados." + "O seu dispositivo lembra-se de manter o Wi-Fi e o Bluetooth ativados no modo de avião. Desative o Wi-Fi e o Bluetooth se não quiser que fiquem ativados." diff --git a/android/app/res/values-pt/strings.xml b/android/app/res/values-pt/strings.xml index b7e878172a2..c8dbf2b569f 100644 --- a/android/app/res/values-pt/strings.xml +++ b/android/app/res/values-pt/strings.xml @@ -130,9 +130,12 @@ "Não é possível transferir arquivos maiores que 4 GB" "Conectar ao Bluetooth" "Bluetooth ativado no modo avião" - "Se você escolher manter o Bluetooth ativado, essa configuração vai ser aplicada na próxima vez que usar o modo avião" + + "O Bluetooth fica ativado" - "O smartphone vai manter o Bluetooth ativado no modo avião. Ele pode ser desativado manualmente se você preferir." + + "O Wi-Fi e o Bluetooth ficam ativados" - "O smartphone vai manter o Wi-Fi e o Bluetooth ativados no modo avião. Eles podem ser desativados manualmente se você preferir." + + diff --git a/android/app/res/values-ro/strings.xml b/android/app/res/values-ro/strings.xml index 42d968415ad..f2807c6c355 100644 --- a/android/app/res/values-ro/strings.xml +++ b/android/app/res/values-ro/strings.xml @@ -130,9 +130,12 @@ "Fișierele mai mari de 4 GB nu pot fi transferate" "Conectează-te la Bluetooth" "Bluetooth activat în modul Avion" - "Dacă păstrezi Bluetooth activat, telefonul tău va reține să-l păstreze activat data viitoare când ești în modul Avion" + + "Bluetooth rămâne activat" - "Telefonul reține să păstreze Bluetooth activat în modul Avion. Dezactivează Bluetooth dacă nu vrei să rămână activat." + + "Wi-Fi și Bluetooth rămân activate" - "Telefonul reține să păstreze funcțiile Wi-Fi și Bluetooth activate în modul Avion. Dezactivează Wi-Fi și Bluetooth dacă nu vrei să rămână activate." + + diff --git a/android/app/res/values-ru/strings.xml b/android/app/res/values-ru/strings.xml index 9519a3a37f1..f3a7ff53948 100644 --- a/android/app/res/values-ru/strings.xml +++ b/android/app/res/values-ru/strings.xml @@ -130,9 +130,12 @@ "Можно перенести только файлы размером до 4 ГБ." "Подключиться по Bluetooth" "Функция Bluetooth будет включена в режиме полета" - "Если не отключить функцию Bluetooth, в следующий раз она останется включенной в режиме полета." + + "Функция Bluetooth остается включенной" - "Функция Bluetooth останется включенной в режиме полета. Вы можете отключить ее, если хотите." + + "Функции Wi‑Fi и Bluetooth остаются включенными" - "Wi‑Fi и Bluetooth останутся включенными в режиме полета. Вы можете отключить их, если хотите." + + diff --git a/android/app/res/values-si/strings.xml b/android/app/res/values-si/strings.xml index 2757685fa62..e560e6bb315 100644 --- a/android/app/res/values-si/strings.xml +++ b/android/app/res/values-si/strings.xml @@ -130,9 +130,12 @@ "4GBට වඩා විශාල ගොනු මාරු කළ නොහැකිය" "බ්ලූටූත් වෙත සබඳින්න" "අහස්යානා ආකාරයේ බ්ලූටූත් ක්‍රියාත්මකයි" - "ඔබ බ්ලූටූත් ක්‍රියාත්මක කර තබා ගන්නේ නම්, ඔබ අහස්යානා ආකාරයේ සිටින මීළඟ වතාවේ එය ක්‍රියාත්මක කිරීමට ඔබේ දුරකථනයට මතක තිබෙනු ඇත." + + "බ්ලූටූත් ක්‍රියාත්මකව පවතී" - "ඔබේ දුරකථනයට අහස්යානා ආකාරයේ බ්ලූටූත් ක්‍රියාත්මකව තබා ගැනීමට මතකයි. ඔබට බ්ලූටූත් ක්‍රියාත්මක වීමට අවශ්‍ය නොවේ නම් එය ක්‍රියාවිරහිත කරන්න." + + "Wi-Fi සහ බ්ලූටූත් ක්‍රියාත්මකව පවතී" - "ඔබේ දුරකථනයට අහස්යානා ආකාරයේ Wi-Fi සහ බ්ලූටූත් ක්‍රියාත්මකව තබා ගැනීමට මතකයි. Wi-Fi සහ බ්ලූටූත් ඒවා ක්‍රියාත්මක වීමට ඔබට අවශ්‍ය නැතිනම් ක්‍රියා විරහිත කරන්න." + + diff --git a/android/app/res/values-sk/strings.xml b/android/app/res/values-sk/strings.xml index 4b1c9782df2..b127a82d3ef 100644 --- a/android/app/res/values-sk/strings.xml +++ b/android/app/res/values-sk/strings.xml @@ -130,9 +130,12 @@ "Súbory väčšie ako 4 GB sa nedajú preniesť" "Pripojiť k zariadeniu Bluetooth" "Rozhranie Bluetooth bude v režime v lietadle zapnuté" - "Ak ponecháte rozhranie Bluetooth zapnuté, váš telefón si zapamätá, že ho má ponechať zapnuté pri ďalšom aktivovaní režimu v lietadle" + + "Rozhranie Bluetooth zostane zapnuté" - "Telefón si pamätá, aby v režime v lietadle nevypínal rozhranie Bluetooth. Ak ho nechcete ponechať zapnuté, vypnite ho." + + "Wi‑Fi a Bluetooth zostanú zapnuté" - "Telefón si pamätá, aby v režime v lietadle nevypínal Wi‑Fi ani Bluetooth. Ak ich nechcete ponechať zapnuté, vypnite ich." + + diff --git a/android/app/res/values-sl/strings.xml b/android/app/res/values-sl/strings.xml index 696e4260fc7..5ad91342a33 100644 --- a/android/app/res/values-sl/strings.xml +++ b/android/app/res/values-sl/strings.xml @@ -130,9 +130,12 @@ "Datotek, večjih od 4 GB, ni mogoče prenesti" "Povezovanje z Bluetoothom" "Bluetooth je vklopljen v načinu za letalo" - "Če pustite Bluetooth vklopljen, bo telefon ob naslednjem preklopu na način za letalo pustil Bluetooth vklopljen." + + "Bluetooth ostane vklopljen" - "Telefon v načinu za letalo pusti Bluetooth vklopljen. Če ne želite, da ostane vklopljen, izklopite vmesnik Bluetooth." + + "Wi-Fi in Bluetooth ostaneta vklopljena" - "Telefon v načinu za letalo pusti Wi-Fi in Bluetooth vklopljena. Če ne želite, da Wi-Fi in Bluetooth ostaneta vklopljena, ju izklopite." + + diff --git a/android/app/res/values-sq/strings.xml b/android/app/res/values-sq/strings.xml index 16a94408ba8..79f548588b3 100644 --- a/android/app/res/values-sq/strings.xml +++ b/android/app/res/values-sq/strings.xml @@ -130,9 +130,12 @@ "Skedarët më të mëdhenj se 4 GB nuk mund të transferohen" "Lidhu me Bluetooth" "Bluetooth-i aktiv në modalitetin e aeroplanit" - "Nëse e mban Bluetooth-in të aktivizuar, telefoni yt do të kujtohet ta mbajë atë të aktivizuar herën tjetër kur të jesh në modalitetin e aeroplanit" + + "Bluetooth qëndron i aktivizuar" - "Telefoni yt kujtohet që ta mbajë Bluetooth-in të aktivizuar në modalitetin e aeroplanit. Çaktivizo Bluetooth-in nëse nuk dëshiron që të qëndrojë i aktivizuar." + + "Wi-Fi dhe Bluetooth-i qëndrojnë aktivë" - "Telefoni yt kujtohet që ta mbajë Wi-Fi dhe Bluetooth-in të aktivizuar në modalitetin e aeroplanit. Çaktivizo Wi-Fi dhe Bluetooth-in nëse nuk dëshiron që të qëndrojnë aktivë." + + diff --git a/android/app/res/values-sr/strings.xml b/android/app/res/values-sr/strings.xml index 1ead9d5024b..44277d78622 100644 --- a/android/app/res/values-sr/strings.xml +++ b/android/app/res/values-sr/strings.xml @@ -130,9 +130,12 @@ "Не могу да се преносе датотеке веће од 4 GB" "Повежи са Bluetooth-ом" "Bluetooth је укључен у режиму рада у авиону" - "Ако одлучите да не искључујете Bluetooth, телефон ће запамтити да га не искључује следећи пут када будете у режиму рада у авиону" + + "Bluetooth се не искључује" - "Телефон памти да не треба да искључује Bluetooth у режиму рада у авиону. Искључите Bluetooth ако не желите да остане укључен." + + "WiFi и Bluetooth остају укључени" - "Телефон памти да не треба да искључује WiFi и Bluetooth у режиму рада у авиону. Искључите WiFi и Bluetooth ако не желите да остану укључени." + + diff --git a/android/app/res/values-sv/strings.xml b/android/app/res/values-sv/strings.xml index 12678538125..e46be12a9e7 100644 --- a/android/app/res/values-sv/strings.xml +++ b/android/app/res/values-sv/strings.xml @@ -130,9 +130,12 @@ "Det går inte att överföra filer som är större än 4 GB" "Anslut till Bluetooth" "Håll Bluetooth aktiverat i flygplansläge" - "Om du håller wifi aktiverat kommer telefonen ihåg att hålla det aktiverat nästa gång du använder flygplansläge." + + "Bluetooth förblir aktiverat" - "Telefonen kommer ihåg att hålla Bluetooth aktiverat i flygplansläge. Inaktivera Bluetooth om du inte vill att det ska hållas aktiverat." + + "Wifi och Bluetooth ska vara aktiverade" - "Telefonen kommer ihåg att hålla wifi och Bluetooth aktiverade i flygplansläge. Du kan inaktivera wifi och Bluetooth om du inte vill hålla dem aktiverade." + + diff --git a/android/app/res/values-sw/strings.xml b/android/app/res/values-sw/strings.xml index 4ebf5cccfc2..8a83f0f6b12 100644 --- a/android/app/res/values-sw/strings.xml +++ b/android/app/res/values-sw/strings.xml @@ -130,9 +130,12 @@ "Haiwezi kutuma faili zinazozidi GB 4" "Unganisha kwenye Bluetooth" "Bluetooth itawashwa katika hali ya ndegeni" - "Usipozima Bluetooth, simu yako itakumbuka kuiwasha wakati mwingine unapokuwa katika hali ya ndegeni" + + "Bluetooth itaendelea kuwaka" - "Simu yako itaendelea kuwasha Bluetooth katika hali ya ndegeni. Zima Bluetooth iwapo hutaki iendelee kuwaka." + + "Wi-Fi na Bluetooth zitaendelea kuwaka" - "Simu yako itaendelea kuwasha Wi-Fi na Bluetooth ukiwa katika hali ya ndegeni. Zima Wi-Fi na Bluetooth ikiwa hutaki ziendelee kuwaka." + + diff --git a/android/app/res/values-ta/strings.xml b/android/app/res/values-ta/strings.xml index ffd800cf343..76e95005131 100644 --- a/android/app/res/values-ta/strings.xml +++ b/android/app/res/values-ta/strings.xml @@ -130,9 +130,12 @@ "4ஜி.பை.க்கு மேலிருக்கும் ஃபைல்களை இடமாற்ற முடியாது" "புளூடூத் உடன் இணை" "விமானப் பயன்முறையில் புளூடூத்தை இயக்குதல்" - "புளூடூத்தை இயக்கத்தில் வைத்திருந்தால், அடுத்த முறை நீங்கள் விமானப் பயன்முறையைப் பயன்படுத்தும்போது உங்கள் மொபைல் புளூடூத்தை இயக்கத்தில் வைக்கும்" + + "புளூடூத் இயக்கத்திலேயே இருக்கும்" - "விமானப் பயன்முறையில் புளூடூத்தை உங்கள் மொபைல் இயக்கத்திலேயே வைத்திருக்கும். புளூடூத்தை இயக்க விரும்பவில்லை என்றால் அதை முடக்கவும்." + + "வைஃபையும் புளூடூத்தும் இயக்கத்திலேயே இருத்தல்" - "விமானப் பயன்முறையில் வைஃபையையும் புளூடூத்தையும் உங்கள் மொபைல் இயக்கத்திலேயே வைத்திருக்கும். வைஃபை மற்றும் புளூடூத்தை இயக்க விரும்பவில்லை என்றால் அவற்றை முடக்கவும்." + + diff --git a/android/app/res/values-te/strings.xml b/android/app/res/values-te/strings.xml index 513e12b95e9..488d53f8992 100644 --- a/android/app/res/values-te/strings.xml +++ b/android/app/res/values-te/strings.xml @@ -130,9 +130,12 @@ "4GB కన్నా పెద్ద ఫైళ్లు బదిలీ చేయబడవు" "బ్లూటూత్‌కు కనెక్ట్ చేయి" "విమానం మోడ్‌లో బ్లూటూత్ ఆన్ చేయబడింది" - "మీరు బ్లూటూత్‌ను ఆన్‌లో ఉంచినట్లయితే, మీరు తదుపరిసారి విమానం మోడ్‌లో ఉన్నప్పుడు దాన్ని ఆన్‌లో ఉంచాలని మీ ఫోన్ గుర్తుంచుకుంటుంది" + + "బ్లూటూత్ ఆన్‌లో ఉంటుంది" - "విమానం మోడ్‌లో బ్లూటూత్ ఆన్‌లో ఉంచాలని మీ ఫోన్ గుర్తుంచుకుంటుంది. బ్లూటూత్ ఆన్‌లో ఉండకూడదనుకుంటే దాన్ని ఆఫ్ చేయండి." + + "Wi-Fi, బ్లూటూత్ ఆన్‌లో ఉంటాయి" - "మీ ఫోన్ విమానం మోడ్‌లో Wi‑Fiని, బ్లూటూత్‌ని ఆన్‌లో ఉంచాలని గుర్తుంచుకుంటుంది. Wi-Fi, బ్లూటూత్ ఆన్‌లో ఉండకూడదనుకుంటే వాటిని ఆఫ్ చేయండి." + + diff --git a/android/app/res/values-th/strings.xml b/android/app/res/values-th/strings.xml index 91763b102a0..55c465d1196 100644 --- a/android/app/res/values-th/strings.xml +++ b/android/app/res/values-th/strings.xml @@ -130,9 +130,12 @@ "โอนไฟล์ที่มีขนาดใหญ่กว่า 4 GB ไม่ได้" "เชื่อมต่อบลูทูธ" "บลูทูธเปิดอยู่ในโหมดบนเครื่องบิน" - "หากเปิดบลูทูธไว้ โทรศัพท์จะจำว่าต้องเปิดบลูทูธในครั้งถัดไปที่คุณอยู่ในโหมดบนเครื่องบิน" + + "บลูทูธเปิดอยู่" - "โทรศัพท์จำว่าจะต้องเปิดบลูทูธไว้ในโหมดบนเครื่องบิน ปิดบลูทูธหากคุณไม่ต้องการให้เปิดไว้" + + "Wi-Fi และบลูทูธยังเปิดอยู่" - "โทรศัพท์จำว่าจะต้องเปิด Wi-Fi และบลูทูธไว้ในโหมดบนเครื่องบิน ปิด Wi-Fi และบลูทูธหากคุณไม่ต้องการให้เปิดไว้" + + diff --git a/android/app/res/values-tl/strings.xml b/android/app/res/values-tl/strings.xml index 93c6a90be2f..cbded17d4fa 100644 --- a/android/app/res/values-tl/strings.xml +++ b/android/app/res/values-tl/strings.xml @@ -130,9 +130,12 @@ "Hindi maililipat ang mga file na mas malaki sa 4GB" "Kumonekta sa Bluetooth" "Naka-on ang Bluetooth sa airplane mode" - "Kung papanatilihin mong naka-on ang Bluetooth, tatandaan ng iyong telepono na panatilihin itong naka-on sa susunod na nasa airplane mode ka" + + "Mananatiling naka-on ang Bluetooth" - "Tinatandaan ng iyong telepono na panatilihing naka-on ang Bluetooth habang nasa airplane mode. I-off ang Bluetooth kung ayaw mo itong manatiling naka-on." + + "Mananatiling naka-on ang Wi-Fi at Bluetooth" - "Tinatandaan ng iyong telepono na panatilihing naka-on ang Wi-Fi at Bluetooth habang nasa airplane mode. I-off ang Wi-Fi at Bluetooth kung ayaw mong manatiling naka-on ang mga ito." + + diff --git a/android/app/res/values-tr/strings.xml b/android/app/res/values-tr/strings.xml index c1a650f337c..60ae75f5ba2 100644 --- a/android/app/res/values-tr/strings.xml +++ b/android/app/res/values-tr/strings.xml @@ -130,9 +130,12 @@ "4 GB\'tan büyük dosyalar aktarılamaz" "Bluetooth\'a bağlan" "Uçak modundayken Bluetooth açık" - "Kablosuz bağlantıyı açık tutarsanız telefonunuz, daha sonra tekrar uçak modunda olduğunuzda kablosuz bağlantıyı açık tutar" + + "Bluetooth açık kalır" - "Telefonunuz, uçak modundayken Bluetooth\'u açık tutmayı hatırlar. Açık kalmasını istemiyorsanız Bluetooth\'u kapatın." + + "Kablosuz bağlantı ve Bluetooth açık kalır" - "Telefonunuz, uçak modundayken kablosuz bağlantıyı ve Bluetooth\'u açık tutmayı hatırlar. Açık kalmasını istemiyorsanız kablosuz bağlantıyı ve Bluetooth\'u kapatın." + + diff --git a/android/app/res/values-uk/strings.xml b/android/app/res/values-uk/strings.xml index 348ae4c3adb..15698f516f3 100644 --- a/android/app/res/values-uk/strings.xml +++ b/android/app/res/values-uk/strings.xml @@ -130,9 +130,12 @@ "Не можна перенести файли, більші за 4 ГБ" "Підключитися до Bluetooth" "Bluetooth увімкнено в режимі польоту" - "Якщо ви не вимкнете Bluetooth на телефоні, ця функція залишатиметься ввімкненою під час наступного використання режиму польоту" + + "Bluetooth не буде вимкнено" - "У режимі польоту функція Bluetooth на телефоні залишатиметься ввімкненою. За бажання її можна вимкнути." + + "Wi-Fi і Bluetooth залишаються ввімкненими" - "У режимі польоту функції Wi-Fi і Bluetooth на телефоні залишатимуться ввімкненими. За бажання їх можна вимкнути." + + diff --git a/android/app/res/values-ur/strings.xml b/android/app/res/values-ur/strings.xml index c8d8480f46f..d0a98565193 100644 --- a/android/app/res/values-ur/strings.xml +++ b/android/app/res/values-ur/strings.xml @@ -130,9 +130,12 @@ "‏4GB سے بڑی فائلیں منتقل نہیں کی جا سکتیں" "بلوٹوتھ سے منسلک کریں" "ہوائی جہاز وضع میں بلوٹوتھ آن ہے" - "اگر آپ بلوٹوتھ کو آن رکھتے ہیں تو آپ کا فون آپ کے اگلی مرتبہ ہوائی جہاز وضع میں ہونے پر اسے آن رکھنا یاد رکھے گا" + + "بلوٹوتھ آن رہتا ہے" - "آپ کا فون ہوائی جہاز وضع میں بلوٹوتھ کو آن رکھنا یاد رکھتا ہے۔ اگر آپ نہیں چاہتے ہیں کہ بلوٹوتھ آن رہے تو اسے آف کریں۔" + + "‏Wi-Fi اور بلوٹوتھ آن رہنے دیں" - "‏آپ کا فون ہوائی جہاز وضع میں Wi-Fi اور بلوٹوتھ کو آن رکھنا یاد رکھتا ہے۔ اگر آپ نہیں چاہتے ہیں کہ Wi-Fi اور بلوٹوتھ آن رہیں تو انہیں آف کریں۔" + + diff --git a/android/app/res/values-uz/strings.xml b/android/app/res/values-uz/strings.xml index f0f22bd7ac3..057813aa624 100644 --- a/android/app/res/values-uz/strings.xml +++ b/android/app/res/values-uz/strings.xml @@ -130,9 +130,12 @@ "4 GBdan katta hajmli videolar o‘tkazilmaydi" "Bluetoothga ulanish" "Bluetooth parvoz rejimida yoniq" - "Bluetooth yoniq qolsa, telefon keyingi safar parvoz rejimida ham uni yoniq qoldiradi." + + "Bluetooth yoniq turadi" - "Telefoningiz parvoz rejimida Bluetooth yoqilganini eslab qoladi. Yoniq qolmasligi uchun Bluetooth aloqasini oʻchiring." + + "Wi-Fi va Bluetooth yoniq qoladi" - "Telefoningiz parvoz rejimida Wi‑Fi va Bluetooth yoqilganini eslab qoladi. Yoniq qolmasligi uchun Wi-Fi va Bluetooth aloqasini oʻchiring." + + diff --git a/android/app/res/values-vi/strings.xml b/android/app/res/values-vi/strings.xml index 55ceb7c126a..b3cef943ef5 100644 --- a/android/app/res/values-vi/strings.xml +++ b/android/app/res/values-vi/strings.xml @@ -130,9 +130,12 @@ "Không thể chuyển những tệp lớn hơn 4 GB" "Kết nối với Bluetooth" "Bluetooth đang bật ở chế độ trên máy bay" - "Nếu bạn không tắt Bluetooth, điện thoại sẽ luôn bật Bluetooth vào lần tiếp theo bạn dùng chế độ trên máy bay" + + "Bluetooth luôn bật" - "Điện thoại của bạn sẽ luôn bật Bluetooth ở chế độ trên máy bay. Nếu không muốn như vậy thì bạn có thể tắt Bluetooth." + + "Wi-Fi và Bluetooth vẫn đang bật" - "Điện thoại của bạn sẽ luôn bật Wi-Fi và Bluetooth ở chế độ trên máy bay. Tắt Wi-Fi và Bluetooth nếu bạn không muốn tiếp tục bật." + + diff --git a/android/app/res/values-zh-rCN/strings.xml b/android/app/res/values-zh-rCN/strings.xml index 05bc8d23ad5..1262f0ea21c 100644 --- a/android/app/res/values-zh-rCN/strings.xml +++ b/android/app/res/values-zh-rCN/strings.xml @@ -130,9 +130,12 @@ "无法传输 4GB 以上的文件" "连接到蓝牙" "在飞行模式下蓝牙保持开启状态" - "如果您不关闭蓝牙,那么您下次进入飞行模式时手机将记住保持开启蓝牙" + + "蓝牙保持开启状态" - "在飞行模式下手机将记住保持开启蓝牙。如果您不想保持开启和蓝牙,请关闭蓝牙。" + + "WLAN 和蓝牙保持开启状态" - "在飞行模式下手机将记住保持开启 WLAN 和蓝牙。如果您不想保持开启 WLAN 和蓝牙,请关闭 WLAN 和蓝牙。" + + diff --git a/android/app/res/values-zh-rHK/strings.xml b/android/app/res/values-zh-rHK/strings.xml index 4ae1ceedeaa..8275cef234d 100644 --- a/android/app/res/values-zh-rHK/strings.xml +++ b/android/app/res/values-zh-rHK/strings.xml @@ -130,9 +130,12 @@ "無法轉移 4 GB 以上的檔案" "連接藍牙" "在飛航模式中保持藍牙開啟" - "如果你不關閉藍牙,下次手機進入飛行模式時,藍牙將保持開啟" + + "保持藍牙連線" - "手機會記得在飛行模式下保持藍牙開啟。如果你不希望保持開啟,請關閉藍牙。" + + "Wi-Fi 和藍牙保持開啟" - "手機會記得在飛行模式下保持 Wi-Fi 及藍牙開啟。如果你不希望保持開啟,請關閉 Wi-Fi 及藍牙。" + + diff --git a/android/app/res/values-zh-rTW/strings.xml b/android/app/res/values-zh-rTW/strings.xml index 9626544969d..e3ab7f9277c 100644 --- a/android/app/res/values-zh-rTW/strings.xml +++ b/android/app/res/values-zh-rTW/strings.xml @@ -130,9 +130,12 @@ "無法轉移大於 4GB 的檔案" "使用藍牙連線" "在飛航模式下保持藍牙開啟狀態" - "如果不關閉藍牙,下次手機進入飛航模式時,藍牙將保持開啟" + + "藍牙會保持開啟狀態" - "手機會記得在飛航模式下保持藍牙開啟。如果不要保持開啟,請關閉藍牙。" + + "Wi-Fi 和藍牙會保持開啟狀態" - "手機會記得在飛航模式下保持 Wi-Fi 和藍牙開啟。如果不要保持開啟,請關閉 Wi-Fi 和藍牙。" + + diff --git a/android/app/res/values-zu/strings.xml b/android/app/res/values-zu/strings.xml index 3d6d007846f..3949f2ee5ce 100644 --- a/android/app/res/values-zu/strings.xml +++ b/android/app/res/values-zu/strings.xml @@ -130,9 +130,12 @@ "Amafayela amakhulu kuno-4GB awakwazi ukudluliselwa" "Xhumeka ku-Bluetooth" "I-Bluetooth ivuliwe kumodi yendiza" - "Uma ugcina i-Wi‑Fi ivuliwe, ifoni yakho izokhumbula ukuyigcina ivuliwe ngesikhathi esilandelayo uma ukumodi yendiza." + + "I-Bluetooth ihlala ivuliwe" - "Ifoni yakho ikhumbula ukugcina i-Bluetooth ivuliwe kumodi yendiza. Vala i-Bluetooth uma ungafuni ukuthi ihlale ivuliwe." + + "I-Wi-Fi ne-Bluetooth kuhlala kuvuliwe" - "Ifoni yakho ikhumbula ukugcina i-Wi-Fi ne-Bluetooth kuvuliwe kumodi yendiza. Vala i-Wi-Fi ne-Bluetooth uma ungafuni ukuthi ihlale ivuliwe." + + -- GitLab From 8f2c782c4cfa816faaa31339d1fa6ed52e066a64 Mon Sep 17 00:00:00 2001 From: Sal Savage Date: Tue, 16 May 2023 13:55:27 -0700 Subject: [PATCH 0076/2405] Use profile names instead of integer constants when logging It is far more understandable in logs to see profile=A2DP_SINK instead of profile=11. This change updates a few spots we use profile IDs in logs messages to instead use the result of getProfileName. Many other places in code have been udpated to do this already. Tag: #refactor Bug: 282988270 Test: atest BluetoothInstrumentationTests Change-Id: If47c46413f0f2567643561ec267ac09f86ef3aab --- .../bluetooth/btservice/AdapterProperties.java | 12 ++++++------ .../com/android/bluetooth/btservice/PhonePolicy.java | 10 ++++++---- .../bluetooth/btservice/SilenceDeviceManager.java | 6 ++++-- 3 files changed, 16 insertions(+), 12 deletions(-) diff --git a/android/app/src/com/android/bluetooth/btservice/AdapterProperties.java b/android/app/src/com/android/bluetooth/btservice/AdapterProperties.java index fbd9c2d8bdf..f2406efe1ce 100644 --- a/android/app/src/com/android/bluetooth/btservice/AdapterProperties.java +++ b/android/app/src/com/android/bluetooth/btservice/AdapterProperties.java @@ -729,17 +729,17 @@ class AdapterProperties { metricId, device.getName()); MetricsLogger.getInstance().logSanitizedBluetoothDeviceName(metricId, device.getName()); } - Log.d(TAG, - "PROFILE_CONNECTION_STATE_CHANGE: profile=" + profile + ", device=" + device + ", " - + prevState + " -> " + state); + Log.d(TAG, "PROFILE_CONNECTION_STATE_CHANGE: profile=" + + BluetoothProfile.getProfileName(profile) + ", device=" + device + ", " + + prevState + " -> " + state); BluetoothStatsLog.write(BluetoothStatsLog.BLUETOOTH_CONNECTION_STATE_CHANGED, state, 0 /* deprecated */, profile, mService.obfuscateAddress(device), metricId, 0, -1); if (!isNormalStateTransition(prevState, state)) { - Log.w(TAG, - "PROFILE_CONNECTION_STATE_CHANGE: unexpected transition for profile=" + profile - + ", device=" + device + ", " + prevState + " -> " + state); + Log.w(TAG, "PROFILE_CONNECTION_STATE_CHANGE: unexpected transition for profile=" + + BluetoothProfile.getProfileName(profile) + + ", device=" + device + ", " + prevState + " -> " + state); } sendConnectionStateChange(device, profile, state, prevState); } diff --git a/android/app/src/com/android/bluetooth/btservice/PhonePolicy.java b/android/app/src/com/android/bluetooth/btservice/PhonePolicy.java index ca333486150..b21ffee5d0f 100644 --- a/android/app/src/com/android/bluetooth/btservice/PhonePolicy.java +++ b/android/app/src/com/android/bluetooth/btservice/PhonePolicy.java @@ -506,8 +506,9 @@ class PhonePolicy { @RequiresPermission(android.Manifest.permission.BLUETOOTH_PRIVILEGED) private void processProfileStateChanged(BluetoothDevice device, int profileId, int nextState, int prevState) { - debugLog("processProfileStateChanged, device=" + device + ", profile=" + profileId + ", " - + prevState + " -> " + nextState); + debugLog("processProfileStateChanged, device=" + device + ", profile=" + + BluetoothProfile.getProfileName(profileId) + ", " + prevState + " -> " + + nextState); if (((profileId == BluetoothProfile.A2DP) || (profileId == BluetoothProfile.HEADSET) || (profileId == BluetoothProfile.LE_AUDIO) || (profileId == BluetoothProfile.CSIP_SET_COORDINATOR) @@ -544,8 +545,9 @@ class PhonePolicy { * @param device is the device we just made the active device */ private void processActiveDeviceChanged(BluetoothDevice device, int profileId) { - debugLog("processActiveDeviceChanged, device=" + device + ", profile=" + profileId - + " isDualModeAudioEnabled=" + isDualModeAudioEnabled()); + debugLog("processActiveDeviceChanged, device=" + device + ", profile=" + + BluetoothProfile.getProfileName(profileId) + " isDualModeAudioEnabled=" + + isDualModeAudioEnabled()); if (device != null) { mDatabaseManager.setConnection(device, profileId == BluetoothProfile.A2DP); diff --git a/android/app/src/com/android/bluetooth/btservice/SilenceDeviceManager.java b/android/app/src/com/android/bluetooth/btservice/SilenceDeviceManager.java index 405c566e3d1..c75ad49b0b8 100644 --- a/android/app/src/com/android/bluetooth/btservice/SilenceDeviceManager.java +++ b/android/app/src/com/android/bluetooth/btservice/SilenceDeviceManager.java @@ -300,7 +300,8 @@ public class SilenceDeviceManager { void addConnectedDevice(BluetoothDevice device, int profile) { if (VERBOSE) { - Log.d(TAG, "addConnectedDevice: " + device + ", profile:" + profile); + Log.d(TAG, "addConnectedDevice: " + device + ", profile:" + + BluetoothProfile.getProfileName(profile)); } switch (profile) { case BluetoothProfile.A2DP: @@ -318,7 +319,8 @@ public class SilenceDeviceManager { void removeConnectedDevice(BluetoothDevice device, int profile) { if (VERBOSE) { - Log.d(TAG, "removeConnectedDevice: " + device + ", profile:" + profile); + Log.d(TAG, "removeConnectedDevice: " + device + ", profile:" + + BluetoothProfile.getProfileName(profile)); } switch (profile) { case BluetoothProfile.A2DP: -- GitLab From a17ecae87dc86c2526bae5886bba4415f057afb8 Mon Sep 17 00:00:00 2001 From: Hsin-chen Chuang Date: Wed, 17 May 2023 08:44:22 +0800 Subject: [PATCH 0077/2405] floss: Avoid reading DIS info when no GATT connection Bug: 279133545 Tag: #floss Test: CQ and CrOS test bluetooth_AdapterLEHealth Change-Id: I2903dffaf4c690dac33af9c29cf10667cb5172d3 --- system/bta/dm/bta_dm_act.cc | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/system/bta/dm/bta_dm_act.cc b/system/bta/dm/bta_dm_act.cc index 7a363a3d185..7c55ab3d26f 100644 --- a/system/bta/dm/bta_dm_act.cc +++ b/system/bta/dm/bta_dm_act.cc @@ -1490,7 +1490,8 @@ void bta_dm_search_cmpl() { bta_dm_search_cb.gatt_disc_active = false; #if TARGET_FLOSS - if (DIS_ReadDISInfo(bta_dm_search_cb.peer_bdaddr, bta_dm_read_dis_cmpl, + if (conn_id != GATT_INVALID_CONN_ID && + DIS_ReadDISInfo(bta_dm_search_cb.peer_bdaddr, bta_dm_read_dis_cmpl, DIS_ATTR_PNP_ID_BIT)) { return; } -- GitLab From 9830b39e0bfca275a9e475c8d2185b2b85ad2536 Mon Sep 17 00:00:00 2001 From: Hsin-chen Chuang Date: Mon, 15 May 2023 16:33:05 +0800 Subject: [PATCH 0078/2405] DIS_ReadDISInfo: Connect GATT when failed to get conn_id Bug: 279133545 Test: CQ Change-Id: I36230e8c6adc1ebc06145201fbc5b54d58122368 --- system/stack/srvc/srvc_dis.cc | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/system/stack/srvc/srvc_dis.cc b/system/stack/srvc/srvc_dis.cc index 3b75e8a6e41..62cfd7c4983 100644 --- a/system/stack/srvc/srvc_dis.cc +++ b/system/stack/srvc/srvc_dis.cc @@ -428,7 +428,7 @@ tDIS_STATUS DIS_SrUpdate(tDIS_ATTR_BIT dis_attr_bit, tDIS_ATTR* p_info) { * * Description Read remote device DIS information. * - * Returns void + * Returns true on success, false otherwise * ******************************************************************************/ bool DIS_ReadDISInfo(const RawAddress& peer_bda, tDIS_READ_CBACK* p_cback, @@ -453,8 +453,10 @@ bool DIS_ReadDISInfo(const RawAddress& peer_bda, tDIS_READ_CBACK* p_cback, << StringPrintf(" cl_read_uuid: 0x%04x", dis_attr_uuid[dis_cb.dis_read_uuid_idx]); - GATT_GetConnIdIfConnected(srvc_eng_cb.gatt_if, peer_bda, &conn_id, - BT_TRANSPORT_LE); + if (!GATT_GetConnIdIfConnected(srvc_eng_cb.gatt_if, peer_bda, &conn_id, + BT_TRANSPORT_LE)) { + conn_id = GATT_INVALID_CONN_ID; + } /* need to enhance it as multiple service is needed */ srvc_eng_request_channel(peer_bda, SRVC_ID_DIS); -- GitLab From c8964ff703be1c2bd4c118954de5b5638e057c8c Mon Sep 17 00:00:00 2001 From: Chris Manton Date: Thu, 6 Apr 2023 22:40:23 +0000 Subject: [PATCH 0079/2405] search_module: Shift to using gatt interface Bug: 281757908 Test: Manual Change-Id: I84165f9596a3b531263c398d65ac6063120a485c --- system/bta/dm/bta_dm_act.cc | 217 +++++++++++++++++++++++++++++++---- system/bta/dm/bta_dm_main.cc | 8 ++ 2 files changed, 200 insertions(+), 25 deletions(-) diff --git a/system/bta/dm/bta_dm_act.cc b/system/bta/dm/bta_dm_act.cc index 7a363a3d185..6b985943e6f 100644 --- a/system/bta/dm/bta_dm_act.cc +++ b/system/bta/dm/bta_dm_act.cc @@ -187,6 +187,9 @@ static uint64_t get_DisableDelayTimerInMs() { return kDisableDelayTimerInMs; #endif } + +TimestampedStringCircularBuffer gatt_history_{50}; + namespace { struct WaitForAllAclConnectionsToDrain { @@ -221,6 +224,80 @@ WaitForAllAclConnectionsToDrain::FromAlarmCallbackData(void* data) { static_cast(data)); } +struct gatt_interface_t { + void (*BTA_GATTC_CancelOpen)(tGATT_IF client_if, const RawAddress& remote_bda, + bool is_direct); + void (*BTA_GATTC_Refresh)(const RawAddress& remote_bda); + void (*BTA_GATTC_GetGattDb)(uint16_t conn_id, uint16_t start_handle, + uint16_t end_handle, btgatt_db_element_t** db, + int* count); + void (*BTA_GATTC_AppRegister)(tBTA_GATTC_CBACK* p_client_cb, + BtaAppRegisterCallback cb, bool eatt_support); + void (*BTA_GATTC_Close)(uint16_t conn_id); + void (*BTA_GATTC_ServiceSearchRequest)(uint16_t conn_id, + const bluetooth::Uuid* p_srvc_uuid); + void (*BTA_GATTC_Open)(tGATT_IF client_if, const RawAddress& remote_bda, + tBTM_BLE_CONN_TYPE connection_type, + bool opportunistic); +} default_gatt_interface = { + .BTA_GATTC_CancelOpen = + [](tGATT_IF client_if, const RawAddress& remote_bda, bool is_direct) { + gatt_history_.Push(base::StringPrintf( + "%-32s bd_addr:%s client_if:%hu is_direct:%c", "GATTC_CancelOpen", + ADDRESS_TO_LOGGABLE_CSTR(remote_bda), client_if, + (is_direct) ? 'T' : 'F')); + BTA_GATTC_CancelOpen(client_if, remote_bda, is_direct); + }, + .BTA_GATTC_Refresh = + [](const RawAddress& remote_bda) { + gatt_history_.Push( + base::StringPrintf("%-32s bd_addr:%s", "GATTC_Refresh", + ADDRESS_TO_LOGGABLE_CSTR(remote_bda))); + BTA_GATTC_Refresh(remote_bda); + }, + .BTA_GATTC_GetGattDb = + [](uint16_t conn_id, uint16_t start_handle, uint16_t end_handle, + btgatt_db_element_t** db, int* count) { + gatt_history_.Push(base::StringPrintf( + "%-32s conn_id:%hu start_handle:%hu end:handle:%hu", + "GATTC_GetGattDb", conn_id, start_handle, end_handle)); + BTA_GATTC_GetGattDb(conn_id, start_handle, end_handle, db, count); + }, + .BTA_GATTC_AppRegister = + [](tBTA_GATTC_CBACK* p_client_cb, BtaAppRegisterCallback cb, + bool eatt_support) { + gatt_history_.Push(base::StringPrintf("%-32s eatt_support:%c", + "GATTC_AppRegister", + (eatt_support) ? 'T' : 'F')); + BTA_GATTC_AppRegister(p_client_cb, cb, eatt_support); + }, + .BTA_GATTC_Close = + [](uint16_t conn_id) { + gatt_history_.Push( + base::StringPrintf("%-32s conn_id:%hu", "GATTC_Close", conn_id)); + BTA_GATTC_Close(conn_id); + }, + .BTA_GATTC_ServiceSearchRequest = + [](uint16_t conn_id, const bluetooth::Uuid* p_srvc_uuid) { + gatt_history_.Push(base::StringPrintf( + "%-32s conn_id:%hu", "GATTC_ServiceSearchRequest", conn_id)); + BTA_GATTC_ServiceSearchRequest(conn_id, p_srvc_uuid); + }, + .BTA_GATTC_Open = + [](tGATT_IF client_if, const RawAddress& remote_bda, + tBTM_BLE_CONN_TYPE connection_type, bool opportunistic) { + gatt_history_.Push(base::StringPrintf( + "%-32s bd_addr:%s client_if:%hu type:0x%x opportunistic:%c", + "GATTC_Open", ADDRESS_TO_LOGGABLE_CSTR(remote_bda), client_if, + connection_type, (opportunistic) ? 'T' : 'F')); + BTA_GATTC_Open(client_if, remote_bda, connection_type, opportunistic); + }, +}; + +gatt_interface_t* gatt_interface = &default_gatt_interface; + +gatt_interface_t& get_gatt_interface() { return *gatt_interface; } + } // namespace static void bta_dm_reset_sec_dev_pending(const RawAddress& remote_bd_addr); @@ -593,12 +670,12 @@ bool BTA_DmSetVisibility(bt_scan_mode_t mode) { static void bta_dm_process_remove_device_no_callback( const RawAddress& bd_addr) { /* need to remove all pending background connection before unpair */ - BTA_GATTC_CancelOpen(0, bd_addr, false); + get_gatt_interface().BTA_GATTC_CancelOpen(0, bd_addr, false); BTM_SecDeleteDevice(bd_addr); /* remove all cached GATT information */ - BTA_GATTC_Refresh(bd_addr); + get_gatt_interface().BTA_GATTC_Refresh(bd_addr); } void bta_dm_process_remove_device(const RawAddress& bd_addr) { @@ -1462,7 +1539,8 @@ void bta_dm_search_cmpl() { } else { btgatt_db_element_t* db = NULL; int count = 0; - BTA_GATTC_GetGattDb(conn_id, 0x0000, 0xFFFF, &db, &count); + get_gatt_interface().BTA_GATTC_GetGattDb(conn_id, 0x0000, 0xFFFF, &db, + &count); if (count != 0) { for (int i = 0; i < count; i++) { // we process service entries only @@ -1524,6 +1602,9 @@ void bta_dm_disc_result(tBTA_DM_MSG* p_data) { bta_dm_search_cb.p_search_cback(BTA_DM_DISC_RES_EVT, &p_data->disc_result.result); + get_gatt_interface().BTA_GATTC_CancelOpen(0, bta_dm_search_cb.peer_bdaddr, + true); + bta_dm_search_cmpl(); } @@ -2730,7 +2811,7 @@ static void bta_dm_acl_down(const RawAddress& bd_addr, issue_unpair_cb = BTM_SecDeleteDevice(device->peer_bdaddr); /* remove all cached GATT information */ - BTA_GATTC_Refresh(bd_addr); + get_gatt_interface().BTA_GATTC_Refresh(bd_addr); APPL_TRACE_DEBUG("%s: Unpairing: issue unpair CB = %d ", __func__, issue_unpair_cb); @@ -4149,16 +4230,30 @@ void bta_dm_ble_get_energy_info( * ******************************************************************************/ static void bta_dm_gattc_register(void) { - if (bta_dm_search_cb.client_if == BTA_GATTS_INVALID_IF) { - BTA_GATTC_AppRegister(bta_dm_gattc_callback, - base::Bind([](uint8_t client_id, uint8_t status) { - if (status == GATT_SUCCESS) - bta_dm_search_cb.client_if = client_id; - else - bta_dm_search_cb.client_if = BTA_GATTS_INVALID_IF; - - }), false); + if (bta_dm_search_cb.client_if != BTA_GATTS_INVALID_IF) { + // Already registered + return; } + get_gatt_interface().BTA_GATTC_AppRegister( + bta_dm_gattc_callback, base::Bind([](uint8_t client_id, uint8_t status) { + tGATT_STATUS gatt_status = static_cast(status); + gatt_history_.Push(base::StringPrintf( + "%-32s client_id:%hu status:%s", "GATTC_RegisteredCallback", + client_id, gatt_status_text(gatt_status).c_str())); + if (static_cast(status) == GATT_SUCCESS) { + LOG_INFO( + "Registered device discovery search gatt client tGATT_IF:%hhu", + client_id); + bta_dm_search_cb.client_if = client_id; + } else { + LOG_WARN( + "Failed to register device discovery search gatt client" + " gatt_status:%hhu previous tGATT_IF:%hhu", + bta_dm_search_cb.client_if, status); + bta_dm_search_cb.client_if = BTA_GATTS_INVALID_IF; + } + }), + false); } /******************************************************************************* @@ -4243,6 +4338,8 @@ void bta_dm_close_gatt_conn(UNUSED_ATTR tBTA_DM_MSG* p_data) { * ******************************************************************************/ void btm_dm_start_gatt_discovery(const RawAddress& bd_addr) { + constexpr bool kUseOpportunistic = true; + bta_dm_search_cb.gatt_disc_active = true; /* connection is already open */ @@ -4250,14 +4347,29 @@ void btm_dm_start_gatt_discovery(const RawAddress& bd_addr) { bta_dm_search_cb.conn_id != GATT_INVALID_CONN_ID) { bta_dm_search_cb.pending_close_bda = RawAddress::kEmpty; alarm_cancel(bta_dm_search_cb.gatt_close_timer); - BTA_GATTC_ServiceSearchRequest(bta_dm_search_cb.conn_id, nullptr); + get_gatt_interface().BTA_GATTC_ServiceSearchRequest( + bta_dm_search_cb.conn_id, nullptr); } else { if (BTM_IsAclConnectionUp(bd_addr, BT_TRANSPORT_LE)) { - BTA_GATTC_Open(bta_dm_search_cb.client_if, bd_addr, - BTM_BLE_DIRECT_CONNECTION, true); + LOG_DEBUG( + "Use existing gatt client connection for discovery peer:%s " + "transport:%s opportunistic:%c", + ADDRESS_TO_LOGGABLE_CSTR(bd_addr), + bt_transport_text(BT_TRANSPORT_LE).c_str(), + (kUseOpportunistic) ? 'T' : 'F'); + get_gatt_interface().BTA_GATTC_Open(bta_dm_search_cb.client_if, bd_addr, + BTM_BLE_DIRECT_CONNECTION, + kUseOpportunistic); } else { - BTA_GATTC_Open(bta_dm_search_cb.client_if, bd_addr, - BTM_BLE_DIRECT_CONNECTION, false); + LOG_DEBUG( + "Opening new gatt client connection for discovery peer:%s " + "transport:%s opportunistic:%c", + ADDRESS_TO_LOGGABLE_CSTR(bd_addr), + bt_transport_text(BT_TRANSPORT_LE).c_str(), + (!kUseOpportunistic) ? 'T' : 'F'); + get_gatt_interface().BTA_GATTC_Open(bta_dm_search_cb.client_if, bd_addr, + BTM_BLE_DIRECT_CONNECTION, + !kUseOpportunistic); } } } @@ -4276,18 +4388,56 @@ void bta_dm_proc_open_evt(tBTA_GATTC_OPEN* p_data) { << " search_cb.peer_dbaddr:" << bta_dm_search_cb.peer_bdaddr << " connected_bda=" << p_data->remote_bda.address; - APPL_TRACE_DEBUG("BTA_GATTC_OPEN_EVT conn_id = %d client_if=%d status = %d", - p_data->conn_id, p_data->client_if, p_data->status); + LOG_DEBUG("BTA_GATTC_OPEN_EVT conn_id = %d client_if=%d status = %d", + p_data->conn_id, p_data->client_if, p_data->status); + + gatt_history_.Push(base::StringPrintf( + "%-32s bd_addr:%s conn_id:%hu client_if:%hu event:%s", + "GATTC_EventCallback", ADDRESS_TO_LOGGABLE_CSTR(p_data->remote_bda), + p_data->conn_id, p_data->client_if, + gatt_client_event_text(BTA_GATTC_OPEN_EVT).c_str())); bta_dm_search_cb.conn_id = p_data->conn_id; if (p_data->status == GATT_SUCCESS) { - BTA_GATTC_ServiceSearchRequest(p_data->conn_id, nullptr); + get_gatt_interface().BTA_GATTC_ServiceSearchRequest(p_data->conn_id, + nullptr); } else { bta_dm_gatt_disc_complete(GATT_INVALID_CONN_ID, p_data->status); } } +void bta_dm_proc_close_evt(const tBTA_GATTC_CLOSE& close) { + LOG_INFO("Gatt connection closed peer:%s reason:%s", + ADDRESS_TO_LOGGABLE_CSTR(close.remote_bda), + gatt_disconnection_reason_text(close.reason).c_str()); + + gatt_history_.Push(base::StringPrintf( + "%-32s bd_addr:%s client_if:%hu status:%s event:%s", + "GATTC_EventCallback", ADDRESS_TO_LOGGABLE_CSTR(close.remote_bda), + close.client_if, gatt_status_text(close.status).c_str(), + gatt_client_event_text(BTA_GATTC_CLOSE_EVT).c_str())); + + if (close.remote_bda == bta_dm_search_cb.peer_bdaddr) { + if (bluetooth::common::init_flags:: + bta_dm_clear_conn_id_on_client_close_is_enabled()) { + LOG_DEBUG("Clearing connection id on client close"); + bta_dm_search_cb.conn_id = GATT_INVALID_CONN_ID; + } + } else { + LOG_WARN("Received close event for unknown peer:%s", + ADDRESS_TO_LOGGABLE_CSTR(close.remote_bda)); + } + + /* in case of disconnect before search is completed */ + if ((bta_dm_search_cb.state != BTA_DM_SEARCH_IDLE) && + (bta_dm_search_cb.state != BTA_DM_SEARCH_ACTIVE) && + close.remote_bda == bta_dm_search_cb.peer_bdaddr) { + bta_dm_gatt_disc_complete((uint16_t)GATT_INVALID_CONN_ID, + (tGATT_STATUS)GATT_ERROR); + } +} + /******************************************************************************* * * Function bta_dm_clear_event_filter @@ -4465,9 +4615,6 @@ static void bta_dm_gattc_callback(tBTA_GATTC_EVT event, tBTA_GATTC* p_data) { bta_dm_proc_open_evt(&p_data->open); break; - case BTA_GATTC_SEARCH_RES_EVT: - break; - case BTA_GATTC_SEARCH_CMPL_EVT: switch (bta_dm_search_get_state()) { case BTA_DM_SEARCH_IDLE: @@ -4479,6 +4626,10 @@ static void bta_dm_gattc_callback(tBTA_GATTC_EVT event, tBTA_GATTC* p_data) { p_data->search_cmpl.status); break; } + gatt_history_.Push(base::StringPrintf( + "%-32s conn_id:%hu status:%s", "GATTC_EventCallback", + p_data->search_cmpl.conn_id, + gatt_status_text(p_data->search_cmpl.status).c_str())); break; case BTA_GATTC_CLOSE_EVT: @@ -4506,7 +4657,23 @@ static void bta_dm_gattc_callback(tBTA_GATTC_EVT event, tBTA_GATTC* p_data) { } break; - default: + case BTA_GATTC_ACL_EVT: + case BTA_GATTC_CANCEL_OPEN_EVT: + case BTA_GATTC_CFG_MTU_EVT: + case BTA_GATTC_CONGEST_EVT: + case BTA_GATTC_CONN_UPDATE_EVT: + case BTA_GATTC_DEREG_EVT: + case BTA_GATTC_ENC_CMPL_CB_EVT: + case BTA_GATTC_EXEC_EVT: + case BTA_GATTC_NOTIF_EVT: + case BTA_GATTC_PHY_UPDATE_EVT: + case BTA_GATTC_SEARCH_RES_EVT: + case BTA_GATTC_SRVC_CHG_EVT: + case BTA_GATTC_SRVC_DISC_DONE_EVT: + case BTA_GATTC_SUBRATE_CHG_EVT: + gatt_history_.Push( + base::StringPrintf("%-32s event:%s", "GATTC_EventCallback", + gatt_client_event_text(event).c_str())); break; } } diff --git a/system/bta/dm/bta_dm_main.cc b/system/bta/dm/bta_dm_main.cc index 532b979e7bb..5da2220b68a 100644 --- a/system/bta/dm/bta_dm_main.cc +++ b/system/bta/dm/bta_dm_main.cc @@ -28,6 +28,7 @@ #include "bta/dm/bta_dm_int.h" #include "gd/common/circular_buffer.h" #include "gd/common/strings.h" +#include "stack/btm/btm_int_types.h" #include "stack/include/bt_hdr.h" #include "stack/include/bt_types.h" @@ -230,6 +231,7 @@ bool bta_dm_search_sm_execute(BT_HDR_RIGID* p_msg) { return true; } +extern TimestampedStringCircularBuffer gatt_history_; #define DUMPSYS_TAG "shim::legacy::bta::dm" void DumpsysBtaDm(int fd) { LOG_DUMPSYS_TITLE(fd, DUMPSYS_TAG); @@ -241,5 +243,11 @@ void DumpsysBtaDm(int fd) { } LOG_DUMPSYS(fd, " current bta_dm_search_state:%s", bta_dm_state_text(bta_dm_search_get_state()).c_str()); + auto gatt_history = gatt_history_.Pull(); + LOG_DUMPSYS(fd, " last %zu gatt history entries", gatt_history.size()); + for (const auto& it : gatt_history) { + LOG_DUMPSYS(fd, " %s %s", EpochMillisToString(it.timestamp).c_str(), + it.entry.c_str()); + } } #undef DUMPSYS_TAG -- GitLab From e6b242f012ac0a64d7a8d16169bc7a1662075ef4 Mon Sep 17 00:00:00 2001 From: Sungsoo Lim Date: Wed, 17 May 2023 04:10:59 +0000 Subject: [PATCH 0080/2405] Fix NPE in SapService An intent with ACTION_CONNECTION_ACCESS_REPLY can be recevied after the USER_TIMEOUT then mRemoteDevice would become null, and NPE happens. Bug: 258140884 Test: atest BluetoothInstrumentationTests:SapServiceTest Change-Id: Ia622cef8508001fd7baee7b362cdba393a774169 --- .../src/com/android/bluetooth/sap/SapService.java | 8 +++++--- .../com/android/bluetooth/sap/SapServiceTest.java | 12 +++++++++--- 2 files changed, 14 insertions(+), 6 deletions(-) diff --git a/android/app/src/com/android/bluetooth/sap/SapService.java b/android/app/src/com/android/bluetooth/sap/SapService.java index a5ef6c1f4e1..008ca3f1e45 100644 --- a/android/app/src/com/android/bluetooth/sap/SapService.java +++ b/android/app/src/com/android/bluetooth/sap/SapService.java @@ -811,9 +811,10 @@ public class SapService extends ProfileService { } // Can only be null during shutdown } - private SapBroadcastReceiver mSapReceiver = new SapBroadcastReceiver(); + @VisibleForTesting SapBroadcastReceiver mSapReceiver = new SapBroadcastReceiver(); - private class SapBroadcastReceiver extends BroadcastReceiver { + @VisibleForTesting + class SapBroadcastReceiver extends BroadcastReceiver { @Override public void onReceive(Context context, Intent intent) { @@ -844,7 +845,8 @@ public class SapService extends ProfileService { Log.v(TAG, " - Received BluetoothDevice.ACTION_CONNECTION_ACCESS_REPLY"); int requestType = intent.getIntExtra(BluetoothDevice.EXTRA_ACCESS_REQUEST_TYPE, -1); - if (requestType != BluetoothDevice.REQUEST_TYPE_SIM_ACCESS) { + if (requestType != BluetoothDevice.REQUEST_TYPE_SIM_ACCESS + || !mIsWaitingAuthorization) { return; } diff --git a/android/app/tests/unit/src/com/android/bluetooth/sap/SapServiceTest.java b/android/app/tests/unit/src/com/android/bluetooth/sap/SapServiceTest.java index c6538154561..dc7a24741c6 100644 --- a/android/app/tests/unit/src/com/android/bluetooth/sap/SapServiceTest.java +++ b/android/app/tests/unit/src/com/android/bluetooth/sap/SapServiceTest.java @@ -26,6 +26,7 @@ import android.bluetooth.BluetoothAdapter; import android.bluetooth.BluetoothDevice; import android.bluetooth.BluetoothProfile; import android.content.Context; +import android.content.Intent; import androidx.test.InstrumentationRegistry; import androidx.test.filters.MediumTest; @@ -37,7 +38,6 @@ import com.android.bluetooth.btservice.AdapterService; import com.android.bluetooth.btservice.storage.DatabaseManager; import org.junit.After; -import org.junit.Assume; import org.junit.Before; import org.junit.Rule; import org.junit.Test; @@ -151,6 +151,12 @@ public class SapServiceTest { public void testGetRemoteDeviceName() { assertThat(SapService.getRemoteDeviceName()).isNull(); } -} - + @Test + public void testReceiver_ConnectionAccessReplyIntent_shouldNotCrash() { + Intent intent = new Intent(BluetoothDevice.ACTION_CONNECTION_ACCESS_REPLY); + intent.putExtra( + BluetoothDevice.EXTRA_ACCESS_REQUEST_TYPE, BluetoothDevice.REQUEST_TYPE_SIM_ACCESS); + mService.mSapReceiver.onReceive(mTargetContext, intent); + } +} -- GitLab From 9cb3d2206f658ab2035e51e696b53611a12cafc2 Mon Sep 17 00:00:00 2001 From: Sungsoo Lim Date: Mon, 15 May 2023 06:26:20 +0000 Subject: [PATCH 0081/2405] Remove an unused AudioPolicyEntity construction Bug: 279224906 Test: atest BluetoothInstrumentationTests:AudioPolicyEntityTest Change-Id: I8343e5887854c4363bee4861ca2df9f8aebd9a36 --- .../btservice/storage/AudioPolicyEntity.java | 7 --- .../storage/AudioPolicyEntityTest.java | 45 +++++++++++++++++++ 2 files changed, 45 insertions(+), 7 deletions(-) create mode 100644 android/app/tests/unit/src/com/android/bluetooth/btservice/storage/AudioPolicyEntityTest.java diff --git a/android/app/src/com/android/bluetooth/btservice/storage/AudioPolicyEntity.java b/android/app/src/com/android/bluetooth/btservice/storage/AudioPolicyEntity.java index d5ec42247c4..024fe1a5292 100644 --- a/android/app/src/com/android/bluetooth/btservice/storage/AudioPolicyEntity.java +++ b/android/app/src/com/android/bluetooth/btservice/storage/AudioPolicyEntity.java @@ -36,13 +36,6 @@ class AudioPolicyEntity { inBandRingtoneAudioPolicy = BluetoothSinkAudioPolicy.POLICY_UNCONFIGURED; } - AudioPolicyEntity(int callEstablishAudioPolicy, int connectingTimeAudioPolicy, - int inBandRingtoneAudioPolicy) { - this.callEstablishAudioPolicy = callEstablishAudioPolicy; - this.connectingTimeAudioPolicy = connectingTimeAudioPolicy; - this.inBandRingtoneAudioPolicy = inBandRingtoneAudioPolicy; - } - public String toString() { StringBuilder builder = new StringBuilder(); builder.append("callEstablishAudioPolicy=") diff --git a/android/app/tests/unit/src/com/android/bluetooth/btservice/storage/AudioPolicyEntityTest.java b/android/app/tests/unit/src/com/android/bluetooth/btservice/storage/AudioPolicyEntityTest.java new file mode 100644 index 00000000000..38dd6d68079 --- /dev/null +++ b/android/app/tests/unit/src/com/android/bluetooth/btservice/storage/AudioPolicyEntityTest.java @@ -0,0 +1,45 @@ +/* + * Copyright 2023 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.bluetooth.btservice.storage; + +import static com.google.common.truth.Truth.assertThat; + +import android.bluetooth.BluetoothSinkAudioPolicy; + +import org.junit.Test; +import org.junit.runner.RunWith; +import org.junit.runners.JUnit4; + +@RunWith(JUnit4.class) +public final class AudioPolicyEntityTest { + @Test + public void constructor() { + AudioPolicyEntity entity = new AudioPolicyEntity(); + assertThat(entity.callEstablishAudioPolicy) + .isEqualTo(BluetoothSinkAudioPolicy.POLICY_UNCONFIGURED); + assertThat(entity.connectingTimeAudioPolicy) + .isEqualTo(BluetoothSinkAudioPolicy.POLICY_UNCONFIGURED); + assertThat(entity.inBandRingtoneAudioPolicy) + .isEqualTo(BluetoothSinkAudioPolicy.POLICY_UNCONFIGURED); + } + + @Test + public void toString_shouldNotEmpty() { + AudioPolicyEntity entity = new AudioPolicyEntity(); + assertThat(entity.toString()).isNotEmpty(); + } +} -- GitLab From 708d08c0777117558704abbca7215cb212cb665c Mon Sep 17 00:00:00 2001 From: Jakob Vukalovic Date: Wed, 26 Apr 2023 14:27:27 +0100 Subject: [PATCH 0082/2405] rust: Make AttPermissions compatible with libbitflags 2.2.1 For compatibility with the new version of libbitflags (2.2.1), implement Copy, Clone, Debug, PartialEq, Eq for AttPermissions. Bug: 261439617 Test: Build Change-Id: Ief378cdd5c9c63f9a01b37a9ef080b90eaee7631 Ignore-AOSP-First: This is a cherry-pick from AOSP because changes to Rust crates are not automerged from AOSP. Change-Id: Ib00d6cf4c55ce69481aab277ae86365aac3eaa8f --- system/rust/src/gatt/server/att_database.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/system/rust/src/gatt/server/att_database.rs b/system/rust/src/gatt/server/att_database.rs index db2d7318826..2235fd81f59 100644 --- a/system/rust/src/gatt/server/att_database.rs +++ b/system/rust/src/gatt/server/att_database.rs @@ -34,6 +34,7 @@ bitflags! { /// /// These values are from Core Spec 5.3 Vol 3G 3.3.1.1 Characteristic Properties, /// and also match what Android uses in JNI. + #[derive(Copy, Clone, Debug, PartialEq, Eq)] pub struct AttPermissions : u8 { /// Attribute can be read using READ_REQ const READABLE = 0x02; -- GitLab From bd2faa9ade1c38bfde8ef6656260e19e664d115e Mon Sep 17 00:00:00 2001 From: Andrew Walbran Date: Wed, 17 May 2023 14:13:14 +0000 Subject: [PATCH 0083/2405] Remove unneccessary `extern crate` lines and use macros explicitly. This makes dependencies more clear. Bug: 261037227 Test: built crates with cargo Change-Id: I37dc3c99c13babcb682f5ff1c10be48ec1cd98a0 --- floss/hcidoc/src/main.rs | 3 --- floss/hcidoc/src/parser.rs | 1 + system/gd/rust/facade_proto/build.rs | 3 --- system/gd/rust/linux/mgmt/build.rs | 2 -- 4 files changed, 1 insertion(+), 8 deletions(-) diff --git a/floss/hcidoc/src/main.rs b/floss/hcidoc/src/main.rs index dde8650c0d4..ed2fce3fbba 100644 --- a/floss/hcidoc/src/main.rs +++ b/floss/hcidoc/src/main.rs @@ -1,6 +1,3 @@ -#[macro_use] -extern crate num_derive; - use clap::{Arg, ArgAction, Command}; use std::io::Write; diff --git a/floss/hcidoc/src/parser.rs b/floss/hcidoc/src/parser.rs index 4f0ed8ce642..f8062980dbb 100644 --- a/floss/hcidoc/src/parser.rs +++ b/floss/hcidoc/src/parser.rs @@ -1,5 +1,6 @@ //! Parsing of various Bluetooth packets. use chrono::NaiveDateTime; +use num_derive::{FromPrimitive, ToPrimitive}; use num_traits::cast::FromPrimitive; use std::convert::TryFrom; use std::fs::File; diff --git a/system/gd/rust/facade_proto/build.rs b/system/gd/rust/facade_proto/build.rs index 99645e17df3..87b9fe6d63e 100644 --- a/system/gd/rust/facade_proto/build.rs +++ b/system/gd/rust/facade_proto/build.rs @@ -13,9 +13,6 @@ // See the License for the specific language governing permissions and // limitations under the License. -extern crate protoc_grpcio; -extern crate protoc_rust; - use std::env; use std::fs; use std::io::Write; diff --git a/system/gd/rust/linux/mgmt/build.rs b/system/gd/rust/linux/mgmt/build.rs index 7f1152b486d..6189dd7ca98 100644 --- a/system/gd/rust/linux/mgmt/build.rs +++ b/system/gd/rust/linux/mgmt/build.rs @@ -1,5 +1,3 @@ -extern crate protoc_rust; - use pkg_config::Config; use std::env; use std::fs; -- GitLab From 4f626976820e8339b55436f034d661c5d7746ec1 Mon Sep 17 00:00:00 2001 From: Chris Manton Date: Mon, 15 May 2023 09:43:29 -0700 Subject: [PATCH 0084/2405] Break out stack::sdp::discovery_db Bug: 282936084 Test: Compiles and link Change-Id: I9aa259e725e0d7c1c48969ce9b484e3857d9a4c4 --- system/stack/include/sdp_api.h | 65 +-------------------- system/stack/sdp/sdp_discovery_db.h | 87 +++++++++++++++++++++++++++++ 2 files changed, 88 insertions(+), 64 deletions(-) create mode 100644 system/stack/sdp/sdp_discovery_db.h diff --git a/system/stack/include/sdp_api.h b/system/stack/include/sdp_api.h index 0bcd6bfebaf..2808cffb914 100644 --- a/system/stack/include/sdp_api.h +++ b/system/stack/include/sdp_api.h @@ -25,6 +25,7 @@ #include "bt_target.h" #include "stack/include/sdp_status.h" #include "stack/include/sdpdefs.h" +#include "stack/sdp/sdp_discovery_db.h" #include "types/bluetooth/uuid.h" #include "types/raw_address.h" @@ -32,14 +33,6 @@ * Constants ****************************************************************************/ -/* Masks for attr_value field of tSDP_DISC_ATTR */ -#define SDP_DISC_ATTR_LEN_MASK 0x0FFF -#define SDP_DISC_ATTR_TYPE(len_type) ((len_type) >> 12) -#define SDP_DISC_ATTR_LEN(len_type) ((len_type)&SDP_DISC_ATTR_LEN_MASK) - -/* Maximum number of protocol list items (list_elem in tSDP_PROTOCOL_ELEM) */ -#define SDP_MAX_LIST_ELEMS 3 - /***************************************************************************** * Type Definitions ****************************************************************************/ @@ -48,62 +41,6 @@ typedef void(tSDP_DISC_CMPL_CB)(tSDP_RESULT result); typedef void(tSDP_DISC_CMPL_CB2)(tSDP_RESULT result, const void* user_data); -/* Define a structure to hold the discovered service information. */ -typedef struct { - union { - uint8_t u8; /* 8-bit integer */ - uint16_t u16; /* 16-bit integer */ - uint32_t u32; /* 32-bit integer */ - struct t_sdp_disc_attr* p_sub_attr; /* Addr of first sub-attr (list)*/ - uint8_t array[]; /* Variable length field */ - /* flexible array member */ - /* requiring backing store */ - /* from SDP DB */ - } v; - -} tSDP_DISC_ATVAL; - -typedef struct t_sdp_disc_attr { - struct t_sdp_disc_attr* p_next_attr; /* Addr of next linked attr */ - uint16_t attr_id; /* Attribute ID */ - uint16_t attr_len_type; /* Length and type fields */ - tSDP_DISC_ATVAL attr_value; /* Variable length entry data */ -} tSDP_DISC_ATTR; - -typedef struct t_sdp_disc_rec { - tSDP_DISC_ATTR* p_first_attr; /* First attribute of record */ - struct t_sdp_disc_rec* p_next_rec; /* Addr of next linked record */ - uint32_t time_read; /* The time the record was read */ - RawAddress remote_bd_addr; /* Remote BD address */ -} tSDP_DISC_REC; - -typedef struct { - uint32_t mem_size; /* Memory size of the DB */ - uint32_t mem_free; /* Memory still available */ - tSDP_DISC_REC* p_first_rec; /* Addr of first record in DB */ - uint16_t num_uuid_filters; /* Number of UUIds to filter */ - bluetooth::Uuid uuid_filters[SDP_MAX_UUID_FILTERS]; /* UUIDs to filter */ - uint16_t num_attr_filters; /* Number of attribute filters */ - uint16_t attr_filters[SDP_MAX_ATTR_FILTERS]; /* Attributes to filter */ - uint8_t* p_free_mem; /* Pointer to free memory */ - uint8_t* - raw_data; /* Received record from server. allocated/released by client */ - uint32_t raw_size; /* size of raw_data */ - uint32_t raw_used; /* length of raw_data used */ -} tSDP_DISCOVERY_DB; - -/* This structure is used to add protocol lists and find protocol elements */ -typedef struct { - uint16_t protocol_uuid; - uint16_t num_params; - uint16_t params[SDP_MAX_PROTOCOL_PARAMS]; -} tSDP_PROTOCOL_ELEM; - -typedef struct { - uint16_t num_elems; - tSDP_PROTOCOL_ELEM list_elem[SDP_MAX_LIST_ELEMS]; -} tSDP_PROTO_LIST_ELEM; - /* Device Identification (DI) data structure */ /* Used to set the DI record */ diff --git a/system/stack/sdp/sdp_discovery_db.h b/system/stack/sdp/sdp_discovery_db.h new file mode 100644 index 00000000000..f67f026cc37 --- /dev/null +++ b/system/stack/sdp/sdp_discovery_db.h @@ -0,0 +1,87 @@ +/****************************************************************************** + * + * Copyright 1999-2012 Broadcom Corporation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + ******************************************************************************/ + +#include + +#include "bt_target.h" // SDP_MAX_PROTOCOL_PARAMS +#include "types/bluetooth/uuid.h" + +#pragma once + +/* Masks for attr_value field of tSDP_DISC_ATTR */ +#define SDP_DISC_ATTR_LEN_MASK 0x0FFF +#define SDP_DISC_ATTR_TYPE(len_type) ((len_type) >> 12) +#define SDP_DISC_ATTR_LEN(len_type) ((len_type)&SDP_DISC_ATTR_LEN_MASK) + +#define SDP_MAX_LIST_ELEMS 3 + +/* Define a structure to hold the discovered service information. */ +typedef struct { + union { + uint8_t u8; /* 8-bit integer */ + uint16_t u16; /* 16-bit integer */ + uint32_t u32; /* 32-bit integer */ + struct t_sdp_disc_attr* p_sub_attr; /* Addr of first sub-attr (list)*/ + uint8_t array[]; /* Variable length field */ + /* flexible array member */ + /* requiring backing store */ + /* from SDP DB */ + } v; + +} tSDP_DISC_ATVAL; + +typedef struct t_sdp_disc_attr { + struct t_sdp_disc_attr* p_next_attr; /* Addr of next linked attr */ + uint16_t attr_id; /* Attribute ID */ + uint16_t attr_len_type; /* Length and type fields */ + tSDP_DISC_ATVAL attr_value; /* Variable length entry data */ +} tSDP_DISC_ATTR; + +typedef struct t_sdp_disc_rec { + tSDP_DISC_ATTR* p_first_attr; /* First attribute of record */ + struct t_sdp_disc_rec* p_next_rec; /* Addr of next linked record */ + uint32_t time_read; /* The time the record was read */ + RawAddress remote_bd_addr; /* Remote BD address */ +} tSDP_DISC_REC; + +typedef struct { + uint32_t mem_size; /* Memory size of the DB */ + uint32_t mem_free; /* Memory still available */ + tSDP_DISC_REC* p_first_rec; /* Addr of first record in DB */ + uint16_t num_uuid_filters; /* Number of UUIds to filter */ + bluetooth::Uuid uuid_filters[SDP_MAX_UUID_FILTERS]; /* UUIDs to filter */ + uint16_t num_attr_filters; /* Number of attribute filters */ + uint16_t attr_filters[SDP_MAX_ATTR_FILTERS]; /* Attributes to filter */ + uint8_t* p_free_mem; /* Pointer to free memory */ + uint8_t* + raw_data; /* Received record from server. allocated/released by client */ + uint32_t raw_size; /* size of raw_data */ + uint32_t raw_used; /* length of raw_data used */ +} tSDP_DISCOVERY_DB; + +/* This structure is used to add protocol lists and find protocol elements */ +typedef struct { + uint16_t protocol_uuid; + uint16_t num_params; + uint16_t params[SDP_MAX_PROTOCOL_PARAMS]; +} tSDP_PROTOCOL_ELEM; + +typedef struct { + uint16_t num_elems; + tSDP_PROTOCOL_ELEM list_elem[SDP_MAX_LIST_ELEMS]; +} tSDP_PROTO_LIST_ELEM; -- GitLab From 5674f0de5dd5370de3a6134bd2d7e36e68b2ab33 Mon Sep 17 00:00:00 2001 From: Yuyang Huang Date: Wed, 17 May 2023 11:06:55 -0700 Subject: [PATCH 0085/2405] Add flag for asha_phy_update_retry_limit have more control on possible phy update collision Test: manual Bug: 280693404 Change-Id: Ib57abf4887310ca704b94f3b9938d339f6e194b3 --- system/bta/include/bta_hearing_aid_api.h | 4 +++- system/gd/rust/common/src/init_flags.rs | 1 + system/gd/rust/shim/src/init_flags.rs | 1 + 3 files changed, 5 insertions(+), 1 deletion(-) diff --git a/system/bta/include/bta_hearing_aid_api.h b/system/bta/include/bta_hearing_aid_api.h index 94f4bda473e..9bda9e6e337 100644 --- a/system/bta/include/bta_hearing_aid_api.h +++ b/system/bta/include/bta_hearing_aid_api.h @@ -26,6 +26,7 @@ #include #include +#include "common/init_flags.h" #include "stack/include/gap_api.h" #include "types/raw_address.h" @@ -38,7 +39,8 @@ constexpr uint8_t CAPABILITY_BINAURAL = 0x02; constexpr uint8_t CAPABILITY_RESERVED = 0xFC; // Number of retry for phy update. This targets to reduce phy update collision. -constexpr uint8_t PHY_UPDATE_RETRY_LIMIT = 5; +const static uint8_t PHY_UPDATE_RETRY_LIMIT = + bluetooth::common::init_flags::get_asha_phy_update_retry_limit(); /** Implementations of HearingAid will also implement this interface */ class HearingAidAudioReceiver { diff --git a/system/gd/rust/common/src/init_flags.rs b/system/gd/rust/common/src/init_flags.rs index fdb0bcee5f3..820d7cf326c 100644 --- a/system/gd/rust/common/src/init_flags.rs +++ b/system/gd/rust/common/src/init_flags.rs @@ -359,6 +359,7 @@ init_flags!( name: InitFlags flags: { asha_packet_drop_frequency_threshold: i32 = 60, + asha_phy_update_retry_limit: i32 = 5, always_send_services_if_gatt_disc_done = true, always_use_private_gatt_for_debugging, asynchronously_start_l2cap_coc = true, diff --git a/system/gd/rust/shim/src/init_flags.rs b/system/gd/rust/shim/src/init_flags.rs index 09750d11e4f..687a44ba291 100644 --- a/system/gd/rust/shim/src/init_flags.rs +++ b/system/gd/rust/shim/src/init_flags.rs @@ -35,6 +35,7 @@ mod ffi { fn get_hci_adapter() -> i32; fn get_log_level_for_tag(tag: &str) -> i32; fn get_asha_packet_drop_frequency_threshold() -> i32; + fn get_asha_phy_update_retry_limit() -> i32; fn hfp_dynamic_version_is_enabled() -> bool; fn irk_rotation_is_enabled() -> bool; fn leaudio_targeted_announcement_reconnection_mode_is_enabled() -> bool; -- GitLab From ea370c19b262034673af4ae5f3e0def61360f20f Mon Sep 17 00:00:00 2001 From: Henri Chataing Date: Tue, 16 May 2023 18:02:34 +0000 Subject: [PATCH 0086/2405] RootCanal: Delay the first ACL packet sent on a connection The PTS test L2CAP/CMC/BV-13-C's flakiness is caused by the PTS tool handling a received ACL packet before the connection complete event when it is received too early after the connection establishment. This change adds a delay of 100ms to the first ACL packet being sent to work around this issue. Bug: 275294283 Test: atest pts-bot:L2CAP/CMC/BV-13-C Change-Id: If32e40f4ef13f948791719fc813ae3aebd6e61aa --- .../model/controller/acl_connection.cc | 1 + .../model/controller/acl_connection.h | 5 ++++ .../model/controller/link_layer_controller.cc | 29 +++++++++++++------ .../model/controller/link_layer_controller.h | 6 ++-- 4 files changed, 30 insertions(+), 11 deletions(-) diff --git a/tools/rootcanal/model/controller/acl_connection.cc b/tools/rootcanal/model/controller/acl_connection.cc index 2c47ad191dc..2a6b1f2823f 100644 --- a/tools/rootcanal/model/controller/acl_connection.cc +++ b/tools/rootcanal/model/controller/acl_connection.cc @@ -26,6 +26,7 @@ AclConnection::AclConnection(AddressWithType address, resolved_address_(resolved_address), type_(phy_type), role_(role), + established_timestamp_(std::chrono::steady_clock::now()), last_packet_timestamp_(std::chrono::steady_clock::now()), timeout_(std::chrono::seconds(1)) {} diff --git a/tools/rootcanal/model/controller/acl_connection.h b/tools/rootcanal/model/controller/acl_connection.h index 74bc9a700ab..16f35abce77 100644 --- a/tools/rootcanal/model/controller/acl_connection.h +++ b/tools/rootcanal/model/controller/acl_connection.h @@ -59,6 +59,10 @@ class AclConnection { bool IsNearExpiring() const; bool HasExpired() const; + std::chrono::steady_clock::duration GetUptime() const { + return std::chrono::steady_clock::now() - established_timestamp_; + } + // LE-ACL state. void InitiatePhyUpdate() { initiated_phy_update_ = true; } void PhyUpdateComplete() { initiated_phy_update_ = false; } @@ -82,6 +86,7 @@ class AclConnection { bool encrypted_{false}; uint16_t link_policy_settings_{0}; bluetooth::hci::Role role_{bluetooth::hci::Role::CENTRAL}; + std::chrono::steady_clock::time_point established_timestamp_; std::chrono::steady_clock::time_point last_packet_timestamp_; std::chrono::steady_clock::duration timeout_; diff --git a/tools/rootcanal/model/controller/link_layer_controller.cc b/tools/rootcanal/model/controller/link_layer_controller.cc index 81a1248e6e2..b7f104d87c0 100644 --- a/tools/rootcanal/model/controller/link_layer_controller.cc +++ b/tools/rootcanal/model/controller/link_layer_controller.cc @@ -2043,20 +2043,20 @@ LinkLayerController::~LinkLayerController() {} void LinkLayerController::SendLeLinkLayerPacket( std::unique_ptr packet, - int8_t tx_power) { + int8_t tx_power, std::chrono::milliseconds delay) { std::shared_ptr shared_packet = std::move(packet); - ScheduleTask(kNoDelayMs, [this, shared_packet, tx_power]() { + ScheduleTask(delay, [this, shared_packet, tx_power]() { send_to_remote_(shared_packet, Phy::Type::LOW_ENERGY, tx_power); }); } void LinkLayerController::SendLinkLayerPacket( std::unique_ptr packet, - int8_t tx_power) { + int8_t tx_power, std::chrono::milliseconds delay) { std::shared_ptr shared_packet = std::move(packet); - ScheduleTask(kNoDelayMs, [this, shared_packet, tx_power]() { + ScheduleTask(delay, [this, shared_packet, tx_power]() { send_to_remote_(shared_packet, Phy::Type::BR_EDR, tx_power); }); } @@ -2143,10 +2143,21 @@ ErrorCode LinkLayerController::SendAclToRemote( return ErrorCode::UNKNOWN_CONNECTION; } - AddressWithType my_address = connections_.GetOwnAddress(handle); - AddressWithType destination = connections_.GetAddress(handle); + AclConnection& connection = connections_.GetAclConnection(handle); + AddressWithType my_address = connection.GetOwnAddress(); + AddressWithType destination = connection.GetAddress(); Phy::Type phy = connections_.GetPhyType(handle); + // The PTS test L2CAP/CMC/BV-13-C flakes if the first ACL packet is + // sent too early after the connection establishment; the PTS in + // this case is handling the packet before the Connection Complete + // event and this causes the test to fail. + std::chrono::milliseconds connection_uptime = + std::chrono::duration_cast( + connection.GetUptime()); + std::chrono::milliseconds delay = + connection_uptime > 100ms ? 0ms : 100ms - connection_uptime; + auto acl_packet_payload = acl_packet.GetPayload(); auto acl = model::packets::AclBuilder::Create( my_address.GetAddress(), destination.GetAddress(), @@ -2156,14 +2167,14 @@ ErrorCode LinkLayerController::SendAclToRemote( switch (phy) { case Phy::Type::BR_EDR: - SendLinkLayerPacket(std::move(acl)); + SendLinkLayerPacket(std::move(acl), 0, delay); break; case Phy::Type::LOW_ENERGY: - SendLeLinkLayerPacket(std::move(acl)); + SendLeLinkLayerPacket(std::move(acl), 0, delay); break; } - ScheduleTask(kNoDelayMs, [this, handle]() { + ScheduleTask(delay, [this, handle]() { send_event_(bluetooth::hci::NumberOfCompletedPacketsBuilder::Create( {bluetooth::hci::CompletedPackets(handle, 1)})); }); diff --git a/tools/rootcanal/model/controller/link_layer_controller.h b/tools/rootcanal/model/controller/link_layer_controller.h index f7300747ee7..8845406b651 100644 --- a/tools/rootcanal/model/controller/link_layer_controller.h +++ b/tools/rootcanal/model/controller/link_layer_controller.h @@ -600,10 +600,12 @@ class LinkLayerController { protected: void SendLinkLayerPacket( std::unique_ptr packet, - int8_t tx_power = 0); + int8_t tx_power = 0, + std::chrono::milliseconds delay = std::chrono::milliseconds(0)); void SendLeLinkLayerPacket( std::unique_ptr packet, - int8_t tx_power = 0); + int8_t tx_power = 0, + std::chrono::milliseconds delay = std::chrono::milliseconds(0)); void IncomingAclPacket(model::packets::LinkLayerPacketView incoming, int8_t rssi); -- GitLab From e96cc915c9288cd710137ff48f39edb83adf0ae7 Mon Sep 17 00:00:00 2001 From: Rahul Sabnis Date: Wed, 17 May 2023 11:45:50 -0700 Subject: [PATCH 0087/2405] Fix typo in oob generation event name Bug: 283124370 Test: system/gd/cert/run --sl4a_sl4a --clean Change-Id: Iea07e258fa8168864740b090622c0ecd9a4ce365 --- system/blueberry/tests/sl4a_sl4a/lib/security.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/system/blueberry/tests/sl4a_sl4a/lib/security.py b/system/blueberry/tests/sl4a_sl4a/lib/security.py index fcfb4ba0e8b..d6e948c99ed 100644 --- a/system/blueberry/tests/sl4a_sl4a/lib/security.py +++ b/system/blueberry/tests/sl4a_sl4a/lib/security.py @@ -61,7 +61,7 @@ class Security: logging.error("Failed to generate OOB data!") # Check if generating oob data failed without blocking try: - generate_failure_event = self.__device.ed.pop_event(self.SL4A_EVENT_GENERATE_OOB_DATA_FAILURE, 0) + generate_failure_event = self.__device.ed.pop_event(self.SL4A_EVENT_GENERATE_OOB_DATA_ERROR, 0) except queue.Empty as error: logging.error("Failed to generate OOB Data without error code") assertThat(True).isFalse() -- GitLab From 80a009fedac6327782502946023794f8b6f527a0 Mon Sep 17 00:00:00 2001 From: Rahul Sabnis Date: Wed, 17 May 2023 11:53:12 -0700 Subject: [PATCH 0088/2405] Account for oob generation returning a tuple Bug: 283124370 Test: system/gd/cert/run --sl4a_sl4a --clean Change-Id: I98936789261ab4b5c41bc153c2489fa441276c55 --- .../blueberry/tests/sl4a_sl4a/security/oob_pairing_test.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/system/blueberry/tests/sl4a_sl4a/security/oob_pairing_test.py b/system/blueberry/tests/sl4a_sl4a/security/oob_pairing_test.py index 5bb2dce0620..3d4c61c5a7c 100644 --- a/system/blueberry/tests/sl4a_sl4a/security/oob_pairing_test.py +++ b/system/blueberry/tests/sl4a_sl4a/security/oob_pairing_test.py @@ -99,9 +99,11 @@ class OobPairingTest(sl4a_sl4a_base_test.Sl4aSl4aBaseTestClass): def test_le_generate_local_oob_data(self): oob_data = self.dut_security_.generate_oob_data(Security.TRANSPORT_LE) - assertThat(oob_data).isNotNone() + assertThat(oob_data[0]).isEqualTo(0) + assertThat(oob_data[1]).isNotNone() oob_data = self.cert_security_.generate_oob_data(Security.TRANSPORT_LE) - assertThat(oob_data).isNotNone() + assertThat(oob_data[0]).isEqualTo(0) + assertThat(oob_data[1]).isNotNone() def test_le_generate_local_oob_data_stress(self): for i in range(1, 20): -- GitLab From d004a70d9515042d33335b88caf3bc307e8630bf Mon Sep 17 00:00:00 2001 From: Martin Geisler Date: Wed, 17 May 2023 18:55:44 +0000 Subject: [PATCH 0089/2405] Revert "pdl: Remove rustfmt from no_alloc test" Revert submission 2586907 Reason for revert: http://b/283107621 Reverted changes: /q/submissionid:2586907 Change-Id: I4fe1eaf99308bcb619aaee5d73423ddb702aea33 --- tools/pdl/Android.bp | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/tools/pdl/Android.bp b/tools/pdl/Android.bp index d81908a4f0b..9f668b42735 100644 --- a/tools/pdl/Android.bp +++ b/tools/pdl/Android.bp @@ -381,8 +381,13 @@ python_test_host { // Defaults for the rust_noalloc backend genrule_defaults { name: "pdl_rust_noalloc_generator_defaults", - cmd: "$(location :pdl) --output-format rust_no_alloc $(in) > $(out)", - tools: [":pdl"], + cmd: "set -o pipefail;" + + " $(location :pdl) --output-format rust_no_alloc $(in) |" + + " $(location :rustfmt) > $(out)", + tools: [ + ":pdl", + ":rustfmt", + ], } // Generate the rust_noalloc backend srcs against the little-endian test vectors -- GitLab From 8dc122e079a283a6878172cffdaf784a7f38a5e9 Mon Sep 17 00:00:00 2001 From: Martin Geisler Date: Wed, 17 May 2023 18:55:44 +0000 Subject: [PATCH 0090/2405] Revert "pdl: Format generated code using prettyplease" Revert submission 2586907 Reason for revert: http://b/283107621 Reverted changes: /q/submissionid:2586907 Change-Id: I96f1d7a70308baee85f31d60630e2ff869c91bfa --- tools/pdl/Android.bp | 9 ++++++-- tools/pdl/src/backends/rust.rs | 30 ++++++++++++++----------- tools/pdl/src/backends/rust/preamble.rs | 18 ++++++++++----- 3 files changed, 37 insertions(+), 20 deletions(-) diff --git a/tools/pdl/Android.bp b/tools/pdl/Android.bp index 9f668b42735..65a23bcca4e 100644 --- a/tools/pdl/Android.bp +++ b/tools/pdl/Android.bp @@ -146,8 +146,13 @@ rust_test_host { genrule_defaults { name: "pdl_rust_generator_defaults", - cmd: "$(location :pdl) --output-format rust $(in) > $(out)", - tools: [":pdl"], + cmd: "set -o pipefail;" + + " $(location :pdl) --output-format rust $(in) |" + + " $(location :rustfmt) > $(out)", + tools: [ + ":pdl", + ":rustfmt", + ], defaults_visibility: [ "//external/uwb/src", "//packages/modules/Bluetooth:__subpackages__", diff --git a/tools/pdl/src/backends/rust.rs b/tools/pdl/src/backends/rust.rs index b480ca665a2..c9101521cb0 100644 --- a/tools/pdl/src/backends/rust.rs +++ b/tools/pdl/src/backends/rust.rs @@ -964,20 +964,24 @@ fn generate_decl( scope: &lint::Scope<'_>, file: &analyzer_ast::File, decl: &analyzer_ast::Decl, -) -> proc_macro2::TokenStream { +) -> String { match &decl.desc { - ast::DeclDesc::Packet { id, .. } => generate_packet_decl(scope, file.endianness.value, id), + ast::DeclDesc::Packet { id, .. } => { + generate_packet_decl(scope, file.endianness.value, id).to_string() + } ast::DeclDesc::Struct { id, parent_id: None, .. } => { // TODO(mgeisler): handle structs with parents. We could // generate code for them, but the code is not useful // since it would require the caller to unpack everything // manually. We either need to change the API, or // implement the recursive (de)serialization. - generate_struct_decl(scope, file.endianness.value, id) + generate_struct_decl(scope, file.endianness.value, id).to_string() + } + ast::DeclDesc::Enum { id, tags, width } => { + generate_enum_decl(id, tags, *width, false).to_string() } - ast::DeclDesc::Enum { id, tags, width } => generate_enum_decl(id, tags, *width, false), ast::DeclDesc::CustomField { id, width: Some(width), .. } => { - generate_custom_field_decl(id, *width) + generate_custom_field_decl(id, *width).to_string() } _ => todo!("unsupported Decl::{:?}", decl), } @@ -988,18 +992,18 @@ fn generate_decl( /// The code is not formatted, pipe it through `rustfmt` to get /// readable source code. pub fn generate(sources: &ast::SourceDatabase, file: &analyzer_ast::File) -> String { + let mut code = String::new(); + let source = sources.get(file.file).expect("could not read source"); - let preamble = preamble::generate(Path::new(source.name())); + code.push_str(&preamble::generate(Path::new(source.name()))); let scope = lint::Scope::new(file); - let decls = file.declarations.iter().map(|decl| generate_decl(&scope, file, decl)); - let code = quote! { - #preamble + for decl in &file.declarations { + code.push_str(&generate_decl(&scope, file, decl)); + code.push_str("\n\n"); + } - #(#decls)* - }; - let syntax_tree = syn::parse2(code).expect("Could not parse code"); - prettyplease::unparse(&syntax_tree) + code } #[cfg(test)] diff --git a/tools/pdl/src/backends/rust/preamble.rs b/tools/pdl/src/backends/rust/preamble.rs index 45978f13ff9..afd84da84a6 100644 --- a/tools/pdl/src/backends/rust/preamble.rs +++ b/tools/pdl/src/backends/rust/preamble.rs @@ -12,11 +12,13 @@ // See the License for the specific language governing permissions and // limitations under the License. -use quote::quote; use std::path::Path; +use crate::quote_block; + /// Generate the file preamble. -pub fn generate(path: &Path) -> proc_macro2::TokenStream { +pub fn generate(path: &Path) -> String { + let mut code = String::new(); // TODO(mgeisler): Make the generated code free from warnings. // // The code either needs @@ -48,7 +50,7 @@ pub fn generate(path: &Path) -> proc_macro2::TokenStream { // mod foo { include_str!("generated.rs") } // use foo::*; // fn after() {} - quote! { + code.push_str("e_block! { #[doc = #module_doc_string] use bytes::{Buf, BufMut, Bytes, BytesMut}; @@ -73,7 +75,9 @@ pub fn generate(path: &Path) -> proc_macro2::TokenStream { &self.0 } } + }); + code.push_str("e_block! { #[derive(Debug, Error)] pub enum Error { #[error("Packet parsing failed")] @@ -93,12 +97,16 @@ pub fn generate(path: &Path) -> proc_macro2::TokenStream { #[error("expected child {expected}, got {actual}")] InvalidChildError { expected: &'static str, actual: String }, } + }); + code.push_str("e_block! { pub trait Packet { fn to_bytes(self) -> Bytes; fn to_vec(self) -> Vec; } - } + }); + + code } #[cfg(test)] @@ -108,7 +116,7 @@ mod tests { #[test] fn test_generate_preamble() { - let actual_code = generate(Path::new("some/path/foo.pdl")).to_string(); + let actual_code = generate(Path::new("some/path/foo.pdl")); assert_snapshot_eq("tests/generated/preamble.rs", &format_rust(&actual_code)); } } -- GitLab From 2c05c32df647735d584e266c707d197c8c31e7fd Mon Sep 17 00:00:00 2001 From: Martin Geisler Date: Wed, 17 May 2023 18:55:44 +0000 Subject: [PATCH 0091/2405] Revert "pdl: Generate canonical tests with prettyplease" Revert submission 2586907 Reason for revert: http://b/283107621 Reverted changes: /q/submissionid:2586907 Change-Id: I1f96ca5ab15a0378488cd2df86a3e435e751422c --- tools/pdl/Android.bp | 21 ++++++++++++++----- tools/pdl/src/bin/generate-canonical-tests.rs | 21 ++++++++++--------- 2 files changed, 27 insertions(+), 15 deletions(-) diff --git a/tools/pdl/Android.bp b/tools/pdl/Android.bp index 65a23bcca4e..df4fd25fbaf 100644 --- a/tools/pdl/Android.bp +++ b/tools/pdl/Android.bp @@ -245,7 +245,6 @@ rust_binary_host { name: "pdl_generate_tests", srcs: ["src/bin/generate-canonical-tests.rs"], rustlibs: [ - "libprettyplease", "libproc_macro2", "libquote", "libserde", @@ -255,20 +254,32 @@ rust_binary_host { ], } +genrule_defaults { + name: "pdl_rust_generator_src_defaults", + tools: [ + ":pdl_generate_tests", + ":rustfmt", + ], +} + genrule { name: "pdl_rust_generator_tests_le_src", - cmd: "$(location :pdl_generate_tests) $(in) pdl_le_backend > $(out)", + cmd: "set -o pipefail;" + + " $(location :pdl_generate_tests) $(in) pdl_le_backend |" + + " $(location :rustfmt) > $(out)", srcs: ["tests/canonical/le_test_vectors.json"], out: ["le_canonical.rs"], - tools: [":pdl_generate_tests"], + defaults: ["pdl_rust_generator_src_defaults"], } genrule { name: "pdl_rust_generator_tests_be_src", - cmd: "$(location :pdl_generate_tests) $(in) pdl_be_backend > $(out)", + cmd: "set -o pipefail;" + + " $(location :pdl_generate_tests) $(in) pdl_be_backend |" + + " $(location :rustfmt) > $(out)", srcs: ["tests/canonical/be_test_vectors.json"], out: ["be_canonical.rs"], - tools: [":pdl_generate_tests"], + defaults: ["pdl_rust_generator_src_defaults"], } rust_test_host { diff --git a/tools/pdl/src/bin/generate-canonical-tests.rs b/tools/pdl/src/bin/generate-canonical-tests.rs index 44ad2b1543b..06246392497 100644 --- a/tools/pdl/src/bin/generate-canonical-tests.rs +++ b/tools/pdl/src/bin/generate-canonical-tests.rs @@ -128,16 +128,17 @@ fn generate_unit_tests(input: &str, packet_names: &[&str], module_name: &str) { } // TODO(mgeisler): make the generated code clean from warnings. - let code = quote! { - #![allow(warnings, missing_docs)] - - use #module::Packet; - use serde_json::json; - - #(#tests)* - }; - let syntax_tree = syn::parse2::(code).expect("Could not parse {code:#?}"); - println!("{}", prettyplease::unparse(&syntax_tree)); + println!("#![allow(warnings, missing_docs)]"); + println!(); + println!( + "{}", + "e! { + use #module::Packet; + use serde_json::json; + + #(#tests)* + } + ); } fn main() { -- GitLab From b2569c2766e742a32df3ed3a92f38bd3b7b847ac Mon Sep 17 00:00:00 2001 From: Martin Geisler Date: Wed, 17 May 2023 18:55:44 +0000 Subject: [PATCH 0092/2405] Revert "pdl: Generate snapshots using prettyplease" Revert submission 2586907 Reason for revert: http://b/283107621 Reverted changes: /q/submissionid:2586907 Change-Id: Iddbbedf65b43eb22eacc428690d9f97196ebfb72 --- tools/pdl/Android.bp | 9 +- tools/pdl/Cargo.toml | 1 - tools/pdl/src/backends/rust.rs | 4 +- tools/pdl/src/backends/rust/preamble.rs | 30 ++--- tools/pdl/src/test_utils.rs | 52 ++++++- .../custom_field_declaration_big_endian.rs | 30 +++-- .../custom_field_declaration_little_endian.rs | 30 +++-- .../generated/enum_declaration_big_endian.rs | 27 ++-- .../enum_declaration_little_endian.rs | 27 ++-- ...packet_decl_24bit_enum_array_big_endian.rs | 31 +++-- ...ket_decl_24bit_enum_array_little_endian.rs | 31 +++-- .../packet_decl_24bit_enum_big_endian.rs | 31 +++-- .../packet_decl_24bit_enum_little_endian.rs | 31 +++-- ...cket_decl_24bit_scalar_array_big_endian.rs | 23 ++-- ...t_decl_24bit_scalar_array_little_endian.rs | 23 ++-- .../packet_decl_24bit_scalar_big_endian.rs | 23 ++-- .../packet_decl_24bit_scalar_little_endian.rs | 23 ++-- ...packet_decl_64bit_enum_array_big_endian.rs | 37 ++--- ...ket_decl_64bit_enum_array_little_endian.rs | 31 +++-- .../packet_decl_64bit_enum_big_endian.rs | 28 ++-- .../packet_decl_64bit_enum_little_endian.rs | 31 +++-- ...cket_decl_64bit_scalar_array_big_endian.rs | 23 ++-- ...t_decl_64bit_scalar_array_little_endian.rs | 23 ++-- .../packet_decl_64bit_scalar_big_endian.rs | 23 ++-- .../packet_decl_64bit_scalar_little_endian.rs | 23 ++-- .../packet_decl_8bit_enum_array_big_endian.rs | 37 ++--- ...cket_decl_8bit_enum_array_little_endian.rs | 37 ++--- .../packet_decl_8bit_enum_big_endian.rs | 28 ++-- .../packet_decl_8bit_enum_little_endian.rs | 28 ++-- ...acket_decl_8bit_scalar_array_big_endian.rs | 23 ++-- ...et_decl_8bit_scalar_array_little_endian.rs | 23 ++-- .../packet_decl_8bit_scalar_big_endian.rs | 23 ++-- .../packet_decl_8bit_scalar_little_endian.rs | 23 ++-- ...ket_decl_array_dynamic_count_big_endian.rs | 32 +++-- ..._decl_array_dynamic_count_little_endian.rs | 32 +++-- ...cket_decl_array_dynamic_size_big_endian.rs | 42 +++--- ...t_decl_array_dynamic_size_little_endian.rs | 42 +++--- ..._element_width_dynamic_count_big_endian.rs | 38 +++--- ...ement_width_dynamic_count_little_endian.rs | 38 +++--- ...n_element_width_dynamic_size_big_endian.rs | 34 ++--- ...lement_width_dynamic_size_little_endian.rs | 34 ++--- ...cket_decl_array_with_padding_big_endian.rs | 33 +++-- ...t_decl_array_with_padding_little_endian.rs | 33 +++-- .../packet_decl_child_packets_big_endian.rs | 64 ++++----- ...packet_decl_child_packets_little_endian.rs | 64 ++++----- .../packet_decl_complex_scalars_big_endian.rs | 33 +++-- ...cket_decl_complex_scalars_little_endian.rs | 33 +++-- .../packet_decl_custom_field_big_endian.rs | 31 +++-- .../packet_decl_custom_field_little_endian.rs | 31 +++-- .../generated/packet_decl_empty_big_endian.rs | 23 ++-- .../packet_decl_empty_little_endian.rs | 23 ++-- ...packet_decl_fixed_enum_field_big_endian.rs | 28 ++-- ...ket_decl_fixed_enum_field_little_endian.rs | 28 ++-- ...cket_decl_fixed_scalar_field_big_endian.rs | 27 ++-- ...t_decl_fixed_scalar_field_little_endian.rs | 27 ++-- .../packet_decl_grand_children_big_endian.rs | 127 +++++++++--------- ...acket_decl_grand_children_little_endian.rs | 127 +++++++++--------- ...acket_decl_mask_scalar_value_big_endian.rs | 29 ++-- ...et_decl_mask_scalar_value_little_endian.rs | 29 ++-- ...ket_decl_mixed_scalars_enums_big_endian.rs | 49 +++---- ..._decl_mixed_scalars_enums_little_endian.rs | 49 +++---- ...l_payload_field_unknown_size_big_endian.rs | 27 ++-- ...ayload_field_unknown_size_little_endian.rs | 27 ++-- ..._field_unknown_size_terminal_big_endian.rs | 27 ++-- ...eld_unknown_size_terminal_little_endian.rs | 27 ++-- ..._payload_field_variable_size_big_endian.rs | 34 ++--- ...yload_field_variable_size_little_endian.rs | 34 ++--- .../packet_decl_reserved_field_big_endian.rs | 23 ++-- ...acket_decl_reserved_field_little_endian.rs | 23 ++-- .../packet_decl_simple_scalars_big_endian.rs | 29 ++-- ...acket_decl_simple_scalars_little_endian.rs | 29 ++-- tools/pdl/tests/generated/preamble.rs | 22 +-- .../struct_decl_complex_scalars_big_endian.rs | 23 ++-- ...ruct_decl_complex_scalars_little_endian.rs | 23 ++-- tools/pdl/tests/generated_files_compile.sh | 4 +- 75 files changed, 1304 insertions(+), 1095 deletions(-) diff --git a/tools/pdl/Android.bp b/tools/pdl/Android.bp index df4fd25fbaf..5bd51d77a93 100644 --- a/tools/pdl/Android.bp +++ b/tools/pdl/Android.bp @@ -15,7 +15,6 @@ rust_defaults { "libcodespan_reporting", "libheck", "libpest", - "libprettyplease", "libproc_macro2", "libquote", "libserde", @@ -122,7 +121,15 @@ rust_test_host { "libpaste", ], test_suites: ["general-tests"], + enabled: false, // rustfmt is only available on x86. + arch: { + x86_64: { + enabled: true, + }, + }, data: [ + ":rustfmt", + ":rustfmt.toml", ":pdl_generated_files", ], } diff --git a/tools/pdl/Cargo.toml b/tools/pdl/Cargo.toml index a74c8515e89..d8da5ff2556 100644 --- a/tools/pdl/Cargo.toml +++ b/tools/pdl/Cargo.toml @@ -19,7 +19,6 @@ quote = "1.0.21" serde_json = "1.0.86" argh = "0.1.7" syn = "1.0.102" -prettyplease = "0.1.25" [dependencies.serde] version = "1.0.145" diff --git a/tools/pdl/src/backends/rust.rs b/tools/pdl/src/backends/rust.rs index c9101521cb0..d7e355b427b 100644 --- a/tools/pdl/src/backends/rust.rs +++ b/tools/pdl/src/backends/rust.rs @@ -1012,7 +1012,7 @@ mod tests { use crate::analyzer; use crate::ast; use crate::parser::parse_inline; - use crate::test_utils::{assert_snapshot_eq, format_rust}; + use crate::test_utils::{assert_snapshot_eq, rustfmt}; use paste::paste; /// Parse a string fragment as a PDL file. @@ -1095,7 +1095,7 @@ mod tests { let actual_code = generate(&db, &file); assert_snapshot_eq( &format!("tests/generated/{name}_{endianness}.rs"), - &format_rust(&actual_code), + &rustfmt(&actual_code), ); } } diff --git a/tools/pdl/src/backends/rust/preamble.rs b/tools/pdl/src/backends/rust/preamble.rs index afd84da84a6..9b23ede5527 100644 --- a/tools/pdl/src/backends/rust/preamble.rs +++ b/tools/pdl/src/backends/rust/preamble.rs @@ -19,6 +19,7 @@ use crate::quote_block; /// Generate the file preamble. pub fn generate(path: &Path) -> String { let mut code = String::new(); + let filename = path.file_name().unwrap().to_str().expect("non UTF-8 filename"); // TODO(mgeisler): Make the generated code free from warnings. // // The code either needs @@ -33,35 +34,22 @@ pub fn generate(path: &Path) -> String { // to the generated code. We cannot add the module-level attribute // here because of how the generated code is used with include! in // lmp/src/packets.rs. - let filename = path.file_name().unwrap().to_str().expect("non UTF-8 filename"); - let module_doc_string = format!(" @generated rust packets from {filename}."); - // TODO(mgeisler): the doc comment below should be an outer - // comment (#![doc = ...]). However, people include the generated - // code in the middle of another module via include_str!: - // - // fn before() {} - // include_str!("generated.rs") - // fn after() {} - // - // It is illegal to have a //! comment in the middle of a file. We - // should refactor such usages to instead look like this: - // - // fn before() {} - // mod foo { include_str!("generated.rs") } - // use foo::*; - // fn after() {} - code.push_str("e_block! { - #[doc = #module_doc_string] + code.push_str(&format!("// @generated rust packets from {filename}\n\n")); + code.push_str("e_block! { use bytes::{Buf, BufMut, Bytes, BytesMut}; use std::convert::{TryFrom, TryInto}; use std::cell::Cell; use std::fmt; use std::sync::Arc; use thiserror::Error; + }); + code.push_str("e_block! { type Result = std::result::Result; + }); + code.push_str("e_block! { /// Private prevents users from creating arbitrary scalar values /// in situations where the value needs to be validated. /// Users can freely deref the value, but only the backend @@ -112,11 +100,11 @@ pub fn generate(path: &Path) -> String { #[cfg(test)] mod tests { use super::*; - use crate::test_utils::{assert_snapshot_eq, format_rust}; + use crate::test_utils::{assert_snapshot_eq, rustfmt}; #[test] fn test_generate_preamble() { let actual_code = generate(Path::new("some/path/foo.pdl")); - assert_snapshot_eq("tests/generated/preamble.rs", &format_rust(&actual_code)); + assert_snapshot_eq("tests/generated/preamble.rs", &rustfmt(&actual_code)); } } diff --git a/tools/pdl/src/test_utils.rs b/tools/pdl/src/test_utils.rs index 13a45fd4fa8..7e618f647eb 100644 --- a/tools/pdl/src/test_utils.rs +++ b/tools/pdl/src/test_utils.rs @@ -22,14 +22,54 @@ use std::fs; use std::io::Write; use std::path::Path; -use std::process::Command; +use std::process::{Command, Stdio}; use tempfile::NamedTempFile; -/// Format Rust code in `input`. -pub fn format_rust(input: &str) -> String { - let syntax_tree = syn::parse_file(input).expect("Could not parse {input:#?} as Rust code"); - let formatted = prettyplease::unparse(&syntax_tree); - format!("#![rustfmt::skip]\n{formatted}") +/// Search for a binary in `$PATH` or as a sibling to the current +/// executable (typically the test binary). +pub fn find_binary(name: &str) -> Result { + let mut current_exe = std::env::current_exe().unwrap(); + current_exe.pop(); + let paths = std::env::var_os("PATH").unwrap(); + for mut path in std::iter::once(current_exe.clone()).chain(std::env::split_paths(&paths)) { + path.push(name); + if path.exists() { + return Ok(path); + } + } + + Err(format!( + "could not find '{}' in the directory of the binary ({}) or in $PATH ({})", + name, + current_exe.to_string_lossy(), + paths.to_string_lossy(), + )) +} + +/// Run `input` through `rustfmt`. +/// +/// # Panics +/// +/// Panics if `rustfmt` cannot be found in the same directory as the +/// test executable or if it returns a non-zero exit code. +pub fn rustfmt(input: &str) -> String { + let rustfmt_path = find_binary("rustfmt").expect("cannot find rustfmt"); + let mut rustfmt = Command::new(&rustfmt_path) + .stdin(Stdio::piped()) + .stdout(Stdio::piped()) + .spawn() + .unwrap_or_else(|_| panic!("failed to start {:?}", &rustfmt_path)); + + let mut stdin = rustfmt.stdin.take().unwrap(); + // Owned copy which we can move into the writing thread. + let input = String::from(input); + std::thread::spawn(move || { + stdin.write_all(input.as_bytes()).expect("could not write to stdin"); + }); + + let output = rustfmt.wait_with_output().expect("error executing rustfmt"); + assert!(output.status.success(), "rustfmt failed: {}", output.status); + String::from_utf8(output.stdout).expect("rustfmt output was not UTF-8") } /// Find the unified diff between two strings using `diff`. diff --git a/tools/pdl/tests/generated/custom_field_declaration_big_endian.rs b/tools/pdl/tests/generated/custom_field_declaration_big_endian.rs index 31fa6036c15..3576f1f1ea5 100644 --- a/tools/pdl/tests/generated/custom_field_declaration_big_endian.rs +++ b/tools/pdl/tests/generated/custom_field_declaration_big_endian.rs @@ -1,16 +1,18 @@ -#![rustfmt::skip] -/// @generated rust packets from test. +// @generated rust packets from test + use bytes::{Buf, BufMut, Bytes, BytesMut}; -use std::convert::{TryFrom, TryInto}; use std::cell::Cell; +use std::convert::{TryFrom, TryInto}; use std::fmt; use std::sync::Arc; use thiserror::Error; + type Result = std::result::Result; -/// Private prevents users from creating arbitrary scalar values -/// in situations where the value needs to be validated. -/// Users can freely deref the value, but only the backend -/// may create it. + +#[doc = r" Private prevents users from creating arbitrary scalar values"] +#[doc = r" in situations where the value needs to be validated."] +#[doc = r" Users can freely deref the value, but only the backend"] +#[doc = r" may create it."] #[derive(Debug, Clone, Copy, Hash, PartialEq, Eq, PartialOrd, Ord)] pub struct Private(T); impl std::ops::Deref for Private { @@ -19,6 +21,7 @@ impl std::ops::Deref for Private { &self.0 } } + #[derive(Debug, Error)] pub enum Error { #[error("Packet parsing failed")] @@ -29,9 +32,7 @@ pub enum Error { InvalidFixedValue { expected: u64, actual: u64 }, #[error("when parsing {obj} needed length of {wanted} but got {got}")] InvalidLengthError { obj: String, wanted: usize, got: usize }, - #[error( - "array size ({array} bytes) is not a multiple of the element size ({element} bytes)" - )] + #[error("array size ({array} bytes) is not a multiple of the element size ({element} bytes)")] InvalidArraySize { array: usize, element: usize }, #[error("Due to size restrictions a struct could not be parsed.")] ImpossibleStructError, @@ -40,10 +41,12 @@ pub enum Error { #[error("expected child {expected}, got {actual}")] InvalidChildError { expected: &'static str, actual: String }, } + pub trait Packet { fn to_bytes(self) -> Bytes; fn to_vec(self) -> Vec; } + #[derive(Debug, Clone, Copy, Hash, Eq, PartialEq)] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] #[cfg_attr(feature = "serde", serde(from = "u32", into = "u32"))] @@ -63,6 +66,7 @@ impl From for ExactSize { ExactSize(value) } } + #[derive(Debug, Clone, Copy, Hash, Eq, PartialEq)] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] #[cfg_attr(feature = "serde", serde(try_from = "u32", into = "u32"))] @@ -80,6 +84,10 @@ impl From for u32 { impl TryFrom for TruncatedSize { type Error = u32; fn try_from(value: u32) -> std::result::Result { - if value > 0xff_ffff { Err(value) } else { Ok(TruncatedSize(value)) } + if value > 0xff_ffff { + Err(value) + } else { + Ok(TruncatedSize(value)) + } } } diff --git a/tools/pdl/tests/generated/custom_field_declaration_little_endian.rs b/tools/pdl/tests/generated/custom_field_declaration_little_endian.rs index 31fa6036c15..3576f1f1ea5 100644 --- a/tools/pdl/tests/generated/custom_field_declaration_little_endian.rs +++ b/tools/pdl/tests/generated/custom_field_declaration_little_endian.rs @@ -1,16 +1,18 @@ -#![rustfmt::skip] -/// @generated rust packets from test. +// @generated rust packets from test + use bytes::{Buf, BufMut, Bytes, BytesMut}; -use std::convert::{TryFrom, TryInto}; use std::cell::Cell; +use std::convert::{TryFrom, TryInto}; use std::fmt; use std::sync::Arc; use thiserror::Error; + type Result = std::result::Result; -/// Private prevents users from creating arbitrary scalar values -/// in situations where the value needs to be validated. -/// Users can freely deref the value, but only the backend -/// may create it. + +#[doc = r" Private prevents users from creating arbitrary scalar values"] +#[doc = r" in situations where the value needs to be validated."] +#[doc = r" Users can freely deref the value, but only the backend"] +#[doc = r" may create it."] #[derive(Debug, Clone, Copy, Hash, PartialEq, Eq, PartialOrd, Ord)] pub struct Private(T); impl std::ops::Deref for Private { @@ -19,6 +21,7 @@ impl std::ops::Deref for Private { &self.0 } } + #[derive(Debug, Error)] pub enum Error { #[error("Packet parsing failed")] @@ -29,9 +32,7 @@ pub enum Error { InvalidFixedValue { expected: u64, actual: u64 }, #[error("when parsing {obj} needed length of {wanted} but got {got}")] InvalidLengthError { obj: String, wanted: usize, got: usize }, - #[error( - "array size ({array} bytes) is not a multiple of the element size ({element} bytes)" - )] + #[error("array size ({array} bytes) is not a multiple of the element size ({element} bytes)")] InvalidArraySize { array: usize, element: usize }, #[error("Due to size restrictions a struct could not be parsed.")] ImpossibleStructError, @@ -40,10 +41,12 @@ pub enum Error { #[error("expected child {expected}, got {actual}")] InvalidChildError { expected: &'static str, actual: String }, } + pub trait Packet { fn to_bytes(self) -> Bytes; fn to_vec(self) -> Vec; } + #[derive(Debug, Clone, Copy, Hash, Eq, PartialEq)] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] #[cfg_attr(feature = "serde", serde(from = "u32", into = "u32"))] @@ -63,6 +66,7 @@ impl From for ExactSize { ExactSize(value) } } + #[derive(Debug, Clone, Copy, Hash, Eq, PartialEq)] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] #[cfg_attr(feature = "serde", serde(try_from = "u32", into = "u32"))] @@ -80,6 +84,10 @@ impl From for u32 { impl TryFrom for TruncatedSize { type Error = u32; fn try_from(value: u32) -> std::result::Result { - if value > 0xff_ffff { Err(value) } else { Ok(TruncatedSize(value)) } + if value > 0xff_ffff { + Err(value) + } else { + Ok(TruncatedSize(value)) + } } } diff --git a/tools/pdl/tests/generated/enum_declaration_big_endian.rs b/tools/pdl/tests/generated/enum_declaration_big_endian.rs index 87b5d0eec5c..f598c3408c0 100644 --- a/tools/pdl/tests/generated/enum_declaration_big_endian.rs +++ b/tools/pdl/tests/generated/enum_declaration_big_endian.rs @@ -1,16 +1,18 @@ -#![rustfmt::skip] -/// @generated rust packets from test. +// @generated rust packets from test + use bytes::{Buf, BufMut, Bytes, BytesMut}; -use std::convert::{TryFrom, TryInto}; use std::cell::Cell; +use std::convert::{TryFrom, TryInto}; use std::fmt; use std::sync::Arc; use thiserror::Error; + type Result = std::result::Result; -/// Private prevents users from creating arbitrary scalar values -/// in situations where the value needs to be validated. -/// Users can freely deref the value, but only the backend -/// may create it. + +#[doc = r" Private prevents users from creating arbitrary scalar values"] +#[doc = r" in situations where the value needs to be validated."] +#[doc = r" Users can freely deref the value, but only the backend"] +#[doc = r" may create it."] #[derive(Debug, Clone, Copy, Hash, PartialEq, Eq, PartialOrd, Ord)] pub struct Private(T); impl std::ops::Deref for Private { @@ -19,6 +21,7 @@ impl std::ops::Deref for Private { &self.0 } } + #[derive(Debug, Error)] pub enum Error { #[error("Packet parsing failed")] @@ -29,9 +32,7 @@ pub enum Error { InvalidFixedValue { expected: u64, actual: u64 }, #[error("when parsing {obj} needed length of {wanted} but got {got}")] InvalidLengthError { obj: String, wanted: usize, got: usize }, - #[error( - "array size ({array} bytes) is not a multiple of the element size ({element} bytes)" - )] + #[error("array size ({array} bytes) is not a multiple of the element size ({element} bytes)")] InvalidArraySize { array: usize, element: usize }, #[error("Due to size restrictions a struct could not be parsed.")] ImpossibleStructError, @@ -40,10 +41,12 @@ pub enum Error { #[error("expected child {expected}, got {actual}")] InvalidChildError { expected: &'static str, actual: String }, } + pub trait Packet { fn to_bytes(self) -> Bytes; fn to_vec(self) -> Vec; } + #[repr(u64)] #[derive(Debug, Clone, Copy, Hash, Eq, PartialEq)] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] @@ -110,6 +113,7 @@ impl From for u64 { u8::from(value) as Self } } + #[derive(Debug, Clone, Copy, Hash, Eq, PartialEq)] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] #[cfg_attr(feature = "serde", serde(try_from = "u8", into = "u8"))] @@ -181,6 +185,7 @@ impl From for u64 { u8::from(value) as Self } } + #[repr(u64)] #[derive(Debug, Clone, Copy, Hash, Eq, PartialEq)] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] @@ -265,6 +270,7 @@ impl From for u64 { u8::from(value) as Self } } + #[derive(Debug, Clone, Copy, Hash, Eq, PartialEq)] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] #[cfg_attr(feature = "serde", serde(try_from = "u8", into = "u8"))] @@ -336,6 +342,7 @@ impl From for u64 { u8::from(value) as Self } } + #[derive(Debug, Clone, Copy, Hash, Eq, PartialEq)] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] #[cfg_attr(feature = "serde", serde(try_from = "u8", into = "u8"))] diff --git a/tools/pdl/tests/generated/enum_declaration_little_endian.rs b/tools/pdl/tests/generated/enum_declaration_little_endian.rs index 87b5d0eec5c..f598c3408c0 100644 --- a/tools/pdl/tests/generated/enum_declaration_little_endian.rs +++ b/tools/pdl/tests/generated/enum_declaration_little_endian.rs @@ -1,16 +1,18 @@ -#![rustfmt::skip] -/// @generated rust packets from test. +// @generated rust packets from test + use bytes::{Buf, BufMut, Bytes, BytesMut}; -use std::convert::{TryFrom, TryInto}; use std::cell::Cell; +use std::convert::{TryFrom, TryInto}; use std::fmt; use std::sync::Arc; use thiserror::Error; + type Result = std::result::Result; -/// Private prevents users from creating arbitrary scalar values -/// in situations where the value needs to be validated. -/// Users can freely deref the value, but only the backend -/// may create it. + +#[doc = r" Private prevents users from creating arbitrary scalar values"] +#[doc = r" in situations where the value needs to be validated."] +#[doc = r" Users can freely deref the value, but only the backend"] +#[doc = r" may create it."] #[derive(Debug, Clone, Copy, Hash, PartialEq, Eq, PartialOrd, Ord)] pub struct Private(T); impl std::ops::Deref for Private { @@ -19,6 +21,7 @@ impl std::ops::Deref for Private { &self.0 } } + #[derive(Debug, Error)] pub enum Error { #[error("Packet parsing failed")] @@ -29,9 +32,7 @@ pub enum Error { InvalidFixedValue { expected: u64, actual: u64 }, #[error("when parsing {obj} needed length of {wanted} but got {got}")] InvalidLengthError { obj: String, wanted: usize, got: usize }, - #[error( - "array size ({array} bytes) is not a multiple of the element size ({element} bytes)" - )] + #[error("array size ({array} bytes) is not a multiple of the element size ({element} bytes)")] InvalidArraySize { array: usize, element: usize }, #[error("Due to size restrictions a struct could not be parsed.")] ImpossibleStructError, @@ -40,10 +41,12 @@ pub enum Error { #[error("expected child {expected}, got {actual}")] InvalidChildError { expected: &'static str, actual: String }, } + pub trait Packet { fn to_bytes(self) -> Bytes; fn to_vec(self) -> Vec; } + #[repr(u64)] #[derive(Debug, Clone, Copy, Hash, Eq, PartialEq)] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] @@ -110,6 +113,7 @@ impl From for u64 { u8::from(value) as Self } } + #[derive(Debug, Clone, Copy, Hash, Eq, PartialEq)] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] #[cfg_attr(feature = "serde", serde(try_from = "u8", into = "u8"))] @@ -181,6 +185,7 @@ impl From for u64 { u8::from(value) as Self } } + #[repr(u64)] #[derive(Debug, Clone, Copy, Hash, Eq, PartialEq)] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] @@ -265,6 +270,7 @@ impl From for u64 { u8::from(value) as Self } } + #[derive(Debug, Clone, Copy, Hash, Eq, PartialEq)] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] #[cfg_attr(feature = "serde", serde(try_from = "u8", into = "u8"))] @@ -336,6 +342,7 @@ impl From for u64 { u8::from(value) as Self } } + #[derive(Debug, Clone, Copy, Hash, Eq, PartialEq)] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] #[cfg_attr(feature = "serde", serde(try_from = "u8", into = "u8"))] diff --git a/tools/pdl/tests/generated/packet_decl_24bit_enum_array_big_endian.rs b/tools/pdl/tests/generated/packet_decl_24bit_enum_array_big_endian.rs index bd352ef126a..77b7af35271 100644 --- a/tools/pdl/tests/generated/packet_decl_24bit_enum_array_big_endian.rs +++ b/tools/pdl/tests/generated/packet_decl_24bit_enum_array_big_endian.rs @@ -1,16 +1,18 @@ -#![rustfmt::skip] -/// @generated rust packets from test. +// @generated rust packets from test + use bytes::{Buf, BufMut, Bytes, BytesMut}; -use std::convert::{TryFrom, TryInto}; use std::cell::Cell; +use std::convert::{TryFrom, TryInto}; use std::fmt; use std::sync::Arc; use thiserror::Error; + type Result = std::result::Result; -/// Private prevents users from creating arbitrary scalar values -/// in situations where the value needs to be validated. -/// Users can freely deref the value, but only the backend -/// may create it. + +#[doc = r" Private prevents users from creating arbitrary scalar values"] +#[doc = r" in situations where the value needs to be validated."] +#[doc = r" Users can freely deref the value, but only the backend"] +#[doc = r" may create it."] #[derive(Debug, Clone, Copy, Hash, PartialEq, Eq, PartialOrd, Ord)] pub struct Private(T); impl std::ops::Deref for Private { @@ -19,6 +21,7 @@ impl std::ops::Deref for Private { &self.0 } } + #[derive(Debug, Error)] pub enum Error { #[error("Packet parsing failed")] @@ -29,9 +32,7 @@ pub enum Error { InvalidFixedValue { expected: u64, actual: u64 }, #[error("when parsing {obj} needed length of {wanted} but got {got}")] InvalidLengthError { obj: String, wanted: usize, got: usize }, - #[error( - "array size ({array} bytes) is not a multiple of the element size ({element} bytes)" - )] + #[error("array size ({array} bytes) is not a multiple of the element size ({element} bytes)")] InvalidArraySize { array: usize, element: usize }, #[error("Due to size restrictions a struct could not be parsed.")] ImpossibleStructError, @@ -40,10 +41,12 @@ pub enum Error { #[error("expected child {expected}, got {actual}")] InvalidChildError { expected: &'static str, actual: String }, } + pub trait Packet { fn to_bytes(self) -> Bytes; fn to_vec(self) -> Vec; } + #[repr(u64)] #[derive(Debug, Clone, Copy, Hash, Eq, PartialEq)] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] @@ -90,6 +93,7 @@ impl From for u64 { u32::from(value) as Self } } + #[derive(Debug, Clone, PartialEq, Eq)] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] pub struct BarData { @@ -125,13 +129,14 @@ impl BarData { } let x = (0..5) .map(|_| { - Foo::try_from(bytes.get_mut().get_uint(3) as u32) - .map_err(|_| Error::InvalidEnumValueError { + Foo::try_from(bytes.get_mut().get_uint(3) as u32).map_err(|_| { + Error::InvalidEnumValueError { obj: "Bar".to_string(), field: String::new(), value: 0, type_: "Foo".to_string(), - }) + } + }) }) .collect::>>()? .try_into() diff --git a/tools/pdl/tests/generated/packet_decl_24bit_enum_array_little_endian.rs b/tools/pdl/tests/generated/packet_decl_24bit_enum_array_little_endian.rs index 5027984e5b6..74498b4a5eb 100644 --- a/tools/pdl/tests/generated/packet_decl_24bit_enum_array_little_endian.rs +++ b/tools/pdl/tests/generated/packet_decl_24bit_enum_array_little_endian.rs @@ -1,16 +1,18 @@ -#![rustfmt::skip] -/// @generated rust packets from test. +// @generated rust packets from test + use bytes::{Buf, BufMut, Bytes, BytesMut}; -use std::convert::{TryFrom, TryInto}; use std::cell::Cell; +use std::convert::{TryFrom, TryInto}; use std::fmt; use std::sync::Arc; use thiserror::Error; + type Result = std::result::Result; -/// Private prevents users from creating arbitrary scalar values -/// in situations where the value needs to be validated. -/// Users can freely deref the value, but only the backend -/// may create it. + +#[doc = r" Private prevents users from creating arbitrary scalar values"] +#[doc = r" in situations where the value needs to be validated."] +#[doc = r" Users can freely deref the value, but only the backend"] +#[doc = r" may create it."] #[derive(Debug, Clone, Copy, Hash, PartialEq, Eq, PartialOrd, Ord)] pub struct Private(T); impl std::ops::Deref for Private { @@ -19,6 +21,7 @@ impl std::ops::Deref for Private { &self.0 } } + #[derive(Debug, Error)] pub enum Error { #[error("Packet parsing failed")] @@ -29,9 +32,7 @@ pub enum Error { InvalidFixedValue { expected: u64, actual: u64 }, #[error("when parsing {obj} needed length of {wanted} but got {got}")] InvalidLengthError { obj: String, wanted: usize, got: usize }, - #[error( - "array size ({array} bytes) is not a multiple of the element size ({element} bytes)" - )] + #[error("array size ({array} bytes) is not a multiple of the element size ({element} bytes)")] InvalidArraySize { array: usize, element: usize }, #[error("Due to size restrictions a struct could not be parsed.")] ImpossibleStructError, @@ -40,10 +41,12 @@ pub enum Error { #[error("expected child {expected}, got {actual}")] InvalidChildError { expected: &'static str, actual: String }, } + pub trait Packet { fn to_bytes(self) -> Bytes; fn to_vec(self) -> Vec; } + #[repr(u64)] #[derive(Debug, Clone, Copy, Hash, Eq, PartialEq)] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] @@ -90,6 +93,7 @@ impl From for u64 { u32::from(value) as Self } } + #[derive(Debug, Clone, PartialEq, Eq)] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] pub struct BarData { @@ -125,13 +129,14 @@ impl BarData { } let x = (0..5) .map(|_| { - Foo::try_from(bytes.get_mut().get_uint_le(3) as u32) - .map_err(|_| Error::InvalidEnumValueError { + Foo::try_from(bytes.get_mut().get_uint_le(3) as u32).map_err(|_| { + Error::InvalidEnumValueError { obj: "Bar".to_string(), field: String::new(), value: 0, type_: "Foo".to_string(), - }) + } + }) }) .collect::>>()? .try_into() diff --git a/tools/pdl/tests/generated/packet_decl_24bit_enum_big_endian.rs b/tools/pdl/tests/generated/packet_decl_24bit_enum_big_endian.rs index d2b63bebab9..1a7ae4c6bc9 100644 --- a/tools/pdl/tests/generated/packet_decl_24bit_enum_big_endian.rs +++ b/tools/pdl/tests/generated/packet_decl_24bit_enum_big_endian.rs @@ -1,16 +1,18 @@ -#![rustfmt::skip] -/// @generated rust packets from test. +// @generated rust packets from test + use bytes::{Buf, BufMut, Bytes, BytesMut}; -use std::convert::{TryFrom, TryInto}; use std::cell::Cell; +use std::convert::{TryFrom, TryInto}; use std::fmt; use std::sync::Arc; use thiserror::Error; + type Result = std::result::Result; -/// Private prevents users from creating arbitrary scalar values -/// in situations where the value needs to be validated. -/// Users can freely deref the value, but only the backend -/// may create it. + +#[doc = r" Private prevents users from creating arbitrary scalar values"] +#[doc = r" in situations where the value needs to be validated."] +#[doc = r" Users can freely deref the value, but only the backend"] +#[doc = r" may create it."] #[derive(Debug, Clone, Copy, Hash, PartialEq, Eq, PartialOrd, Ord)] pub struct Private(T); impl std::ops::Deref for Private { @@ -19,6 +21,7 @@ impl std::ops::Deref for Private { &self.0 } } + #[derive(Debug, Error)] pub enum Error { #[error("Packet parsing failed")] @@ -29,9 +32,7 @@ pub enum Error { InvalidFixedValue { expected: u64, actual: u64 }, #[error("when parsing {obj} needed length of {wanted} but got {got}")] InvalidLengthError { obj: String, wanted: usize, got: usize }, - #[error( - "array size ({array} bytes) is not a multiple of the element size ({element} bytes)" - )] + #[error("array size ({array} bytes) is not a multiple of the element size ({element} bytes)")] InvalidArraySize { array: usize, element: usize }, #[error("Due to size restrictions a struct could not be parsed.")] ImpossibleStructError, @@ -40,10 +41,12 @@ pub enum Error { #[error("expected child {expected}, got {actual}")] InvalidChildError { expected: &'static str, actual: String }, } + pub trait Packet { fn to_bytes(self) -> Bytes; fn to_vec(self) -> Vec; } + #[repr(u64)] #[derive(Debug, Clone, Copy, Hash, Eq, PartialEq)] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] @@ -90,6 +93,7 @@ impl From for u64 { u32::from(value) as Self } } + #[derive(Debug, Clone, PartialEq, Eq)] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] pub struct BarData { @@ -123,13 +127,14 @@ impl BarData { got: bytes.get().remaining(), }); } - let x = Foo::try_from(bytes.get_mut().get_uint(3) as u32) - .map_err(|_| Error::InvalidEnumValueError { + let x = Foo::try_from(bytes.get_mut().get_uint(3) as u32).map_err(|_| { + Error::InvalidEnumValueError { obj: "Bar".to_string(), field: "x".to_string(), value: bytes.get_mut().get_uint(3) as u32 as u64, type_: "Foo".to_string(), - })?; + } + })?; Ok(Self { x }) } fn write_to(&self, buffer: &mut BytesMut) { diff --git a/tools/pdl/tests/generated/packet_decl_24bit_enum_little_endian.rs b/tools/pdl/tests/generated/packet_decl_24bit_enum_little_endian.rs index 40f98945b0d..1edc62686cf 100644 --- a/tools/pdl/tests/generated/packet_decl_24bit_enum_little_endian.rs +++ b/tools/pdl/tests/generated/packet_decl_24bit_enum_little_endian.rs @@ -1,16 +1,18 @@ -#![rustfmt::skip] -/// @generated rust packets from test. +// @generated rust packets from test + use bytes::{Buf, BufMut, Bytes, BytesMut}; -use std::convert::{TryFrom, TryInto}; use std::cell::Cell; +use std::convert::{TryFrom, TryInto}; use std::fmt; use std::sync::Arc; use thiserror::Error; + type Result = std::result::Result; -/// Private prevents users from creating arbitrary scalar values -/// in situations where the value needs to be validated. -/// Users can freely deref the value, but only the backend -/// may create it. + +#[doc = r" Private prevents users from creating arbitrary scalar values"] +#[doc = r" in situations where the value needs to be validated."] +#[doc = r" Users can freely deref the value, but only the backend"] +#[doc = r" may create it."] #[derive(Debug, Clone, Copy, Hash, PartialEq, Eq, PartialOrd, Ord)] pub struct Private(T); impl std::ops::Deref for Private { @@ -19,6 +21,7 @@ impl std::ops::Deref for Private { &self.0 } } + #[derive(Debug, Error)] pub enum Error { #[error("Packet parsing failed")] @@ -29,9 +32,7 @@ pub enum Error { InvalidFixedValue { expected: u64, actual: u64 }, #[error("when parsing {obj} needed length of {wanted} but got {got}")] InvalidLengthError { obj: String, wanted: usize, got: usize }, - #[error( - "array size ({array} bytes) is not a multiple of the element size ({element} bytes)" - )] + #[error("array size ({array} bytes) is not a multiple of the element size ({element} bytes)")] InvalidArraySize { array: usize, element: usize }, #[error("Due to size restrictions a struct could not be parsed.")] ImpossibleStructError, @@ -40,10 +41,12 @@ pub enum Error { #[error("expected child {expected}, got {actual}")] InvalidChildError { expected: &'static str, actual: String }, } + pub trait Packet { fn to_bytes(self) -> Bytes; fn to_vec(self) -> Vec; } + #[repr(u64)] #[derive(Debug, Clone, Copy, Hash, Eq, PartialEq)] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] @@ -90,6 +93,7 @@ impl From for u64 { u32::from(value) as Self } } + #[derive(Debug, Clone, PartialEq, Eq)] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] pub struct BarData { @@ -123,13 +127,14 @@ impl BarData { got: bytes.get().remaining(), }); } - let x = Foo::try_from(bytes.get_mut().get_uint_le(3) as u32) - .map_err(|_| Error::InvalidEnumValueError { + let x = Foo::try_from(bytes.get_mut().get_uint_le(3) as u32).map_err(|_| { + Error::InvalidEnumValueError { obj: "Bar".to_string(), field: "x".to_string(), value: bytes.get_mut().get_uint_le(3) as u32 as u64, type_: "Foo".to_string(), - })?; + } + })?; Ok(Self { x }) } fn write_to(&self, buffer: &mut BytesMut) { diff --git a/tools/pdl/tests/generated/packet_decl_24bit_scalar_array_big_endian.rs b/tools/pdl/tests/generated/packet_decl_24bit_scalar_array_big_endian.rs index eaa75379059..2289d06265d 100644 --- a/tools/pdl/tests/generated/packet_decl_24bit_scalar_array_big_endian.rs +++ b/tools/pdl/tests/generated/packet_decl_24bit_scalar_array_big_endian.rs @@ -1,16 +1,18 @@ -#![rustfmt::skip] -/// @generated rust packets from test. +// @generated rust packets from test + use bytes::{Buf, BufMut, Bytes, BytesMut}; -use std::convert::{TryFrom, TryInto}; use std::cell::Cell; +use std::convert::{TryFrom, TryInto}; use std::fmt; use std::sync::Arc; use thiserror::Error; + type Result = std::result::Result; -/// Private prevents users from creating arbitrary scalar values -/// in situations where the value needs to be validated. -/// Users can freely deref the value, but only the backend -/// may create it. + +#[doc = r" Private prevents users from creating arbitrary scalar values"] +#[doc = r" in situations where the value needs to be validated."] +#[doc = r" Users can freely deref the value, but only the backend"] +#[doc = r" may create it."] #[derive(Debug, Clone, Copy, Hash, PartialEq, Eq, PartialOrd, Ord)] pub struct Private(T); impl std::ops::Deref for Private { @@ -19,6 +21,7 @@ impl std::ops::Deref for Private { &self.0 } } + #[derive(Debug, Error)] pub enum Error { #[error("Packet parsing failed")] @@ -29,9 +32,7 @@ pub enum Error { InvalidFixedValue { expected: u64, actual: u64 }, #[error("when parsing {obj} needed length of {wanted} but got {got}")] InvalidLengthError { obj: String, wanted: usize, got: usize }, - #[error( - "array size ({array} bytes) is not a multiple of the element size ({element} bytes)" - )] + #[error("array size ({array} bytes) is not a multiple of the element size ({element} bytes)")] InvalidArraySize { array: usize, element: usize }, #[error("Due to size restrictions a struct could not be parsed.")] ImpossibleStructError, @@ -40,10 +41,12 @@ pub enum Error { #[error("expected child {expected}, got {actual}")] InvalidChildError { expected: &'static str, actual: String }, } + pub trait Packet { fn to_bytes(self) -> Bytes; fn to_vec(self) -> Vec; } + #[derive(Debug, Clone, PartialEq, Eq)] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] pub struct FooData { diff --git a/tools/pdl/tests/generated/packet_decl_24bit_scalar_array_little_endian.rs b/tools/pdl/tests/generated/packet_decl_24bit_scalar_array_little_endian.rs index f9878462a9d..8cf1ec587f1 100644 --- a/tools/pdl/tests/generated/packet_decl_24bit_scalar_array_little_endian.rs +++ b/tools/pdl/tests/generated/packet_decl_24bit_scalar_array_little_endian.rs @@ -1,16 +1,18 @@ -#![rustfmt::skip] -/// @generated rust packets from test. +// @generated rust packets from test + use bytes::{Buf, BufMut, Bytes, BytesMut}; -use std::convert::{TryFrom, TryInto}; use std::cell::Cell; +use std::convert::{TryFrom, TryInto}; use std::fmt; use std::sync::Arc; use thiserror::Error; + type Result = std::result::Result; -/// Private prevents users from creating arbitrary scalar values -/// in situations where the value needs to be validated. -/// Users can freely deref the value, but only the backend -/// may create it. + +#[doc = r" Private prevents users from creating arbitrary scalar values"] +#[doc = r" in situations where the value needs to be validated."] +#[doc = r" Users can freely deref the value, but only the backend"] +#[doc = r" may create it."] #[derive(Debug, Clone, Copy, Hash, PartialEq, Eq, PartialOrd, Ord)] pub struct Private(T); impl std::ops::Deref for Private { @@ -19,6 +21,7 @@ impl std::ops::Deref for Private { &self.0 } } + #[derive(Debug, Error)] pub enum Error { #[error("Packet parsing failed")] @@ -29,9 +32,7 @@ pub enum Error { InvalidFixedValue { expected: u64, actual: u64 }, #[error("when parsing {obj} needed length of {wanted} but got {got}")] InvalidLengthError { obj: String, wanted: usize, got: usize }, - #[error( - "array size ({array} bytes) is not a multiple of the element size ({element} bytes)" - )] + #[error("array size ({array} bytes) is not a multiple of the element size ({element} bytes)")] InvalidArraySize { array: usize, element: usize }, #[error("Due to size restrictions a struct could not be parsed.")] ImpossibleStructError, @@ -40,10 +41,12 @@ pub enum Error { #[error("expected child {expected}, got {actual}")] InvalidChildError { expected: &'static str, actual: String }, } + pub trait Packet { fn to_bytes(self) -> Bytes; fn to_vec(self) -> Vec; } + #[derive(Debug, Clone, PartialEq, Eq)] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] pub struct FooData { diff --git a/tools/pdl/tests/generated/packet_decl_24bit_scalar_big_endian.rs b/tools/pdl/tests/generated/packet_decl_24bit_scalar_big_endian.rs index e5aa0e26924..4782eabd3c2 100644 --- a/tools/pdl/tests/generated/packet_decl_24bit_scalar_big_endian.rs +++ b/tools/pdl/tests/generated/packet_decl_24bit_scalar_big_endian.rs @@ -1,16 +1,18 @@ -#![rustfmt::skip] -/// @generated rust packets from test. +// @generated rust packets from test + use bytes::{Buf, BufMut, Bytes, BytesMut}; -use std::convert::{TryFrom, TryInto}; use std::cell::Cell; +use std::convert::{TryFrom, TryInto}; use std::fmt; use std::sync::Arc; use thiserror::Error; + type Result = std::result::Result; -/// Private prevents users from creating arbitrary scalar values -/// in situations where the value needs to be validated. -/// Users can freely deref the value, but only the backend -/// may create it. + +#[doc = r" Private prevents users from creating arbitrary scalar values"] +#[doc = r" in situations where the value needs to be validated."] +#[doc = r" Users can freely deref the value, but only the backend"] +#[doc = r" may create it."] #[derive(Debug, Clone, Copy, Hash, PartialEq, Eq, PartialOrd, Ord)] pub struct Private(T); impl std::ops::Deref for Private { @@ -19,6 +21,7 @@ impl std::ops::Deref for Private { &self.0 } } + #[derive(Debug, Error)] pub enum Error { #[error("Packet parsing failed")] @@ -29,9 +32,7 @@ pub enum Error { InvalidFixedValue { expected: u64, actual: u64 }, #[error("when parsing {obj} needed length of {wanted} but got {got}")] InvalidLengthError { obj: String, wanted: usize, got: usize }, - #[error( - "array size ({array} bytes) is not a multiple of the element size ({element} bytes)" - )] + #[error("array size ({array} bytes) is not a multiple of the element size ({element} bytes)")] InvalidArraySize { array: usize, element: usize }, #[error("Due to size restrictions a struct could not be parsed.")] ImpossibleStructError, @@ -40,10 +41,12 @@ pub enum Error { #[error("expected child {expected}, got {actual}")] InvalidChildError { expected: &'static str, actual: String }, } + pub trait Packet { fn to_bytes(self) -> Bytes; fn to_vec(self) -> Vec; } + #[derive(Debug, Clone, PartialEq, Eq)] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] pub struct FooData { diff --git a/tools/pdl/tests/generated/packet_decl_24bit_scalar_little_endian.rs b/tools/pdl/tests/generated/packet_decl_24bit_scalar_little_endian.rs index c9a65ed19b3..a0f1c58e0d8 100644 --- a/tools/pdl/tests/generated/packet_decl_24bit_scalar_little_endian.rs +++ b/tools/pdl/tests/generated/packet_decl_24bit_scalar_little_endian.rs @@ -1,16 +1,18 @@ -#![rustfmt::skip] -/// @generated rust packets from test. +// @generated rust packets from test + use bytes::{Buf, BufMut, Bytes, BytesMut}; -use std::convert::{TryFrom, TryInto}; use std::cell::Cell; +use std::convert::{TryFrom, TryInto}; use std::fmt; use std::sync::Arc; use thiserror::Error; + type Result = std::result::Result; -/// Private prevents users from creating arbitrary scalar values -/// in situations where the value needs to be validated. -/// Users can freely deref the value, but only the backend -/// may create it. + +#[doc = r" Private prevents users from creating arbitrary scalar values"] +#[doc = r" in situations where the value needs to be validated."] +#[doc = r" Users can freely deref the value, but only the backend"] +#[doc = r" may create it."] #[derive(Debug, Clone, Copy, Hash, PartialEq, Eq, PartialOrd, Ord)] pub struct Private(T); impl std::ops::Deref for Private { @@ -19,6 +21,7 @@ impl std::ops::Deref for Private { &self.0 } } + #[derive(Debug, Error)] pub enum Error { #[error("Packet parsing failed")] @@ -29,9 +32,7 @@ pub enum Error { InvalidFixedValue { expected: u64, actual: u64 }, #[error("when parsing {obj} needed length of {wanted} but got {got}")] InvalidLengthError { obj: String, wanted: usize, got: usize }, - #[error( - "array size ({array} bytes) is not a multiple of the element size ({element} bytes)" - )] + #[error("array size ({array} bytes) is not a multiple of the element size ({element} bytes)")] InvalidArraySize { array: usize, element: usize }, #[error("Due to size restrictions a struct could not be parsed.")] ImpossibleStructError, @@ -40,10 +41,12 @@ pub enum Error { #[error("expected child {expected}, got {actual}")] InvalidChildError { expected: &'static str, actual: String }, } + pub trait Packet { fn to_bytes(self) -> Bytes; fn to_vec(self) -> Vec; } + #[derive(Debug, Clone, PartialEq, Eq)] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] pub struct FooData { diff --git a/tools/pdl/tests/generated/packet_decl_64bit_enum_array_big_endian.rs b/tools/pdl/tests/generated/packet_decl_64bit_enum_array_big_endian.rs index 69409017367..c7ebf8b7795 100644 --- a/tools/pdl/tests/generated/packet_decl_64bit_enum_array_big_endian.rs +++ b/tools/pdl/tests/generated/packet_decl_64bit_enum_array_big_endian.rs @@ -1,16 +1,18 @@ -#![rustfmt::skip] -/// @generated rust packets from test. +// @generated rust packets from test + use bytes::{Buf, BufMut, Bytes, BytesMut}; -use std::convert::{TryFrom, TryInto}; use std::cell::Cell; +use std::convert::{TryFrom, TryInto}; use std::fmt; use std::sync::Arc; use thiserror::Error; + type Result = std::result::Result; -/// Private prevents users from creating arbitrary scalar values -/// in situations where the value needs to be validated. -/// Users can freely deref the value, but only the backend -/// may create it. + +#[doc = r" Private prevents users from creating arbitrary scalar values"] +#[doc = r" in situations where the value needs to be validated."] +#[doc = r" Users can freely deref the value, but only the backend"] +#[doc = r" may create it."] #[derive(Debug, Clone, Copy, Hash, PartialEq, Eq, PartialOrd, Ord)] pub struct Private(T); impl std::ops::Deref for Private { @@ -19,6 +21,7 @@ impl std::ops::Deref for Private { &self.0 } } + #[derive(Debug, Error)] pub enum Error { #[error("Packet parsing failed")] @@ -29,9 +32,7 @@ pub enum Error { InvalidFixedValue { expected: u64, actual: u64 }, #[error("when parsing {obj} needed length of {wanted} but got {got}")] InvalidLengthError { obj: String, wanted: usize, got: usize }, - #[error( - "array size ({array} bytes) is not a multiple of the element size ({element} bytes)" - )] + #[error("array size ({array} bytes) is not a multiple of the element size ({element} bytes)")] InvalidArraySize { array: usize, element: usize }, #[error("Due to size restrictions a struct could not be parsed.")] ImpossibleStructError, @@ -40,10 +41,12 @@ pub enum Error { #[error("expected child {expected}, got {actual}")] InvalidChildError { expected: &'static str, actual: String }, } + pub trait Packet { fn to_bytes(self) -> Bytes; fn to_vec(self) -> Vec; } + #[repr(u64)] #[derive(Debug, Clone, Copy, Hash, Eq, PartialEq)] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] @@ -75,6 +78,7 @@ impl From for u64 { (&value).into() } } + #[derive(Debug, Clone, PartialEq, Eq)] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] pub struct BarData { @@ -110,13 +114,12 @@ impl BarData { } let x = (0..7) .map(|_| { - Foo::try_from(bytes.get_mut().get_u64()) - .map_err(|_| Error::InvalidEnumValueError { - obj: "Bar".to_string(), - field: String::new(), - value: 0, - type_: "Foo".to_string(), - }) + Foo::try_from(bytes.get_mut().get_u64()).map_err(|_| Error::InvalidEnumValueError { + obj: "Bar".to_string(), + field: String::new(), + value: 0, + type_: "Foo".to_string(), + }) }) .collect::>>()? .try_into() diff --git a/tools/pdl/tests/generated/packet_decl_64bit_enum_array_little_endian.rs b/tools/pdl/tests/generated/packet_decl_64bit_enum_array_little_endian.rs index a7008b37d02..d8d0d72110f 100644 --- a/tools/pdl/tests/generated/packet_decl_64bit_enum_array_little_endian.rs +++ b/tools/pdl/tests/generated/packet_decl_64bit_enum_array_little_endian.rs @@ -1,16 +1,18 @@ -#![rustfmt::skip] -/// @generated rust packets from test. +// @generated rust packets from test + use bytes::{Buf, BufMut, Bytes, BytesMut}; -use std::convert::{TryFrom, TryInto}; use std::cell::Cell; +use std::convert::{TryFrom, TryInto}; use std::fmt; use std::sync::Arc; use thiserror::Error; + type Result = std::result::Result; -/// Private prevents users from creating arbitrary scalar values -/// in situations where the value needs to be validated. -/// Users can freely deref the value, but only the backend -/// may create it. + +#[doc = r" Private prevents users from creating arbitrary scalar values"] +#[doc = r" in situations where the value needs to be validated."] +#[doc = r" Users can freely deref the value, but only the backend"] +#[doc = r" may create it."] #[derive(Debug, Clone, Copy, Hash, PartialEq, Eq, PartialOrd, Ord)] pub struct Private(T); impl std::ops::Deref for Private { @@ -19,6 +21,7 @@ impl std::ops::Deref for Private { &self.0 } } + #[derive(Debug, Error)] pub enum Error { #[error("Packet parsing failed")] @@ -29,9 +32,7 @@ pub enum Error { InvalidFixedValue { expected: u64, actual: u64 }, #[error("when parsing {obj} needed length of {wanted} but got {got}")] InvalidLengthError { obj: String, wanted: usize, got: usize }, - #[error( - "array size ({array} bytes) is not a multiple of the element size ({element} bytes)" - )] + #[error("array size ({array} bytes) is not a multiple of the element size ({element} bytes)")] InvalidArraySize { array: usize, element: usize }, #[error("Due to size restrictions a struct could not be parsed.")] ImpossibleStructError, @@ -40,10 +41,12 @@ pub enum Error { #[error("expected child {expected}, got {actual}")] InvalidChildError { expected: &'static str, actual: String }, } + pub trait Packet { fn to_bytes(self) -> Bytes; fn to_vec(self) -> Vec; } + #[repr(u64)] #[derive(Debug, Clone, Copy, Hash, Eq, PartialEq)] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] @@ -75,6 +78,7 @@ impl From for u64 { (&value).into() } } + #[derive(Debug, Clone, PartialEq, Eq)] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] pub struct BarData { @@ -110,13 +114,14 @@ impl BarData { } let x = (0..7) .map(|_| { - Foo::try_from(bytes.get_mut().get_u64_le()) - .map_err(|_| Error::InvalidEnumValueError { + Foo::try_from(bytes.get_mut().get_u64_le()).map_err(|_| { + Error::InvalidEnumValueError { obj: "Bar".to_string(), field: String::new(), value: 0, type_: "Foo".to_string(), - }) + } + }) }) .collect::>>()? .try_into() diff --git a/tools/pdl/tests/generated/packet_decl_64bit_enum_big_endian.rs b/tools/pdl/tests/generated/packet_decl_64bit_enum_big_endian.rs index a8f182c32ee..0dd9553ae73 100644 --- a/tools/pdl/tests/generated/packet_decl_64bit_enum_big_endian.rs +++ b/tools/pdl/tests/generated/packet_decl_64bit_enum_big_endian.rs @@ -1,16 +1,18 @@ -#![rustfmt::skip] -/// @generated rust packets from test. +// @generated rust packets from test + use bytes::{Buf, BufMut, Bytes, BytesMut}; -use std::convert::{TryFrom, TryInto}; use std::cell::Cell; +use std::convert::{TryFrom, TryInto}; use std::fmt; use std::sync::Arc; use thiserror::Error; + type Result = std::result::Result; -/// Private prevents users from creating arbitrary scalar values -/// in situations where the value needs to be validated. -/// Users can freely deref the value, but only the backend -/// may create it. + +#[doc = r" Private prevents users from creating arbitrary scalar values"] +#[doc = r" in situations where the value needs to be validated."] +#[doc = r" Users can freely deref the value, but only the backend"] +#[doc = r" may create it."] #[derive(Debug, Clone, Copy, Hash, PartialEq, Eq, PartialOrd, Ord)] pub struct Private(T); impl std::ops::Deref for Private { @@ -19,6 +21,7 @@ impl std::ops::Deref for Private { &self.0 } } + #[derive(Debug, Error)] pub enum Error { #[error("Packet parsing failed")] @@ -29,9 +32,7 @@ pub enum Error { InvalidFixedValue { expected: u64, actual: u64 }, #[error("when parsing {obj} needed length of {wanted} but got {got}")] InvalidLengthError { obj: String, wanted: usize, got: usize }, - #[error( - "array size ({array} bytes) is not a multiple of the element size ({element} bytes)" - )] + #[error("array size ({array} bytes) is not a multiple of the element size ({element} bytes)")] InvalidArraySize { array: usize, element: usize }, #[error("Due to size restrictions a struct could not be parsed.")] ImpossibleStructError, @@ -40,10 +41,12 @@ pub enum Error { #[error("expected child {expected}, got {actual}")] InvalidChildError { expected: &'static str, actual: String }, } + pub trait Packet { fn to_bytes(self) -> Bytes; fn to_vec(self) -> Vec; } + #[repr(u64)] #[derive(Debug, Clone, Copy, Hash, Eq, PartialEq)] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] @@ -75,6 +78,7 @@ impl From for u64 { (&value).into() } } + #[derive(Debug, Clone, PartialEq, Eq)] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] pub struct BarData { @@ -108,8 +112,8 @@ impl BarData { got: bytes.get().remaining(), }); } - let x = Foo::try_from(bytes.get_mut().get_u64()) - .map_err(|_| Error::InvalidEnumValueError { + let x = + Foo::try_from(bytes.get_mut().get_u64()).map_err(|_| Error::InvalidEnumValueError { obj: "Bar".to_string(), field: "x".to_string(), value: bytes.get_mut().get_u64() as u64, diff --git a/tools/pdl/tests/generated/packet_decl_64bit_enum_little_endian.rs b/tools/pdl/tests/generated/packet_decl_64bit_enum_little_endian.rs index 8fa8467f9ef..b9182cc2888 100644 --- a/tools/pdl/tests/generated/packet_decl_64bit_enum_little_endian.rs +++ b/tools/pdl/tests/generated/packet_decl_64bit_enum_little_endian.rs @@ -1,16 +1,18 @@ -#![rustfmt::skip] -/// @generated rust packets from test. +// @generated rust packets from test + use bytes::{Buf, BufMut, Bytes, BytesMut}; -use std::convert::{TryFrom, TryInto}; use std::cell::Cell; +use std::convert::{TryFrom, TryInto}; use std::fmt; use std::sync::Arc; use thiserror::Error; + type Result = std::result::Result; -/// Private prevents users from creating arbitrary scalar values -/// in situations where the value needs to be validated. -/// Users can freely deref the value, but only the backend -/// may create it. + +#[doc = r" Private prevents users from creating arbitrary scalar values"] +#[doc = r" in situations where the value needs to be validated."] +#[doc = r" Users can freely deref the value, but only the backend"] +#[doc = r" may create it."] #[derive(Debug, Clone, Copy, Hash, PartialEq, Eq, PartialOrd, Ord)] pub struct Private(T); impl std::ops::Deref for Private { @@ -19,6 +21,7 @@ impl std::ops::Deref for Private { &self.0 } } + #[derive(Debug, Error)] pub enum Error { #[error("Packet parsing failed")] @@ -29,9 +32,7 @@ pub enum Error { InvalidFixedValue { expected: u64, actual: u64 }, #[error("when parsing {obj} needed length of {wanted} but got {got}")] InvalidLengthError { obj: String, wanted: usize, got: usize }, - #[error( - "array size ({array} bytes) is not a multiple of the element size ({element} bytes)" - )] + #[error("array size ({array} bytes) is not a multiple of the element size ({element} bytes)")] InvalidArraySize { array: usize, element: usize }, #[error("Due to size restrictions a struct could not be parsed.")] ImpossibleStructError, @@ -40,10 +41,12 @@ pub enum Error { #[error("expected child {expected}, got {actual}")] InvalidChildError { expected: &'static str, actual: String }, } + pub trait Packet { fn to_bytes(self) -> Bytes; fn to_vec(self) -> Vec; } + #[repr(u64)] #[derive(Debug, Clone, Copy, Hash, Eq, PartialEq)] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] @@ -75,6 +78,7 @@ impl From for u64 { (&value).into() } } + #[derive(Debug, Clone, PartialEq, Eq)] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] pub struct BarData { @@ -108,13 +112,14 @@ impl BarData { got: bytes.get().remaining(), }); } - let x = Foo::try_from(bytes.get_mut().get_u64_le()) - .map_err(|_| Error::InvalidEnumValueError { + let x = Foo::try_from(bytes.get_mut().get_u64_le()).map_err(|_| { + Error::InvalidEnumValueError { obj: "Bar".to_string(), field: "x".to_string(), value: bytes.get_mut().get_u64_le() as u64, type_: "Foo".to_string(), - })?; + } + })?; Ok(Self { x }) } fn write_to(&self, buffer: &mut BytesMut) { diff --git a/tools/pdl/tests/generated/packet_decl_64bit_scalar_array_big_endian.rs b/tools/pdl/tests/generated/packet_decl_64bit_scalar_array_big_endian.rs index d162424f3c1..b62eb41fa72 100644 --- a/tools/pdl/tests/generated/packet_decl_64bit_scalar_array_big_endian.rs +++ b/tools/pdl/tests/generated/packet_decl_64bit_scalar_array_big_endian.rs @@ -1,16 +1,18 @@ -#![rustfmt::skip] -/// @generated rust packets from test. +// @generated rust packets from test + use bytes::{Buf, BufMut, Bytes, BytesMut}; -use std::convert::{TryFrom, TryInto}; use std::cell::Cell; +use std::convert::{TryFrom, TryInto}; use std::fmt; use std::sync::Arc; use thiserror::Error; + type Result = std::result::Result; -/// Private prevents users from creating arbitrary scalar values -/// in situations where the value needs to be validated. -/// Users can freely deref the value, but only the backend -/// may create it. + +#[doc = r" Private prevents users from creating arbitrary scalar values"] +#[doc = r" in situations where the value needs to be validated."] +#[doc = r" Users can freely deref the value, but only the backend"] +#[doc = r" may create it."] #[derive(Debug, Clone, Copy, Hash, PartialEq, Eq, PartialOrd, Ord)] pub struct Private(T); impl std::ops::Deref for Private { @@ -19,6 +21,7 @@ impl std::ops::Deref for Private { &self.0 } } + #[derive(Debug, Error)] pub enum Error { #[error("Packet parsing failed")] @@ -29,9 +32,7 @@ pub enum Error { InvalidFixedValue { expected: u64, actual: u64 }, #[error("when parsing {obj} needed length of {wanted} but got {got}")] InvalidLengthError { obj: String, wanted: usize, got: usize }, - #[error( - "array size ({array} bytes) is not a multiple of the element size ({element} bytes)" - )] + #[error("array size ({array} bytes) is not a multiple of the element size ({element} bytes)")] InvalidArraySize { array: usize, element: usize }, #[error("Due to size restrictions a struct could not be parsed.")] ImpossibleStructError, @@ -40,10 +41,12 @@ pub enum Error { #[error("expected child {expected}, got {actual}")] InvalidChildError { expected: &'static str, actual: String }, } + pub trait Packet { fn to_bytes(self) -> Bytes; fn to_vec(self) -> Vec; } + #[derive(Debug, Clone, PartialEq, Eq)] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] pub struct FooData { diff --git a/tools/pdl/tests/generated/packet_decl_64bit_scalar_array_little_endian.rs b/tools/pdl/tests/generated/packet_decl_64bit_scalar_array_little_endian.rs index 5d8c77ee746..0aee553e95d 100644 --- a/tools/pdl/tests/generated/packet_decl_64bit_scalar_array_little_endian.rs +++ b/tools/pdl/tests/generated/packet_decl_64bit_scalar_array_little_endian.rs @@ -1,16 +1,18 @@ -#![rustfmt::skip] -/// @generated rust packets from test. +// @generated rust packets from test + use bytes::{Buf, BufMut, Bytes, BytesMut}; -use std::convert::{TryFrom, TryInto}; use std::cell::Cell; +use std::convert::{TryFrom, TryInto}; use std::fmt; use std::sync::Arc; use thiserror::Error; + type Result = std::result::Result; -/// Private prevents users from creating arbitrary scalar values -/// in situations where the value needs to be validated. -/// Users can freely deref the value, but only the backend -/// may create it. + +#[doc = r" Private prevents users from creating arbitrary scalar values"] +#[doc = r" in situations where the value needs to be validated."] +#[doc = r" Users can freely deref the value, but only the backend"] +#[doc = r" may create it."] #[derive(Debug, Clone, Copy, Hash, PartialEq, Eq, PartialOrd, Ord)] pub struct Private(T); impl std::ops::Deref for Private { @@ -19,6 +21,7 @@ impl std::ops::Deref for Private { &self.0 } } + #[derive(Debug, Error)] pub enum Error { #[error("Packet parsing failed")] @@ -29,9 +32,7 @@ pub enum Error { InvalidFixedValue { expected: u64, actual: u64 }, #[error("when parsing {obj} needed length of {wanted} but got {got}")] InvalidLengthError { obj: String, wanted: usize, got: usize }, - #[error( - "array size ({array} bytes) is not a multiple of the element size ({element} bytes)" - )] + #[error("array size ({array} bytes) is not a multiple of the element size ({element} bytes)")] InvalidArraySize { array: usize, element: usize }, #[error("Due to size restrictions a struct could not be parsed.")] ImpossibleStructError, @@ -40,10 +41,12 @@ pub enum Error { #[error("expected child {expected}, got {actual}")] InvalidChildError { expected: &'static str, actual: String }, } + pub trait Packet { fn to_bytes(self) -> Bytes; fn to_vec(self) -> Vec; } + #[derive(Debug, Clone, PartialEq, Eq)] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] pub struct FooData { diff --git a/tools/pdl/tests/generated/packet_decl_64bit_scalar_big_endian.rs b/tools/pdl/tests/generated/packet_decl_64bit_scalar_big_endian.rs index 176a4af46d8..bf640019c1f 100644 --- a/tools/pdl/tests/generated/packet_decl_64bit_scalar_big_endian.rs +++ b/tools/pdl/tests/generated/packet_decl_64bit_scalar_big_endian.rs @@ -1,16 +1,18 @@ -#![rustfmt::skip] -/// @generated rust packets from test. +// @generated rust packets from test + use bytes::{Buf, BufMut, Bytes, BytesMut}; -use std::convert::{TryFrom, TryInto}; use std::cell::Cell; +use std::convert::{TryFrom, TryInto}; use std::fmt; use std::sync::Arc; use thiserror::Error; + type Result = std::result::Result; -/// Private prevents users from creating arbitrary scalar values -/// in situations where the value needs to be validated. -/// Users can freely deref the value, but only the backend -/// may create it. + +#[doc = r" Private prevents users from creating arbitrary scalar values"] +#[doc = r" in situations where the value needs to be validated."] +#[doc = r" Users can freely deref the value, but only the backend"] +#[doc = r" may create it."] #[derive(Debug, Clone, Copy, Hash, PartialEq, Eq, PartialOrd, Ord)] pub struct Private(T); impl std::ops::Deref for Private { @@ -19,6 +21,7 @@ impl std::ops::Deref for Private { &self.0 } } + #[derive(Debug, Error)] pub enum Error { #[error("Packet parsing failed")] @@ -29,9 +32,7 @@ pub enum Error { InvalidFixedValue { expected: u64, actual: u64 }, #[error("when parsing {obj} needed length of {wanted} but got {got}")] InvalidLengthError { obj: String, wanted: usize, got: usize }, - #[error( - "array size ({array} bytes) is not a multiple of the element size ({element} bytes)" - )] + #[error("array size ({array} bytes) is not a multiple of the element size ({element} bytes)")] InvalidArraySize { array: usize, element: usize }, #[error("Due to size restrictions a struct could not be parsed.")] ImpossibleStructError, @@ -40,10 +41,12 @@ pub enum Error { #[error("expected child {expected}, got {actual}")] InvalidChildError { expected: &'static str, actual: String }, } + pub trait Packet { fn to_bytes(self) -> Bytes; fn to_vec(self) -> Vec; } + #[derive(Debug, Clone, PartialEq, Eq)] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] pub struct FooData { diff --git a/tools/pdl/tests/generated/packet_decl_64bit_scalar_little_endian.rs b/tools/pdl/tests/generated/packet_decl_64bit_scalar_little_endian.rs index 3f26f6c3f69..63d838a41fe 100644 --- a/tools/pdl/tests/generated/packet_decl_64bit_scalar_little_endian.rs +++ b/tools/pdl/tests/generated/packet_decl_64bit_scalar_little_endian.rs @@ -1,16 +1,18 @@ -#![rustfmt::skip] -/// @generated rust packets from test. +// @generated rust packets from test + use bytes::{Buf, BufMut, Bytes, BytesMut}; -use std::convert::{TryFrom, TryInto}; use std::cell::Cell; +use std::convert::{TryFrom, TryInto}; use std::fmt; use std::sync::Arc; use thiserror::Error; + type Result = std::result::Result; -/// Private prevents users from creating arbitrary scalar values -/// in situations where the value needs to be validated. -/// Users can freely deref the value, but only the backend -/// may create it. + +#[doc = r" Private prevents users from creating arbitrary scalar values"] +#[doc = r" in situations where the value needs to be validated."] +#[doc = r" Users can freely deref the value, but only the backend"] +#[doc = r" may create it."] #[derive(Debug, Clone, Copy, Hash, PartialEq, Eq, PartialOrd, Ord)] pub struct Private(T); impl std::ops::Deref for Private { @@ -19,6 +21,7 @@ impl std::ops::Deref for Private { &self.0 } } + #[derive(Debug, Error)] pub enum Error { #[error("Packet parsing failed")] @@ -29,9 +32,7 @@ pub enum Error { InvalidFixedValue { expected: u64, actual: u64 }, #[error("when parsing {obj} needed length of {wanted} but got {got}")] InvalidLengthError { obj: String, wanted: usize, got: usize }, - #[error( - "array size ({array} bytes) is not a multiple of the element size ({element} bytes)" - )] + #[error("array size ({array} bytes) is not a multiple of the element size ({element} bytes)")] InvalidArraySize { array: usize, element: usize }, #[error("Due to size restrictions a struct could not be parsed.")] ImpossibleStructError, @@ -40,10 +41,12 @@ pub enum Error { #[error("expected child {expected}, got {actual}")] InvalidChildError { expected: &'static str, actual: String }, } + pub trait Packet { fn to_bytes(self) -> Bytes; fn to_vec(self) -> Vec; } + #[derive(Debug, Clone, PartialEq, Eq)] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] pub struct FooData { diff --git a/tools/pdl/tests/generated/packet_decl_8bit_enum_array_big_endian.rs b/tools/pdl/tests/generated/packet_decl_8bit_enum_array_big_endian.rs index ef47d85b1f1..bf243090fbe 100644 --- a/tools/pdl/tests/generated/packet_decl_8bit_enum_array_big_endian.rs +++ b/tools/pdl/tests/generated/packet_decl_8bit_enum_array_big_endian.rs @@ -1,16 +1,18 @@ -#![rustfmt::skip] -/// @generated rust packets from test. +// @generated rust packets from test + use bytes::{Buf, BufMut, Bytes, BytesMut}; -use std::convert::{TryFrom, TryInto}; use std::cell::Cell; +use std::convert::{TryFrom, TryInto}; use std::fmt; use std::sync::Arc; use thiserror::Error; + type Result = std::result::Result; -/// Private prevents users from creating arbitrary scalar values -/// in situations where the value needs to be validated. -/// Users can freely deref the value, but only the backend -/// may create it. + +#[doc = r" Private prevents users from creating arbitrary scalar values"] +#[doc = r" in situations where the value needs to be validated."] +#[doc = r" Users can freely deref the value, but only the backend"] +#[doc = r" may create it."] #[derive(Debug, Clone, Copy, Hash, PartialEq, Eq, PartialOrd, Ord)] pub struct Private(T); impl std::ops::Deref for Private { @@ -19,6 +21,7 @@ impl std::ops::Deref for Private { &self.0 } } + #[derive(Debug, Error)] pub enum Error { #[error("Packet parsing failed")] @@ -29,9 +32,7 @@ pub enum Error { InvalidFixedValue { expected: u64, actual: u64 }, #[error("when parsing {obj} needed length of {wanted} but got {got}")] InvalidLengthError { obj: String, wanted: usize, got: usize }, - #[error( - "array size ({array} bytes) is not a multiple of the element size ({element} bytes)" - )] + #[error("array size ({array} bytes) is not a multiple of the element size ({element} bytes)")] InvalidArraySize { array: usize, element: usize }, #[error("Due to size restrictions a struct could not be parsed.")] ImpossibleStructError, @@ -40,10 +41,12 @@ pub enum Error { #[error("expected child {expected}, got {actual}")] InvalidChildError { expected: &'static str, actual: String }, } + pub trait Packet { fn to_bytes(self) -> Bytes; fn to_vec(self) -> Vec; } + #[repr(u64)] #[derive(Debug, Clone, Copy, Hash, Eq, PartialEq)] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] @@ -105,6 +108,7 @@ impl From for u64 { u8::from(value) as Self } } + #[derive(Debug, Clone, PartialEq, Eq)] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] pub struct BarData { @@ -140,13 +144,12 @@ impl BarData { } let x = (0..3) .map(|_| { - Foo::try_from(bytes.get_mut().get_u8()) - .map_err(|_| Error::InvalidEnumValueError { - obj: "Bar".to_string(), - field: String::new(), - value: 0, - type_: "Foo".to_string(), - }) + Foo::try_from(bytes.get_mut().get_u8()).map_err(|_| Error::InvalidEnumValueError { + obj: "Bar".to_string(), + field: String::new(), + value: 0, + type_: "Foo".to_string(), + }) }) .collect::>>()? .try_into() diff --git a/tools/pdl/tests/generated/packet_decl_8bit_enum_array_little_endian.rs b/tools/pdl/tests/generated/packet_decl_8bit_enum_array_little_endian.rs index ef47d85b1f1..bf243090fbe 100644 --- a/tools/pdl/tests/generated/packet_decl_8bit_enum_array_little_endian.rs +++ b/tools/pdl/tests/generated/packet_decl_8bit_enum_array_little_endian.rs @@ -1,16 +1,18 @@ -#![rustfmt::skip] -/// @generated rust packets from test. +// @generated rust packets from test + use bytes::{Buf, BufMut, Bytes, BytesMut}; -use std::convert::{TryFrom, TryInto}; use std::cell::Cell; +use std::convert::{TryFrom, TryInto}; use std::fmt; use std::sync::Arc; use thiserror::Error; + type Result = std::result::Result; -/// Private prevents users from creating arbitrary scalar values -/// in situations where the value needs to be validated. -/// Users can freely deref the value, but only the backend -/// may create it. + +#[doc = r" Private prevents users from creating arbitrary scalar values"] +#[doc = r" in situations where the value needs to be validated."] +#[doc = r" Users can freely deref the value, but only the backend"] +#[doc = r" may create it."] #[derive(Debug, Clone, Copy, Hash, PartialEq, Eq, PartialOrd, Ord)] pub struct Private(T); impl std::ops::Deref for Private { @@ -19,6 +21,7 @@ impl std::ops::Deref for Private { &self.0 } } + #[derive(Debug, Error)] pub enum Error { #[error("Packet parsing failed")] @@ -29,9 +32,7 @@ pub enum Error { InvalidFixedValue { expected: u64, actual: u64 }, #[error("when parsing {obj} needed length of {wanted} but got {got}")] InvalidLengthError { obj: String, wanted: usize, got: usize }, - #[error( - "array size ({array} bytes) is not a multiple of the element size ({element} bytes)" - )] + #[error("array size ({array} bytes) is not a multiple of the element size ({element} bytes)")] InvalidArraySize { array: usize, element: usize }, #[error("Due to size restrictions a struct could not be parsed.")] ImpossibleStructError, @@ -40,10 +41,12 @@ pub enum Error { #[error("expected child {expected}, got {actual}")] InvalidChildError { expected: &'static str, actual: String }, } + pub trait Packet { fn to_bytes(self) -> Bytes; fn to_vec(self) -> Vec; } + #[repr(u64)] #[derive(Debug, Clone, Copy, Hash, Eq, PartialEq)] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] @@ -105,6 +108,7 @@ impl From for u64 { u8::from(value) as Self } } + #[derive(Debug, Clone, PartialEq, Eq)] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] pub struct BarData { @@ -140,13 +144,12 @@ impl BarData { } let x = (0..3) .map(|_| { - Foo::try_from(bytes.get_mut().get_u8()) - .map_err(|_| Error::InvalidEnumValueError { - obj: "Bar".to_string(), - field: String::new(), - value: 0, - type_: "Foo".to_string(), - }) + Foo::try_from(bytes.get_mut().get_u8()).map_err(|_| Error::InvalidEnumValueError { + obj: "Bar".to_string(), + field: String::new(), + value: 0, + type_: "Foo".to_string(), + }) }) .collect::>>()? .try_into() diff --git a/tools/pdl/tests/generated/packet_decl_8bit_enum_big_endian.rs b/tools/pdl/tests/generated/packet_decl_8bit_enum_big_endian.rs index b3c497967f6..60976c9607f 100644 --- a/tools/pdl/tests/generated/packet_decl_8bit_enum_big_endian.rs +++ b/tools/pdl/tests/generated/packet_decl_8bit_enum_big_endian.rs @@ -1,16 +1,18 @@ -#![rustfmt::skip] -/// @generated rust packets from test. +// @generated rust packets from test + use bytes::{Buf, BufMut, Bytes, BytesMut}; -use std::convert::{TryFrom, TryInto}; use std::cell::Cell; +use std::convert::{TryFrom, TryInto}; use std::fmt; use std::sync::Arc; use thiserror::Error; + type Result = std::result::Result; -/// Private prevents users from creating arbitrary scalar values -/// in situations where the value needs to be validated. -/// Users can freely deref the value, but only the backend -/// may create it. + +#[doc = r" Private prevents users from creating arbitrary scalar values"] +#[doc = r" in situations where the value needs to be validated."] +#[doc = r" Users can freely deref the value, but only the backend"] +#[doc = r" may create it."] #[derive(Debug, Clone, Copy, Hash, PartialEq, Eq, PartialOrd, Ord)] pub struct Private(T); impl std::ops::Deref for Private { @@ -19,6 +21,7 @@ impl std::ops::Deref for Private { &self.0 } } + #[derive(Debug, Error)] pub enum Error { #[error("Packet parsing failed")] @@ -29,9 +32,7 @@ pub enum Error { InvalidFixedValue { expected: u64, actual: u64 }, #[error("when parsing {obj} needed length of {wanted} but got {got}")] InvalidLengthError { obj: String, wanted: usize, got: usize }, - #[error( - "array size ({array} bytes) is not a multiple of the element size ({element} bytes)" - )] + #[error("array size ({array} bytes) is not a multiple of the element size ({element} bytes)")] InvalidArraySize { array: usize, element: usize }, #[error("Due to size restrictions a struct could not be parsed.")] ImpossibleStructError, @@ -40,10 +41,12 @@ pub enum Error { #[error("expected child {expected}, got {actual}")] InvalidChildError { expected: &'static str, actual: String }, } + pub trait Packet { fn to_bytes(self) -> Bytes; fn to_vec(self) -> Vec; } + #[repr(u64)] #[derive(Debug, Clone, Copy, Hash, Eq, PartialEq)] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] @@ -105,6 +108,7 @@ impl From for u64 { u8::from(value) as Self } } + #[derive(Debug, Clone, PartialEq, Eq)] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] pub struct BarData { @@ -138,8 +142,8 @@ impl BarData { got: bytes.get().remaining(), }); } - let x = Foo::try_from(bytes.get_mut().get_u8()) - .map_err(|_| Error::InvalidEnumValueError { + let x = + Foo::try_from(bytes.get_mut().get_u8()).map_err(|_| Error::InvalidEnumValueError { obj: "Bar".to_string(), field: "x".to_string(), value: bytes.get_mut().get_u8() as u64, diff --git a/tools/pdl/tests/generated/packet_decl_8bit_enum_little_endian.rs b/tools/pdl/tests/generated/packet_decl_8bit_enum_little_endian.rs index b3c497967f6..60976c9607f 100644 --- a/tools/pdl/tests/generated/packet_decl_8bit_enum_little_endian.rs +++ b/tools/pdl/tests/generated/packet_decl_8bit_enum_little_endian.rs @@ -1,16 +1,18 @@ -#![rustfmt::skip] -/// @generated rust packets from test. +// @generated rust packets from test + use bytes::{Buf, BufMut, Bytes, BytesMut}; -use std::convert::{TryFrom, TryInto}; use std::cell::Cell; +use std::convert::{TryFrom, TryInto}; use std::fmt; use std::sync::Arc; use thiserror::Error; + type Result = std::result::Result; -/// Private prevents users from creating arbitrary scalar values -/// in situations where the value needs to be validated. -/// Users can freely deref the value, but only the backend -/// may create it. + +#[doc = r" Private prevents users from creating arbitrary scalar values"] +#[doc = r" in situations where the value needs to be validated."] +#[doc = r" Users can freely deref the value, but only the backend"] +#[doc = r" may create it."] #[derive(Debug, Clone, Copy, Hash, PartialEq, Eq, PartialOrd, Ord)] pub struct Private(T); impl std::ops::Deref for Private { @@ -19,6 +21,7 @@ impl std::ops::Deref for Private { &self.0 } } + #[derive(Debug, Error)] pub enum Error { #[error("Packet parsing failed")] @@ -29,9 +32,7 @@ pub enum Error { InvalidFixedValue { expected: u64, actual: u64 }, #[error("when parsing {obj} needed length of {wanted} but got {got}")] InvalidLengthError { obj: String, wanted: usize, got: usize }, - #[error( - "array size ({array} bytes) is not a multiple of the element size ({element} bytes)" - )] + #[error("array size ({array} bytes) is not a multiple of the element size ({element} bytes)")] InvalidArraySize { array: usize, element: usize }, #[error("Due to size restrictions a struct could not be parsed.")] ImpossibleStructError, @@ -40,10 +41,12 @@ pub enum Error { #[error("expected child {expected}, got {actual}")] InvalidChildError { expected: &'static str, actual: String }, } + pub trait Packet { fn to_bytes(self) -> Bytes; fn to_vec(self) -> Vec; } + #[repr(u64)] #[derive(Debug, Clone, Copy, Hash, Eq, PartialEq)] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] @@ -105,6 +108,7 @@ impl From for u64 { u8::from(value) as Self } } + #[derive(Debug, Clone, PartialEq, Eq)] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] pub struct BarData { @@ -138,8 +142,8 @@ impl BarData { got: bytes.get().remaining(), }); } - let x = Foo::try_from(bytes.get_mut().get_u8()) - .map_err(|_| Error::InvalidEnumValueError { + let x = + Foo::try_from(bytes.get_mut().get_u8()).map_err(|_| Error::InvalidEnumValueError { obj: "Bar".to_string(), field: "x".to_string(), value: bytes.get_mut().get_u8() as u64, diff --git a/tools/pdl/tests/generated/packet_decl_8bit_scalar_array_big_endian.rs b/tools/pdl/tests/generated/packet_decl_8bit_scalar_array_big_endian.rs index a1915a28648..8a0c287cc12 100644 --- a/tools/pdl/tests/generated/packet_decl_8bit_scalar_array_big_endian.rs +++ b/tools/pdl/tests/generated/packet_decl_8bit_scalar_array_big_endian.rs @@ -1,16 +1,18 @@ -#![rustfmt::skip] -/// @generated rust packets from test. +// @generated rust packets from test + use bytes::{Buf, BufMut, Bytes, BytesMut}; -use std::convert::{TryFrom, TryInto}; use std::cell::Cell; +use std::convert::{TryFrom, TryInto}; use std::fmt; use std::sync::Arc; use thiserror::Error; + type Result = std::result::Result; -/// Private prevents users from creating arbitrary scalar values -/// in situations where the value needs to be validated. -/// Users can freely deref the value, but only the backend -/// may create it. + +#[doc = r" Private prevents users from creating arbitrary scalar values"] +#[doc = r" in situations where the value needs to be validated."] +#[doc = r" Users can freely deref the value, but only the backend"] +#[doc = r" may create it."] #[derive(Debug, Clone, Copy, Hash, PartialEq, Eq, PartialOrd, Ord)] pub struct Private(T); impl std::ops::Deref for Private { @@ -19,6 +21,7 @@ impl std::ops::Deref for Private { &self.0 } } + #[derive(Debug, Error)] pub enum Error { #[error("Packet parsing failed")] @@ -29,9 +32,7 @@ pub enum Error { InvalidFixedValue { expected: u64, actual: u64 }, #[error("when parsing {obj} needed length of {wanted} but got {got}")] InvalidLengthError { obj: String, wanted: usize, got: usize }, - #[error( - "array size ({array} bytes) is not a multiple of the element size ({element} bytes)" - )] + #[error("array size ({array} bytes) is not a multiple of the element size ({element} bytes)")] InvalidArraySize { array: usize, element: usize }, #[error("Due to size restrictions a struct could not be parsed.")] ImpossibleStructError, @@ -40,10 +41,12 @@ pub enum Error { #[error("expected child {expected}, got {actual}")] InvalidChildError { expected: &'static str, actual: String }, } + pub trait Packet { fn to_bytes(self) -> Bytes; fn to_vec(self) -> Vec; } + #[derive(Debug, Clone, PartialEq, Eq)] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] pub struct FooData { diff --git a/tools/pdl/tests/generated/packet_decl_8bit_scalar_array_little_endian.rs b/tools/pdl/tests/generated/packet_decl_8bit_scalar_array_little_endian.rs index a1915a28648..8a0c287cc12 100644 --- a/tools/pdl/tests/generated/packet_decl_8bit_scalar_array_little_endian.rs +++ b/tools/pdl/tests/generated/packet_decl_8bit_scalar_array_little_endian.rs @@ -1,16 +1,18 @@ -#![rustfmt::skip] -/// @generated rust packets from test. +// @generated rust packets from test + use bytes::{Buf, BufMut, Bytes, BytesMut}; -use std::convert::{TryFrom, TryInto}; use std::cell::Cell; +use std::convert::{TryFrom, TryInto}; use std::fmt; use std::sync::Arc; use thiserror::Error; + type Result = std::result::Result; -/// Private prevents users from creating arbitrary scalar values -/// in situations where the value needs to be validated. -/// Users can freely deref the value, but only the backend -/// may create it. + +#[doc = r" Private prevents users from creating arbitrary scalar values"] +#[doc = r" in situations where the value needs to be validated."] +#[doc = r" Users can freely deref the value, but only the backend"] +#[doc = r" may create it."] #[derive(Debug, Clone, Copy, Hash, PartialEq, Eq, PartialOrd, Ord)] pub struct Private(T); impl std::ops::Deref for Private { @@ -19,6 +21,7 @@ impl std::ops::Deref for Private { &self.0 } } + #[derive(Debug, Error)] pub enum Error { #[error("Packet parsing failed")] @@ -29,9 +32,7 @@ pub enum Error { InvalidFixedValue { expected: u64, actual: u64 }, #[error("when parsing {obj} needed length of {wanted} but got {got}")] InvalidLengthError { obj: String, wanted: usize, got: usize }, - #[error( - "array size ({array} bytes) is not a multiple of the element size ({element} bytes)" - )] + #[error("array size ({array} bytes) is not a multiple of the element size ({element} bytes)")] InvalidArraySize { array: usize, element: usize }, #[error("Due to size restrictions a struct could not be parsed.")] ImpossibleStructError, @@ -40,10 +41,12 @@ pub enum Error { #[error("expected child {expected}, got {actual}")] InvalidChildError { expected: &'static str, actual: String }, } + pub trait Packet { fn to_bytes(self) -> Bytes; fn to_vec(self) -> Vec; } + #[derive(Debug, Clone, PartialEq, Eq)] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] pub struct FooData { diff --git a/tools/pdl/tests/generated/packet_decl_8bit_scalar_big_endian.rs b/tools/pdl/tests/generated/packet_decl_8bit_scalar_big_endian.rs index ae3515a5114..103eeb32ddf 100644 --- a/tools/pdl/tests/generated/packet_decl_8bit_scalar_big_endian.rs +++ b/tools/pdl/tests/generated/packet_decl_8bit_scalar_big_endian.rs @@ -1,16 +1,18 @@ -#![rustfmt::skip] -/// @generated rust packets from test. +// @generated rust packets from test + use bytes::{Buf, BufMut, Bytes, BytesMut}; -use std::convert::{TryFrom, TryInto}; use std::cell::Cell; +use std::convert::{TryFrom, TryInto}; use std::fmt; use std::sync::Arc; use thiserror::Error; + type Result = std::result::Result; -/// Private prevents users from creating arbitrary scalar values -/// in situations where the value needs to be validated. -/// Users can freely deref the value, but only the backend -/// may create it. + +#[doc = r" Private prevents users from creating arbitrary scalar values"] +#[doc = r" in situations where the value needs to be validated."] +#[doc = r" Users can freely deref the value, but only the backend"] +#[doc = r" may create it."] #[derive(Debug, Clone, Copy, Hash, PartialEq, Eq, PartialOrd, Ord)] pub struct Private(T); impl std::ops::Deref for Private { @@ -19,6 +21,7 @@ impl std::ops::Deref for Private { &self.0 } } + #[derive(Debug, Error)] pub enum Error { #[error("Packet parsing failed")] @@ -29,9 +32,7 @@ pub enum Error { InvalidFixedValue { expected: u64, actual: u64 }, #[error("when parsing {obj} needed length of {wanted} but got {got}")] InvalidLengthError { obj: String, wanted: usize, got: usize }, - #[error( - "array size ({array} bytes) is not a multiple of the element size ({element} bytes)" - )] + #[error("array size ({array} bytes) is not a multiple of the element size ({element} bytes)")] InvalidArraySize { array: usize, element: usize }, #[error("Due to size restrictions a struct could not be parsed.")] ImpossibleStructError, @@ -40,10 +41,12 @@ pub enum Error { #[error("expected child {expected}, got {actual}")] InvalidChildError { expected: &'static str, actual: String }, } + pub trait Packet { fn to_bytes(self) -> Bytes; fn to_vec(self) -> Vec; } + #[derive(Debug, Clone, PartialEq, Eq)] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] pub struct FooData { diff --git a/tools/pdl/tests/generated/packet_decl_8bit_scalar_little_endian.rs b/tools/pdl/tests/generated/packet_decl_8bit_scalar_little_endian.rs index ae3515a5114..103eeb32ddf 100644 --- a/tools/pdl/tests/generated/packet_decl_8bit_scalar_little_endian.rs +++ b/tools/pdl/tests/generated/packet_decl_8bit_scalar_little_endian.rs @@ -1,16 +1,18 @@ -#![rustfmt::skip] -/// @generated rust packets from test. +// @generated rust packets from test + use bytes::{Buf, BufMut, Bytes, BytesMut}; -use std::convert::{TryFrom, TryInto}; use std::cell::Cell; +use std::convert::{TryFrom, TryInto}; use std::fmt; use std::sync::Arc; use thiserror::Error; + type Result = std::result::Result; -/// Private prevents users from creating arbitrary scalar values -/// in situations where the value needs to be validated. -/// Users can freely deref the value, but only the backend -/// may create it. + +#[doc = r" Private prevents users from creating arbitrary scalar values"] +#[doc = r" in situations where the value needs to be validated."] +#[doc = r" Users can freely deref the value, but only the backend"] +#[doc = r" may create it."] #[derive(Debug, Clone, Copy, Hash, PartialEq, Eq, PartialOrd, Ord)] pub struct Private(T); impl std::ops::Deref for Private { @@ -19,6 +21,7 @@ impl std::ops::Deref for Private { &self.0 } } + #[derive(Debug, Error)] pub enum Error { #[error("Packet parsing failed")] @@ -29,9 +32,7 @@ pub enum Error { InvalidFixedValue { expected: u64, actual: u64 }, #[error("when parsing {obj} needed length of {wanted} but got {got}")] InvalidLengthError { obj: String, wanted: usize, got: usize }, - #[error( - "array size ({array} bytes) is not a multiple of the element size ({element} bytes)" - )] + #[error("array size ({array} bytes) is not a multiple of the element size ({element} bytes)")] InvalidArraySize { array: usize, element: usize }, #[error("Due to size restrictions a struct could not be parsed.")] ImpossibleStructError, @@ -40,10 +41,12 @@ pub enum Error { #[error("expected child {expected}, got {actual}")] InvalidChildError { expected: &'static str, actual: String }, } + pub trait Packet { fn to_bytes(self) -> Bytes; fn to_vec(self) -> Vec; } + #[derive(Debug, Clone, PartialEq, Eq)] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] pub struct FooData { diff --git a/tools/pdl/tests/generated/packet_decl_array_dynamic_count_big_endian.rs b/tools/pdl/tests/generated/packet_decl_array_dynamic_count_big_endian.rs index c9a5e221a8c..3628db4666f 100644 --- a/tools/pdl/tests/generated/packet_decl_array_dynamic_count_big_endian.rs +++ b/tools/pdl/tests/generated/packet_decl_array_dynamic_count_big_endian.rs @@ -1,16 +1,18 @@ -#![rustfmt::skip] -/// @generated rust packets from test. +// @generated rust packets from test + use bytes::{Buf, BufMut, Bytes, BytesMut}; -use std::convert::{TryFrom, TryInto}; use std::cell::Cell; +use std::convert::{TryFrom, TryInto}; use std::fmt; use std::sync::Arc; use thiserror::Error; + type Result = std::result::Result; -/// Private prevents users from creating arbitrary scalar values -/// in situations where the value needs to be validated. -/// Users can freely deref the value, but only the backend -/// may create it. + +#[doc = r" Private prevents users from creating arbitrary scalar values"] +#[doc = r" in situations where the value needs to be validated."] +#[doc = r" Users can freely deref the value, but only the backend"] +#[doc = r" may create it."] #[derive(Debug, Clone, Copy, Hash, PartialEq, Eq, PartialOrd, Ord)] pub struct Private(T); impl std::ops::Deref for Private { @@ -19,6 +21,7 @@ impl std::ops::Deref for Private { &self.0 } } + #[derive(Debug, Error)] pub enum Error { #[error("Packet parsing failed")] @@ -29,9 +32,7 @@ pub enum Error { InvalidFixedValue { expected: u64, actual: u64 }, #[error("when parsing {obj} needed length of {wanted} but got {got}")] InvalidLengthError { obj: String, wanted: usize, got: usize }, - #[error( - "array size ({array} bytes) is not a multiple of the element size ({element} bytes)" - )] + #[error("array size ({array} bytes) is not a multiple of the element size ({element} bytes)")] InvalidArraySize { array: usize, element: usize }, #[error("Due to size restrictions a struct could not be parsed.")] ImpossibleStructError, @@ -40,10 +41,12 @@ pub enum Error { #[error("expected child {expected}, got {actual}")] InvalidChildError { expected: &'static str, actual: String }, } + pub trait Packet { fn to_bytes(self) -> Bytes; fn to_vec(self) -> Vec; } + #[derive(Debug, Clone, PartialEq, Eq)] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] pub struct FooData { @@ -99,9 +102,7 @@ impl FooData { panic!("Invalid length for {}::{}: {} > {}", "Foo", "x", self.x.len(), 0x1f); } if self.padding > 0x7 { - panic!( - "Invalid value for {}::{}: {} > {}", "Foo", "padding", self.padding, 0x7 - ); + panic!("Invalid value for {}::{}: {} > {}", "Foo", "padding", self.padding, 0x7); } let value = self.x.len() as u8 | (self.padding << 5); buffer.put_u8(value); @@ -164,10 +165,7 @@ impl Foo { } impl FooBuilder { pub fn build(self) -> Foo { - let foo = Arc::new(FooData { - padding: self.padding, - x: self.x, - }); + let foo = Arc::new(FooData { padding: self.padding, x: self.x }); Foo::new(foo).unwrap() } } diff --git a/tools/pdl/tests/generated/packet_decl_array_dynamic_count_little_endian.rs b/tools/pdl/tests/generated/packet_decl_array_dynamic_count_little_endian.rs index 7a9f27fbf79..ef8c84955d9 100644 --- a/tools/pdl/tests/generated/packet_decl_array_dynamic_count_little_endian.rs +++ b/tools/pdl/tests/generated/packet_decl_array_dynamic_count_little_endian.rs @@ -1,16 +1,18 @@ -#![rustfmt::skip] -/// @generated rust packets from test. +// @generated rust packets from test + use bytes::{Buf, BufMut, Bytes, BytesMut}; -use std::convert::{TryFrom, TryInto}; use std::cell::Cell; +use std::convert::{TryFrom, TryInto}; use std::fmt; use std::sync::Arc; use thiserror::Error; + type Result = std::result::Result; -/// Private prevents users from creating arbitrary scalar values -/// in situations where the value needs to be validated. -/// Users can freely deref the value, but only the backend -/// may create it. + +#[doc = r" Private prevents users from creating arbitrary scalar values"] +#[doc = r" in situations where the value needs to be validated."] +#[doc = r" Users can freely deref the value, but only the backend"] +#[doc = r" may create it."] #[derive(Debug, Clone, Copy, Hash, PartialEq, Eq, PartialOrd, Ord)] pub struct Private(T); impl std::ops::Deref for Private { @@ -19,6 +21,7 @@ impl std::ops::Deref for Private { &self.0 } } + #[derive(Debug, Error)] pub enum Error { #[error("Packet parsing failed")] @@ -29,9 +32,7 @@ pub enum Error { InvalidFixedValue { expected: u64, actual: u64 }, #[error("when parsing {obj} needed length of {wanted} but got {got}")] InvalidLengthError { obj: String, wanted: usize, got: usize }, - #[error( - "array size ({array} bytes) is not a multiple of the element size ({element} bytes)" - )] + #[error("array size ({array} bytes) is not a multiple of the element size ({element} bytes)")] InvalidArraySize { array: usize, element: usize }, #[error("Due to size restrictions a struct could not be parsed.")] ImpossibleStructError, @@ -40,10 +41,12 @@ pub enum Error { #[error("expected child {expected}, got {actual}")] InvalidChildError { expected: &'static str, actual: String }, } + pub trait Packet { fn to_bytes(self) -> Bytes; fn to_vec(self) -> Vec; } + #[derive(Debug, Clone, PartialEq, Eq)] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] pub struct FooData { @@ -99,9 +102,7 @@ impl FooData { panic!("Invalid length for {}::{}: {} > {}", "Foo", "x", self.x.len(), 0x1f); } if self.padding > 0x7 { - panic!( - "Invalid value for {}::{}: {} > {}", "Foo", "padding", self.padding, 0x7 - ); + panic!("Invalid value for {}::{}: {} > {}", "Foo", "padding", self.padding, 0x7); } let value = self.x.len() as u8 | (self.padding << 5); buffer.put_u8(value); @@ -164,10 +165,7 @@ impl Foo { } impl FooBuilder { pub fn build(self) -> Foo { - let foo = Arc::new(FooData { - padding: self.padding, - x: self.x, - }); + let foo = Arc::new(FooData { padding: self.padding, x: self.x }); Foo::new(foo).unwrap() } } diff --git a/tools/pdl/tests/generated/packet_decl_array_dynamic_size_big_endian.rs b/tools/pdl/tests/generated/packet_decl_array_dynamic_size_big_endian.rs index ec487365ea7..7148196e291 100644 --- a/tools/pdl/tests/generated/packet_decl_array_dynamic_size_big_endian.rs +++ b/tools/pdl/tests/generated/packet_decl_array_dynamic_size_big_endian.rs @@ -1,16 +1,18 @@ -#![rustfmt::skip] -/// @generated rust packets from test. +// @generated rust packets from test + use bytes::{Buf, BufMut, Bytes, BytesMut}; -use std::convert::{TryFrom, TryInto}; use std::cell::Cell; +use std::convert::{TryFrom, TryInto}; use std::fmt; use std::sync::Arc; use thiserror::Error; + type Result = std::result::Result; -/// Private prevents users from creating arbitrary scalar values -/// in situations where the value needs to be validated. -/// Users can freely deref the value, but only the backend -/// may create it. + +#[doc = r" Private prevents users from creating arbitrary scalar values"] +#[doc = r" in situations where the value needs to be validated."] +#[doc = r" Users can freely deref the value, but only the backend"] +#[doc = r" may create it."] #[derive(Debug, Clone, Copy, Hash, PartialEq, Eq, PartialOrd, Ord)] pub struct Private(T); impl std::ops::Deref for Private { @@ -19,6 +21,7 @@ impl std::ops::Deref for Private { &self.0 } } + #[derive(Debug, Error)] pub enum Error { #[error("Packet parsing failed")] @@ -29,9 +32,7 @@ pub enum Error { InvalidFixedValue { expected: u64, actual: u64 }, #[error("when parsing {obj} needed length of {wanted} but got {got}")] InvalidLengthError { obj: String, wanted: usize, got: usize }, - #[error( - "array size ({array} bytes) is not a multiple of the element size ({element} bytes)" - )] + #[error("array size ({array} bytes) is not a multiple of the element size ({element} bytes)")] InvalidArraySize { array: usize, element: usize }, #[error("Due to size restrictions a struct could not be parsed.")] ImpossibleStructError, @@ -40,10 +41,12 @@ pub enum Error { #[error("expected child {expected}, got {actual}")] InvalidChildError { expected: &'static str, actual: String }, } + pub trait Packet { fn to_bytes(self) -> Bytes; fn to_vec(self) -> Vec; } + #[derive(Debug, Clone, PartialEq, Eq)] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] pub struct FooData { @@ -90,10 +93,7 @@ impl FooData { }); } if x_size % 3 != 0 { - return Err(Error::InvalidArraySize { - array: x_size, - element: 3, - }); + return Err(Error::InvalidArraySize { array: x_size, element: 3 }); } let x_count = x_size / 3; let mut x = Vec::with_capacity(x_count); @@ -104,15 +104,10 @@ impl FooData { } fn write_to(&self, buffer: &mut BytesMut) { if (self.x.len() * 3) > 0x1f { - panic!( - "Invalid length for {}::{}: {} > {}", "Foo", "x", (self.x.len() * 3), - 0x1f - ); + panic!("Invalid length for {}::{}: {} > {}", "Foo", "x", (self.x.len() * 3), 0x1f); } if self.padding > 0x7 { - panic!( - "Invalid value for {}::{}: {} > {}", "Foo", "padding", self.padding, 0x7 - ); + panic!("Invalid value for {}::{}: {} > {}", "Foo", "padding", self.padding, 0x7); } let value = (self.x.len() * 3) as u8 | (self.padding << 5); buffer.put_u8(value); @@ -175,10 +170,7 @@ impl Foo { } impl FooBuilder { pub fn build(self) -> Foo { - let foo = Arc::new(FooData { - padding: self.padding, - x: self.x, - }); + let foo = Arc::new(FooData { padding: self.padding, x: self.x }); Foo::new(foo).unwrap() } } diff --git a/tools/pdl/tests/generated/packet_decl_array_dynamic_size_little_endian.rs b/tools/pdl/tests/generated/packet_decl_array_dynamic_size_little_endian.rs index cec18ee62c4..6645cf2f411 100644 --- a/tools/pdl/tests/generated/packet_decl_array_dynamic_size_little_endian.rs +++ b/tools/pdl/tests/generated/packet_decl_array_dynamic_size_little_endian.rs @@ -1,16 +1,18 @@ -#![rustfmt::skip] -/// @generated rust packets from test. +// @generated rust packets from test + use bytes::{Buf, BufMut, Bytes, BytesMut}; -use std::convert::{TryFrom, TryInto}; use std::cell::Cell; +use std::convert::{TryFrom, TryInto}; use std::fmt; use std::sync::Arc; use thiserror::Error; + type Result = std::result::Result; -/// Private prevents users from creating arbitrary scalar values -/// in situations where the value needs to be validated. -/// Users can freely deref the value, but only the backend -/// may create it. + +#[doc = r" Private prevents users from creating arbitrary scalar values"] +#[doc = r" in situations where the value needs to be validated."] +#[doc = r" Users can freely deref the value, but only the backend"] +#[doc = r" may create it."] #[derive(Debug, Clone, Copy, Hash, PartialEq, Eq, PartialOrd, Ord)] pub struct Private(T); impl std::ops::Deref for Private { @@ -19,6 +21,7 @@ impl std::ops::Deref for Private { &self.0 } } + #[derive(Debug, Error)] pub enum Error { #[error("Packet parsing failed")] @@ -29,9 +32,7 @@ pub enum Error { InvalidFixedValue { expected: u64, actual: u64 }, #[error("when parsing {obj} needed length of {wanted} but got {got}")] InvalidLengthError { obj: String, wanted: usize, got: usize }, - #[error( - "array size ({array} bytes) is not a multiple of the element size ({element} bytes)" - )] + #[error("array size ({array} bytes) is not a multiple of the element size ({element} bytes)")] InvalidArraySize { array: usize, element: usize }, #[error("Due to size restrictions a struct could not be parsed.")] ImpossibleStructError, @@ -40,10 +41,12 @@ pub enum Error { #[error("expected child {expected}, got {actual}")] InvalidChildError { expected: &'static str, actual: String }, } + pub trait Packet { fn to_bytes(self) -> Bytes; fn to_vec(self) -> Vec; } + #[derive(Debug, Clone, PartialEq, Eq)] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] pub struct FooData { @@ -90,10 +93,7 @@ impl FooData { }); } if x_size % 3 != 0 { - return Err(Error::InvalidArraySize { - array: x_size, - element: 3, - }); + return Err(Error::InvalidArraySize { array: x_size, element: 3 }); } let x_count = x_size / 3; let mut x = Vec::with_capacity(x_count); @@ -104,15 +104,10 @@ impl FooData { } fn write_to(&self, buffer: &mut BytesMut) { if (self.x.len() * 3) > 0x1f { - panic!( - "Invalid length for {}::{}: {} > {}", "Foo", "x", (self.x.len() * 3), - 0x1f - ); + panic!("Invalid length for {}::{}: {} > {}", "Foo", "x", (self.x.len() * 3), 0x1f); } if self.padding > 0x7 { - panic!( - "Invalid value for {}::{}: {} > {}", "Foo", "padding", self.padding, 0x7 - ); + panic!("Invalid value for {}::{}: {} > {}", "Foo", "padding", self.padding, 0x7); } let value = (self.x.len() * 3) as u8 | (self.padding << 5); buffer.put_u8(value); @@ -175,10 +170,7 @@ impl Foo { } impl FooBuilder { pub fn build(self) -> Foo { - let foo = Arc::new(FooData { - padding: self.padding, - x: self.x, - }); + let foo = Arc::new(FooData { padding: self.padding, x: self.x }); Foo::new(foo).unwrap() } } diff --git a/tools/pdl/tests/generated/packet_decl_array_unknown_element_width_dynamic_count_big_endian.rs b/tools/pdl/tests/generated/packet_decl_array_unknown_element_width_dynamic_count_big_endian.rs index b57eb296653..e1a54c7f82c 100644 --- a/tools/pdl/tests/generated/packet_decl_array_unknown_element_width_dynamic_count_big_endian.rs +++ b/tools/pdl/tests/generated/packet_decl_array_unknown_element_width_dynamic_count_big_endian.rs @@ -1,16 +1,18 @@ -#![rustfmt::skip] -/// @generated rust packets from test. +// @generated rust packets from test + use bytes::{Buf, BufMut, Bytes, BytesMut}; -use std::convert::{TryFrom, TryInto}; use std::cell::Cell; +use std::convert::{TryFrom, TryInto}; use std::fmt; use std::sync::Arc; use thiserror::Error; + type Result = std::result::Result; -/// Private prevents users from creating arbitrary scalar values -/// in situations where the value needs to be validated. -/// Users can freely deref the value, but only the backend -/// may create it. + +#[doc = r" Private prevents users from creating arbitrary scalar values"] +#[doc = r" in situations where the value needs to be validated."] +#[doc = r" Users can freely deref the value, but only the backend"] +#[doc = r" may create it."] #[derive(Debug, Clone, Copy, Hash, PartialEq, Eq, PartialOrd, Ord)] pub struct Private(T); impl std::ops::Deref for Private { @@ -19,6 +21,7 @@ impl std::ops::Deref for Private { &self.0 } } + #[derive(Debug, Error)] pub enum Error { #[error("Packet parsing failed")] @@ -29,9 +32,7 @@ pub enum Error { InvalidFixedValue { expected: u64, actual: u64 }, #[error("when parsing {obj} needed length of {wanted} but got {got}")] InvalidLengthError { obj: String, wanted: usize, got: usize }, - #[error( - "array size ({array} bytes) is not a multiple of the element size ({element} bytes)" - )] + #[error("array size ({array} bytes) is not a multiple of the element size ({element} bytes)")] InvalidArraySize { array: usize, element: usize }, #[error("Due to size restrictions a struct could not be parsed.")] ImpossibleStructError, @@ -40,10 +41,12 @@ pub enum Error { #[error("expected child {expected}, got {actual}")] InvalidChildError { expected: &'static str, actual: String }, } + pub trait Packet { fn to_bytes(self) -> Bytes; fn to_vec(self) -> Vec; } + #[derive(Debug, Clone, PartialEq, Eq)] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] pub struct Foo { @@ -82,7 +85,10 @@ impl Foo { fn write_to(&self, buffer: &mut BytesMut) { if self.a.len() > 0xff_ffff_ffff_usize { panic!( - "Invalid length for {}::{}: {} > {}", "Foo", "a", self.a.len(), + "Invalid length for {}::{}: {} > {}", + "Foo", + "a", + self.a.len(), 0xff_ffff_ffff_usize ); } @@ -98,6 +104,7 @@ impl Foo { 5 + self.a.len() * 2 } } + #[derive(Debug, Clone, PartialEq, Eq)] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] pub struct BarData { @@ -132,15 +139,16 @@ impl BarData { }); } let x_count = bytes.get_mut().get_uint(5) as usize; - let x = (0..x_count) - .map(|_| Foo::parse_inner(bytes)) - .collect::>>()?; + let x = (0..x_count).map(|_| Foo::parse_inner(bytes)).collect::>>()?; Ok(Self { x }) } fn write_to(&self, buffer: &mut BytesMut) { if self.x.len() > 0xff_ffff_ffff_usize { panic!( - "Invalid length for {}::{}: {} > {}", "Bar", "x", self.x.len(), + "Invalid length for {}::{}: {} > {}", + "Bar", + "x", + self.x.len(), 0xff_ffff_ffff_usize ); } diff --git a/tools/pdl/tests/generated/packet_decl_array_unknown_element_width_dynamic_count_little_endian.rs b/tools/pdl/tests/generated/packet_decl_array_unknown_element_width_dynamic_count_little_endian.rs index 3fb7990f4d6..4a1e47c6b9c 100644 --- a/tools/pdl/tests/generated/packet_decl_array_unknown_element_width_dynamic_count_little_endian.rs +++ b/tools/pdl/tests/generated/packet_decl_array_unknown_element_width_dynamic_count_little_endian.rs @@ -1,16 +1,18 @@ -#![rustfmt::skip] -/// @generated rust packets from test. +// @generated rust packets from test + use bytes::{Buf, BufMut, Bytes, BytesMut}; -use std::convert::{TryFrom, TryInto}; use std::cell::Cell; +use std::convert::{TryFrom, TryInto}; use std::fmt; use std::sync::Arc; use thiserror::Error; + type Result = std::result::Result; -/// Private prevents users from creating arbitrary scalar values -/// in situations where the value needs to be validated. -/// Users can freely deref the value, but only the backend -/// may create it. + +#[doc = r" Private prevents users from creating arbitrary scalar values"] +#[doc = r" in situations where the value needs to be validated."] +#[doc = r" Users can freely deref the value, but only the backend"] +#[doc = r" may create it."] #[derive(Debug, Clone, Copy, Hash, PartialEq, Eq, PartialOrd, Ord)] pub struct Private(T); impl std::ops::Deref for Private { @@ -19,6 +21,7 @@ impl std::ops::Deref for Private { &self.0 } } + #[derive(Debug, Error)] pub enum Error { #[error("Packet parsing failed")] @@ -29,9 +32,7 @@ pub enum Error { InvalidFixedValue { expected: u64, actual: u64 }, #[error("when parsing {obj} needed length of {wanted} but got {got}")] InvalidLengthError { obj: String, wanted: usize, got: usize }, - #[error( - "array size ({array} bytes) is not a multiple of the element size ({element} bytes)" - )] + #[error("array size ({array} bytes) is not a multiple of the element size ({element} bytes)")] InvalidArraySize { array: usize, element: usize }, #[error("Due to size restrictions a struct could not be parsed.")] ImpossibleStructError, @@ -40,10 +41,12 @@ pub enum Error { #[error("expected child {expected}, got {actual}")] InvalidChildError { expected: &'static str, actual: String }, } + pub trait Packet { fn to_bytes(self) -> Bytes; fn to_vec(self) -> Vec; } + #[derive(Debug, Clone, PartialEq, Eq)] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] pub struct Foo { @@ -82,7 +85,10 @@ impl Foo { fn write_to(&self, buffer: &mut BytesMut) { if self.a.len() > 0xff_ffff_ffff_usize { panic!( - "Invalid length for {}::{}: {} > {}", "Foo", "a", self.a.len(), + "Invalid length for {}::{}: {} > {}", + "Foo", + "a", + self.a.len(), 0xff_ffff_ffff_usize ); } @@ -98,6 +104,7 @@ impl Foo { 5 + self.a.len() * 2 } } + #[derive(Debug, Clone, PartialEq, Eq)] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] pub struct BarData { @@ -132,15 +139,16 @@ impl BarData { }); } let x_count = bytes.get_mut().get_uint_le(5) as usize; - let x = (0..x_count) - .map(|_| Foo::parse_inner(bytes)) - .collect::>>()?; + let x = (0..x_count).map(|_| Foo::parse_inner(bytes)).collect::>>()?; Ok(Self { x }) } fn write_to(&self, buffer: &mut BytesMut) { if self.x.len() > 0xff_ffff_ffff_usize { panic!( - "Invalid length for {}::{}: {} > {}", "Bar", "x", self.x.len(), + "Invalid length for {}::{}: {} > {}", + "Bar", + "x", + self.x.len(), 0xff_ffff_ffff_usize ); } diff --git a/tools/pdl/tests/generated/packet_decl_array_unknown_element_width_dynamic_size_big_endian.rs b/tools/pdl/tests/generated/packet_decl_array_unknown_element_width_dynamic_size_big_endian.rs index ee4459e5978..efd41a25a4f 100644 --- a/tools/pdl/tests/generated/packet_decl_array_unknown_element_width_dynamic_size_big_endian.rs +++ b/tools/pdl/tests/generated/packet_decl_array_unknown_element_width_dynamic_size_big_endian.rs @@ -1,16 +1,18 @@ -#![rustfmt::skip] -/// @generated rust packets from test. +// @generated rust packets from test + use bytes::{Buf, BufMut, Bytes, BytesMut}; -use std::convert::{TryFrom, TryInto}; use std::cell::Cell; +use std::convert::{TryFrom, TryInto}; use std::fmt; use std::sync::Arc; use thiserror::Error; + type Result = std::result::Result; -/// Private prevents users from creating arbitrary scalar values -/// in situations where the value needs to be validated. -/// Users can freely deref the value, but only the backend -/// may create it. + +#[doc = r" Private prevents users from creating arbitrary scalar values"] +#[doc = r" in situations where the value needs to be validated."] +#[doc = r" Users can freely deref the value, but only the backend"] +#[doc = r" may create it."] #[derive(Debug, Clone, Copy, Hash, PartialEq, Eq, PartialOrd, Ord)] pub struct Private(T); impl std::ops::Deref for Private { @@ -19,6 +21,7 @@ impl std::ops::Deref for Private { &self.0 } } + #[derive(Debug, Error)] pub enum Error { #[error("Packet parsing failed")] @@ -29,9 +32,7 @@ pub enum Error { InvalidFixedValue { expected: u64, actual: u64 }, #[error("when parsing {obj} needed length of {wanted} but got {got}")] InvalidLengthError { obj: String, wanted: usize, got: usize }, - #[error( - "array size ({array} bytes) is not a multiple of the element size ({element} bytes)" - )] + #[error("array size ({array} bytes) is not a multiple of the element size ({element} bytes)")] InvalidArraySize { array: usize, element: usize }, #[error("Due to size restrictions a struct could not be parsed.")] ImpossibleStructError, @@ -40,10 +41,12 @@ pub enum Error { #[error("expected child {expected}, got {actual}")] InvalidChildError { expected: &'static str, actual: String }, } + pub trait Packet { fn to_bytes(self) -> Bytes; fn to_vec(self) -> Vec; } + #[derive(Debug, Clone, PartialEq, Eq)] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] pub struct Foo { @@ -82,7 +85,10 @@ impl Foo { fn write_to(&self, buffer: &mut BytesMut) { if self.a.len() > 0xff_ffff_ffff_usize { panic!( - "Invalid length for {}::{}: {} > {}", "Foo", "a", self.a.len(), + "Invalid length for {}::{}: {} > {}", + "Foo", + "a", + self.a.len(), 0xff_ffff_ffff_usize ); } @@ -98,6 +104,7 @@ impl Foo { 5 + self.a.len() * 2 } } + #[derive(Debug, Clone, PartialEq, Eq)] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] pub struct BarData { @@ -151,10 +158,7 @@ impl BarData { fn write_to(&self, buffer: &mut BytesMut) { let x_size = self.x.iter().map(|elem| elem.get_size()).sum::(); if x_size > 0xff_ffff_ffff_usize { - panic!( - "Invalid length for {}::{}: {} > {}", "Bar", "x", x_size, - 0xff_ffff_ffff_usize - ); + panic!("Invalid length for {}::{}: {} > {}", "Bar", "x", x_size, 0xff_ffff_ffff_usize); } buffer.put_uint(x_size as u64, 5); for elem in &self.x { diff --git a/tools/pdl/tests/generated/packet_decl_array_unknown_element_width_dynamic_size_little_endian.rs b/tools/pdl/tests/generated/packet_decl_array_unknown_element_width_dynamic_size_little_endian.rs index a0605eb919d..4fdaa545aa0 100644 --- a/tools/pdl/tests/generated/packet_decl_array_unknown_element_width_dynamic_size_little_endian.rs +++ b/tools/pdl/tests/generated/packet_decl_array_unknown_element_width_dynamic_size_little_endian.rs @@ -1,16 +1,18 @@ -#![rustfmt::skip] -/// @generated rust packets from test. +// @generated rust packets from test + use bytes::{Buf, BufMut, Bytes, BytesMut}; -use std::convert::{TryFrom, TryInto}; use std::cell::Cell; +use std::convert::{TryFrom, TryInto}; use std::fmt; use std::sync::Arc; use thiserror::Error; + type Result = std::result::Result; -/// Private prevents users from creating arbitrary scalar values -/// in situations where the value needs to be validated. -/// Users can freely deref the value, but only the backend -/// may create it. + +#[doc = r" Private prevents users from creating arbitrary scalar values"] +#[doc = r" in situations where the value needs to be validated."] +#[doc = r" Users can freely deref the value, but only the backend"] +#[doc = r" may create it."] #[derive(Debug, Clone, Copy, Hash, PartialEq, Eq, PartialOrd, Ord)] pub struct Private(T); impl std::ops::Deref for Private { @@ -19,6 +21,7 @@ impl std::ops::Deref for Private { &self.0 } } + #[derive(Debug, Error)] pub enum Error { #[error("Packet parsing failed")] @@ -29,9 +32,7 @@ pub enum Error { InvalidFixedValue { expected: u64, actual: u64 }, #[error("when parsing {obj} needed length of {wanted} but got {got}")] InvalidLengthError { obj: String, wanted: usize, got: usize }, - #[error( - "array size ({array} bytes) is not a multiple of the element size ({element} bytes)" - )] + #[error("array size ({array} bytes) is not a multiple of the element size ({element} bytes)")] InvalidArraySize { array: usize, element: usize }, #[error("Due to size restrictions a struct could not be parsed.")] ImpossibleStructError, @@ -40,10 +41,12 @@ pub enum Error { #[error("expected child {expected}, got {actual}")] InvalidChildError { expected: &'static str, actual: String }, } + pub trait Packet { fn to_bytes(self) -> Bytes; fn to_vec(self) -> Vec; } + #[derive(Debug, Clone, PartialEq, Eq)] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] pub struct Foo { @@ -82,7 +85,10 @@ impl Foo { fn write_to(&self, buffer: &mut BytesMut) { if self.a.len() > 0xff_ffff_ffff_usize { panic!( - "Invalid length for {}::{}: {} > {}", "Foo", "a", self.a.len(), + "Invalid length for {}::{}: {} > {}", + "Foo", + "a", + self.a.len(), 0xff_ffff_ffff_usize ); } @@ -98,6 +104,7 @@ impl Foo { 5 + self.a.len() * 2 } } + #[derive(Debug, Clone, PartialEq, Eq)] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] pub struct BarData { @@ -151,10 +158,7 @@ impl BarData { fn write_to(&self, buffer: &mut BytesMut) { let x_size = self.x.iter().map(|elem| elem.get_size()).sum::(); if x_size > 0xff_ffff_ffff_usize { - panic!( - "Invalid length for {}::{}: {} > {}", "Bar", "x", x_size, - 0xff_ffff_ffff_usize - ); + panic!("Invalid length for {}::{}: {} > {}", "Bar", "x", x_size, 0xff_ffff_ffff_usize); } buffer.put_uint_le(x_size as u64, 5); for elem in &self.x { diff --git a/tools/pdl/tests/generated/packet_decl_array_with_padding_big_endian.rs b/tools/pdl/tests/generated/packet_decl_array_with_padding_big_endian.rs index 36b55712183..9e285db1444 100644 --- a/tools/pdl/tests/generated/packet_decl_array_with_padding_big_endian.rs +++ b/tools/pdl/tests/generated/packet_decl_array_with_padding_big_endian.rs @@ -1,16 +1,18 @@ -#![rustfmt::skip] -/// @generated rust packets from test. +// @generated rust packets from test + use bytes::{Buf, BufMut, Bytes, BytesMut}; -use std::convert::{TryFrom, TryInto}; use std::cell::Cell; +use std::convert::{TryFrom, TryInto}; use std::fmt; use std::sync::Arc; use thiserror::Error; + type Result = std::result::Result; -/// Private prevents users from creating arbitrary scalar values -/// in situations where the value needs to be validated. -/// Users can freely deref the value, but only the backend -/// may create it. + +#[doc = r" Private prevents users from creating arbitrary scalar values"] +#[doc = r" in situations where the value needs to be validated."] +#[doc = r" Users can freely deref the value, but only the backend"] +#[doc = r" may create it."] #[derive(Debug, Clone, Copy, Hash, PartialEq, Eq, PartialOrd, Ord)] pub struct Private(T); impl std::ops::Deref for Private { @@ -19,6 +21,7 @@ impl std::ops::Deref for Private { &self.0 } } + #[derive(Debug, Error)] pub enum Error { #[error("Packet parsing failed")] @@ -29,9 +32,7 @@ pub enum Error { InvalidFixedValue { expected: u64, actual: u64 }, #[error("when parsing {obj} needed length of {wanted} but got {got}")] InvalidLengthError { obj: String, wanted: usize, got: usize }, - #[error( - "array size ({array} bytes) is not a multiple of the element size ({element} bytes)" - )] + #[error("array size ({array} bytes) is not a multiple of the element size ({element} bytes)")] InvalidArraySize { array: usize, element: usize }, #[error("Due to size restrictions a struct could not be parsed.")] ImpossibleStructError, @@ -40,10 +41,12 @@ pub enum Error { #[error("expected child {expected}, got {actual}")] InvalidChildError { expected: &'static str, actual: String }, } + pub trait Packet { fn to_bytes(self) -> Bytes; fn to_vec(self) -> Vec; } + #[derive(Debug, Clone, PartialEq, Eq)] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] pub struct Foo { @@ -82,7 +85,10 @@ impl Foo { fn write_to(&self, buffer: &mut BytesMut) { if self.a.len() > 0xff_ffff_ffff_usize { panic!( - "Invalid length for {}::{}: {} > {}", "Foo", "a", self.a.len(), + "Invalid length for {}::{}: {} > {}", + "Foo", + "a", + self.a.len(), 0xff_ffff_ffff_usize ); } @@ -98,6 +104,7 @@ impl Foo { 5 + self.a.len() * 2 } } + #[derive(Debug, Clone, PartialEq, Eq)] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] pub struct BarData { @@ -147,9 +154,7 @@ impl BarData { } let array_size = buffer.len() - current_size; if array_size > 128usize { - panic!( - "attempted to serialize an array larger than the enclosing padding size" - ); + panic!("attempted to serialize an array larger than the enclosing padding size"); } buffer.put_bytes(0, 128usize - array_size); } diff --git a/tools/pdl/tests/generated/packet_decl_array_with_padding_little_endian.rs b/tools/pdl/tests/generated/packet_decl_array_with_padding_little_endian.rs index 53cec927818..df694a61a5c 100644 --- a/tools/pdl/tests/generated/packet_decl_array_with_padding_little_endian.rs +++ b/tools/pdl/tests/generated/packet_decl_array_with_padding_little_endian.rs @@ -1,16 +1,18 @@ -#![rustfmt::skip] -/// @generated rust packets from test. +// @generated rust packets from test + use bytes::{Buf, BufMut, Bytes, BytesMut}; -use std::convert::{TryFrom, TryInto}; use std::cell::Cell; +use std::convert::{TryFrom, TryInto}; use std::fmt; use std::sync::Arc; use thiserror::Error; + type Result = std::result::Result; -/// Private prevents users from creating arbitrary scalar values -/// in situations where the value needs to be validated. -/// Users can freely deref the value, but only the backend -/// may create it. + +#[doc = r" Private prevents users from creating arbitrary scalar values"] +#[doc = r" in situations where the value needs to be validated."] +#[doc = r" Users can freely deref the value, but only the backend"] +#[doc = r" may create it."] #[derive(Debug, Clone, Copy, Hash, PartialEq, Eq, PartialOrd, Ord)] pub struct Private(T); impl std::ops::Deref for Private { @@ -19,6 +21,7 @@ impl std::ops::Deref for Private { &self.0 } } + #[derive(Debug, Error)] pub enum Error { #[error("Packet parsing failed")] @@ -29,9 +32,7 @@ pub enum Error { InvalidFixedValue { expected: u64, actual: u64 }, #[error("when parsing {obj} needed length of {wanted} but got {got}")] InvalidLengthError { obj: String, wanted: usize, got: usize }, - #[error( - "array size ({array} bytes) is not a multiple of the element size ({element} bytes)" - )] + #[error("array size ({array} bytes) is not a multiple of the element size ({element} bytes)")] InvalidArraySize { array: usize, element: usize }, #[error("Due to size restrictions a struct could not be parsed.")] ImpossibleStructError, @@ -40,10 +41,12 @@ pub enum Error { #[error("expected child {expected}, got {actual}")] InvalidChildError { expected: &'static str, actual: String }, } + pub trait Packet { fn to_bytes(self) -> Bytes; fn to_vec(self) -> Vec; } + #[derive(Debug, Clone, PartialEq, Eq)] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] pub struct Foo { @@ -82,7 +85,10 @@ impl Foo { fn write_to(&self, buffer: &mut BytesMut) { if self.a.len() > 0xff_ffff_ffff_usize { panic!( - "Invalid length for {}::{}: {} > {}", "Foo", "a", self.a.len(), + "Invalid length for {}::{}: {} > {}", + "Foo", + "a", + self.a.len(), 0xff_ffff_ffff_usize ); } @@ -98,6 +104,7 @@ impl Foo { 5 + self.a.len() * 2 } } + #[derive(Debug, Clone, PartialEq, Eq)] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] pub struct BarData { @@ -147,9 +154,7 @@ impl BarData { } let array_size = buffer.len() - current_size; if array_size > 128usize { - panic!( - "attempted to serialize an array larger than the enclosing padding size" - ); + panic!("attempted to serialize an array larger than the enclosing padding size"); } buffer.put_bytes(0, 128usize - array_size); } diff --git a/tools/pdl/tests/generated/packet_decl_child_packets_big_endian.rs b/tools/pdl/tests/generated/packet_decl_child_packets_big_endian.rs index e8468a7a44e..3940cc0f3fb 100644 --- a/tools/pdl/tests/generated/packet_decl_child_packets_big_endian.rs +++ b/tools/pdl/tests/generated/packet_decl_child_packets_big_endian.rs @@ -1,16 +1,18 @@ -#![rustfmt::skip] -/// @generated rust packets from test. +// @generated rust packets from test + use bytes::{Buf, BufMut, Bytes, BytesMut}; -use std::convert::{TryFrom, TryInto}; use std::cell::Cell; +use std::convert::{TryFrom, TryInto}; use std::fmt; use std::sync::Arc; use thiserror::Error; + type Result = std::result::Result; -/// Private prevents users from creating arbitrary scalar values -/// in situations where the value needs to be validated. -/// Users can freely deref the value, but only the backend -/// may create it. + +#[doc = r" Private prevents users from creating arbitrary scalar values"] +#[doc = r" in situations where the value needs to be validated."] +#[doc = r" Users can freely deref the value, but only the backend"] +#[doc = r" may create it."] #[derive(Debug, Clone, Copy, Hash, PartialEq, Eq, PartialOrd, Ord)] pub struct Private(T); impl std::ops::Deref for Private { @@ -19,6 +21,7 @@ impl std::ops::Deref for Private { &self.0 } } + #[derive(Debug, Error)] pub enum Error { #[error("Packet parsing failed")] @@ -29,9 +32,7 @@ pub enum Error { InvalidFixedValue { expected: u64, actual: u64 }, #[error("when parsing {obj} needed length of {wanted} but got {got}")] InvalidLengthError { obj: String, wanted: usize, got: usize }, - #[error( - "array size ({array} bytes) is not a multiple of the element size ({element} bytes)" - )] + #[error("array size ({array} bytes) is not a multiple of the element size ({element} bytes)")] InvalidArraySize { array: usize, element: usize }, #[error("Due to size restrictions a struct could not be parsed.")] ImpossibleStructError, @@ -40,10 +41,12 @@ pub enum Error { #[error("expected child {expected}, got {actual}")] InvalidChildError { expected: &'static str, actual: String }, } + pub trait Packet { fn to_bytes(self) -> Bytes; fn to_vec(self) -> Vec; } + #[repr(u64)] #[derive(Debug, Clone, Copy, Hash, Eq, PartialEq)] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] @@ -95,6 +98,7 @@ impl From for u64 { u16::from(value) as Self } } + #[derive(Debug, Clone, PartialEq, Eq)] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] pub enum FooDataChild { @@ -166,13 +170,14 @@ impl FooData { got: bytes.get().remaining(), }); } - let b = Enum16::try_from(bytes.get_mut().get_u16()) - .map_err(|_| Error::InvalidEnumValueError { + let b = Enum16::try_from(bytes.get_mut().get_u16()).map_err(|_| { + Error::InvalidEnumValueError { obj: "Foo".to_string(), field: "b".to_string(), value: bytes.get_mut().get_u16() as u64, type_: "Enum16".to_string(), - })?; + } + })?; if bytes.get().remaining() < 1 { return Err(Error::InvalidLengthError { obj: "Foo".to_string(), @@ -201,9 +206,7 @@ impl FooData { let child_data = BazData::parse_inner(&mut cell)?; FooDataChild::Baz(Arc::new(child_data)) } - _ if !payload.is_empty() => { - FooDataChild::Payload(Bytes::copy_from_slice(payload)) - } + _ if !payload.is_empty() => FooDataChild::Payload(Bytes::copy_from_slice(payload)), _ => FooDataChild::None, }; Ok(Self { a, b, child }) @@ -213,8 +216,11 @@ impl FooData { buffer.put_u16(u16::from(self.b)); if self.child.get_total_size() > 0xff { panic!( - "Invalid length for {}::{}: {} > {}", "Foo", "_payload_", self.child - .get_total_size(), 0xff + "Invalid length for {}::{}: {} > {}", + "Foo", + "_payload_", + self.child.get_total_size(), + 0xff ); } buffer.put_u8(self.child.get_total_size() as u8); @@ -304,6 +310,7 @@ impl From for Foo { builder.build().into() } } + #[derive(Debug, Clone, PartialEq, Eq)] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] pub struct BarData { @@ -400,8 +407,8 @@ impl Bar { _ => { return Err(Error::InvalidChildError { expected: stringify!(FooDataChild::Bar), - actual: format!("{:?}", & foo.child), - }); + actual: format!("{:?}", &foo.child), + }) } }; Ok(Self { foo, bar }) @@ -425,11 +432,7 @@ impl Bar { impl BarBuilder { pub fn build(self) -> Bar { let bar = Arc::new(BarData { x: self.x }); - let foo = Arc::new(FooData { - a: 100, - b: self.b, - child: FooDataChild::Bar(bar), - }); + let foo = Arc::new(FooData { a: 100, b: self.b, child: FooDataChild::Bar(bar) }); Bar::new(foo).unwrap() } } @@ -443,6 +446,7 @@ impl From for Bar { builder.build().into() } } + #[derive(Debug, Clone, PartialEq, Eq)] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] pub struct BazData { @@ -539,8 +543,8 @@ impl Baz { _ => { return Err(Error::InvalidChildError { expected: stringify!(FooDataChild::Baz), - actual: format!("{:?}", & foo.child), - }); + actual: format!("{:?}", &foo.child), + }) } }; Ok(Self { foo, baz }) @@ -564,11 +568,7 @@ impl Baz { impl BazBuilder { pub fn build(self) -> Baz { let baz = Arc::new(BazData { y: self.y }); - let foo = Arc::new(FooData { - a: self.a, - b: Enum16::B, - child: FooDataChild::Baz(baz), - }); + let foo = Arc::new(FooData { a: self.a, b: Enum16::B, child: FooDataChild::Baz(baz) }); Baz::new(foo).unwrap() } } diff --git a/tools/pdl/tests/generated/packet_decl_child_packets_little_endian.rs b/tools/pdl/tests/generated/packet_decl_child_packets_little_endian.rs index bbbb2617c4e..ca17b244db9 100644 --- a/tools/pdl/tests/generated/packet_decl_child_packets_little_endian.rs +++ b/tools/pdl/tests/generated/packet_decl_child_packets_little_endian.rs @@ -1,16 +1,18 @@ -#![rustfmt::skip] -/// @generated rust packets from test. +// @generated rust packets from test + use bytes::{Buf, BufMut, Bytes, BytesMut}; -use std::convert::{TryFrom, TryInto}; use std::cell::Cell; +use std::convert::{TryFrom, TryInto}; use std::fmt; use std::sync::Arc; use thiserror::Error; + type Result = std::result::Result; -/// Private prevents users from creating arbitrary scalar values -/// in situations where the value needs to be validated. -/// Users can freely deref the value, but only the backend -/// may create it. + +#[doc = r" Private prevents users from creating arbitrary scalar values"] +#[doc = r" in situations where the value needs to be validated."] +#[doc = r" Users can freely deref the value, but only the backend"] +#[doc = r" may create it."] #[derive(Debug, Clone, Copy, Hash, PartialEq, Eq, PartialOrd, Ord)] pub struct Private(T); impl std::ops::Deref for Private { @@ -19,6 +21,7 @@ impl std::ops::Deref for Private { &self.0 } } + #[derive(Debug, Error)] pub enum Error { #[error("Packet parsing failed")] @@ -29,9 +32,7 @@ pub enum Error { InvalidFixedValue { expected: u64, actual: u64 }, #[error("when parsing {obj} needed length of {wanted} but got {got}")] InvalidLengthError { obj: String, wanted: usize, got: usize }, - #[error( - "array size ({array} bytes) is not a multiple of the element size ({element} bytes)" - )] + #[error("array size ({array} bytes) is not a multiple of the element size ({element} bytes)")] InvalidArraySize { array: usize, element: usize }, #[error("Due to size restrictions a struct could not be parsed.")] ImpossibleStructError, @@ -40,10 +41,12 @@ pub enum Error { #[error("expected child {expected}, got {actual}")] InvalidChildError { expected: &'static str, actual: String }, } + pub trait Packet { fn to_bytes(self) -> Bytes; fn to_vec(self) -> Vec; } + #[repr(u64)] #[derive(Debug, Clone, Copy, Hash, Eq, PartialEq)] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] @@ -95,6 +98,7 @@ impl From for u64 { u16::from(value) as Self } } + #[derive(Debug, Clone, PartialEq, Eq)] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] pub enum FooDataChild { @@ -166,13 +170,14 @@ impl FooData { got: bytes.get().remaining(), }); } - let b = Enum16::try_from(bytes.get_mut().get_u16_le()) - .map_err(|_| Error::InvalidEnumValueError { + let b = Enum16::try_from(bytes.get_mut().get_u16_le()).map_err(|_| { + Error::InvalidEnumValueError { obj: "Foo".to_string(), field: "b".to_string(), value: bytes.get_mut().get_u16_le() as u64, type_: "Enum16".to_string(), - })?; + } + })?; if bytes.get().remaining() < 1 { return Err(Error::InvalidLengthError { obj: "Foo".to_string(), @@ -201,9 +206,7 @@ impl FooData { let child_data = BazData::parse_inner(&mut cell)?; FooDataChild::Baz(Arc::new(child_data)) } - _ if !payload.is_empty() => { - FooDataChild::Payload(Bytes::copy_from_slice(payload)) - } + _ if !payload.is_empty() => FooDataChild::Payload(Bytes::copy_from_slice(payload)), _ => FooDataChild::None, }; Ok(Self { a, b, child }) @@ -213,8 +216,11 @@ impl FooData { buffer.put_u16_le(u16::from(self.b)); if self.child.get_total_size() > 0xff { panic!( - "Invalid length for {}::{}: {} > {}", "Foo", "_payload_", self.child - .get_total_size(), 0xff + "Invalid length for {}::{}: {} > {}", + "Foo", + "_payload_", + self.child.get_total_size(), + 0xff ); } buffer.put_u8(self.child.get_total_size() as u8); @@ -304,6 +310,7 @@ impl From for Foo { builder.build().into() } } + #[derive(Debug, Clone, PartialEq, Eq)] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] pub struct BarData { @@ -400,8 +407,8 @@ impl Bar { _ => { return Err(Error::InvalidChildError { expected: stringify!(FooDataChild::Bar), - actual: format!("{:?}", & foo.child), - }); + actual: format!("{:?}", &foo.child), + }) } }; Ok(Self { foo, bar }) @@ -425,11 +432,7 @@ impl Bar { impl BarBuilder { pub fn build(self) -> Bar { let bar = Arc::new(BarData { x: self.x }); - let foo = Arc::new(FooData { - a: 100, - b: self.b, - child: FooDataChild::Bar(bar), - }); + let foo = Arc::new(FooData { a: 100, b: self.b, child: FooDataChild::Bar(bar) }); Bar::new(foo).unwrap() } } @@ -443,6 +446,7 @@ impl From for Bar { builder.build().into() } } + #[derive(Debug, Clone, PartialEq, Eq)] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] pub struct BazData { @@ -539,8 +543,8 @@ impl Baz { _ => { return Err(Error::InvalidChildError { expected: stringify!(FooDataChild::Baz), - actual: format!("{:?}", & foo.child), - }); + actual: format!("{:?}", &foo.child), + }) } }; Ok(Self { foo, baz }) @@ -564,11 +568,7 @@ impl Baz { impl BazBuilder { pub fn build(self) -> Baz { let baz = Arc::new(BazData { y: self.y }); - let foo = Arc::new(FooData { - a: self.a, - b: Enum16::B, - child: FooDataChild::Baz(baz), - }); + let foo = Arc::new(FooData { a: self.a, b: Enum16::B, child: FooDataChild::Baz(baz) }); Baz::new(foo).unwrap() } } diff --git a/tools/pdl/tests/generated/packet_decl_complex_scalars_big_endian.rs b/tools/pdl/tests/generated/packet_decl_complex_scalars_big_endian.rs index 688af4282f9..7eeb9b7df6e 100644 --- a/tools/pdl/tests/generated/packet_decl_complex_scalars_big_endian.rs +++ b/tools/pdl/tests/generated/packet_decl_complex_scalars_big_endian.rs @@ -1,16 +1,18 @@ -#![rustfmt::skip] -/// @generated rust packets from test. +// @generated rust packets from test + use bytes::{Buf, BufMut, Bytes, BytesMut}; -use std::convert::{TryFrom, TryInto}; use std::cell::Cell; +use std::convert::{TryFrom, TryInto}; use std::fmt; use std::sync::Arc; use thiserror::Error; + type Result = std::result::Result; -/// Private prevents users from creating arbitrary scalar values -/// in situations where the value needs to be validated. -/// Users can freely deref the value, but only the backend -/// may create it. + +#[doc = r" Private prevents users from creating arbitrary scalar values"] +#[doc = r" in situations where the value needs to be validated."] +#[doc = r" Users can freely deref the value, but only the backend"] +#[doc = r" may create it."] #[derive(Debug, Clone, Copy, Hash, PartialEq, Eq, PartialOrd, Ord)] pub struct Private(T); impl std::ops::Deref for Private { @@ -19,6 +21,7 @@ impl std::ops::Deref for Private { &self.0 } } + #[derive(Debug, Error)] pub enum Error { #[error("Packet parsing failed")] @@ -29,9 +32,7 @@ pub enum Error { InvalidFixedValue { expected: u64, actual: u64 }, #[error("when parsing {obj} needed length of {wanted} but got {got}")] InvalidLengthError { obj: String, wanted: usize, got: usize }, - #[error( - "array size ({array} bytes) is not a multiple of the element size ({element} bytes)" - )] + #[error("array size ({array} bytes) is not a multiple of the element size ({element} bytes)")] InvalidArraySize { array: usize, element: usize }, #[error("Due to size restrictions a struct could not be parsed.")] ImpossibleStructError, @@ -40,10 +41,12 @@ pub enum Error { #[error("expected child {expected}, got {actual}")] InvalidChildError { expected: &'static str, actual: String }, } + pub trait Packet { fn to_bytes(self) -> Bytes; fn to_vec(self) -> Vec; } + #[derive(Debug, Clone, PartialEq, Eq)] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] pub struct FooData { @@ -200,14 +203,8 @@ impl Foo { } impl FooBuilder { pub fn build(self) -> Foo { - let foo = Arc::new(FooData { - a: self.a, - b: self.b, - c: self.c, - d: self.d, - e: self.e, - f: self.f, - }); + let foo = + Arc::new(FooData { a: self.a, b: self.b, c: self.c, d: self.d, e: self.e, f: self.f }); Foo::new(foo).unwrap() } } diff --git a/tools/pdl/tests/generated/packet_decl_complex_scalars_little_endian.rs b/tools/pdl/tests/generated/packet_decl_complex_scalars_little_endian.rs index 83da632a3a0..dd684e60a18 100644 --- a/tools/pdl/tests/generated/packet_decl_complex_scalars_little_endian.rs +++ b/tools/pdl/tests/generated/packet_decl_complex_scalars_little_endian.rs @@ -1,16 +1,18 @@ -#![rustfmt::skip] -/// @generated rust packets from test. +// @generated rust packets from test + use bytes::{Buf, BufMut, Bytes, BytesMut}; -use std::convert::{TryFrom, TryInto}; use std::cell::Cell; +use std::convert::{TryFrom, TryInto}; use std::fmt; use std::sync::Arc; use thiserror::Error; + type Result = std::result::Result; -/// Private prevents users from creating arbitrary scalar values -/// in situations where the value needs to be validated. -/// Users can freely deref the value, but only the backend -/// may create it. + +#[doc = r" Private prevents users from creating arbitrary scalar values"] +#[doc = r" in situations where the value needs to be validated."] +#[doc = r" Users can freely deref the value, but only the backend"] +#[doc = r" may create it."] #[derive(Debug, Clone, Copy, Hash, PartialEq, Eq, PartialOrd, Ord)] pub struct Private(T); impl std::ops::Deref for Private { @@ -19,6 +21,7 @@ impl std::ops::Deref for Private { &self.0 } } + #[derive(Debug, Error)] pub enum Error { #[error("Packet parsing failed")] @@ -29,9 +32,7 @@ pub enum Error { InvalidFixedValue { expected: u64, actual: u64 }, #[error("when parsing {obj} needed length of {wanted} but got {got}")] InvalidLengthError { obj: String, wanted: usize, got: usize }, - #[error( - "array size ({array} bytes) is not a multiple of the element size ({element} bytes)" - )] + #[error("array size ({array} bytes) is not a multiple of the element size ({element} bytes)")] InvalidArraySize { array: usize, element: usize }, #[error("Due to size restrictions a struct could not be parsed.")] ImpossibleStructError, @@ -40,10 +41,12 @@ pub enum Error { #[error("expected child {expected}, got {actual}")] InvalidChildError { expected: &'static str, actual: String }, } + pub trait Packet { fn to_bytes(self) -> Bytes; fn to_vec(self) -> Vec; } + #[derive(Debug, Clone, PartialEq, Eq)] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] pub struct FooData { @@ -200,14 +203,8 @@ impl Foo { } impl FooBuilder { pub fn build(self) -> Foo { - let foo = Arc::new(FooData { - a: self.a, - b: self.b, - c: self.c, - d: self.d, - e: self.e, - f: self.f, - }); + let foo = + Arc::new(FooData { a: self.a, b: self.b, c: self.c, d: self.d, e: self.e, f: self.f }); Foo::new(foo).unwrap() } } diff --git a/tools/pdl/tests/generated/packet_decl_custom_field_big_endian.rs b/tools/pdl/tests/generated/packet_decl_custom_field_big_endian.rs index 4783d1f767d..cfe327f6b74 100644 --- a/tools/pdl/tests/generated/packet_decl_custom_field_big_endian.rs +++ b/tools/pdl/tests/generated/packet_decl_custom_field_big_endian.rs @@ -1,16 +1,18 @@ -#![rustfmt::skip] -/// @generated rust packets from test. +// @generated rust packets from test + use bytes::{Buf, BufMut, Bytes, BytesMut}; -use std::convert::{TryFrom, TryInto}; use std::cell::Cell; +use std::convert::{TryFrom, TryInto}; use std::fmt; use std::sync::Arc; use thiserror::Error; + type Result = std::result::Result; -/// Private prevents users from creating arbitrary scalar values -/// in situations where the value needs to be validated. -/// Users can freely deref the value, but only the backend -/// may create it. + +#[doc = r" Private prevents users from creating arbitrary scalar values"] +#[doc = r" in situations where the value needs to be validated."] +#[doc = r" Users can freely deref the value, but only the backend"] +#[doc = r" may create it."] #[derive(Debug, Clone, Copy, Hash, PartialEq, Eq, PartialOrd, Ord)] pub struct Private(T); impl std::ops::Deref for Private { @@ -19,6 +21,7 @@ impl std::ops::Deref for Private { &self.0 } } + #[derive(Debug, Error)] pub enum Error { #[error("Packet parsing failed")] @@ -29,9 +32,7 @@ pub enum Error { InvalidFixedValue { expected: u64, actual: u64 }, #[error("when parsing {obj} needed length of {wanted} but got {got}")] InvalidLengthError { obj: String, wanted: usize, got: usize }, - #[error( - "array size ({array} bytes) is not a multiple of the element size ({element} bytes)" - )] + #[error("array size ({array} bytes) is not a multiple of the element size ({element} bytes)")] InvalidArraySize { array: usize, element: usize }, #[error("Due to size restrictions a struct could not be parsed.")] ImpossibleStructError, @@ -40,10 +41,12 @@ pub enum Error { #[error("expected child {expected}, got {actual}")] InvalidChildError { expected: &'static str, actual: String }, } + pub trait Packet { fn to_bytes(self) -> Bytes; fn to_vec(self) -> Vec; } + #[derive(Debug, Clone, Copy, Hash, Eq, PartialEq)] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] #[cfg_attr(feature = "serde", serde(try_from = "u32", into = "u32"))] @@ -61,9 +64,14 @@ impl From for u32 { impl TryFrom for Bar1 { type Error = u32; fn try_from(value: u32) -> std::result::Result { - if value > 0xff_ffff { Err(value) } else { Ok(Bar1(value)) } + if value > 0xff_ffff { + Err(value) + } else { + Ok(Bar1(value)) + } } } + #[derive(Debug, Clone, Copy, Hash, Eq, PartialEq)] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] #[cfg_attr(feature = "serde", serde(from = "u32", into = "u32"))] @@ -83,6 +91,7 @@ impl From for Bar2 { Bar2(value) } } + #[derive(Debug, Clone, PartialEq, Eq)] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] pub struct FooData { diff --git a/tools/pdl/tests/generated/packet_decl_custom_field_little_endian.rs b/tools/pdl/tests/generated/packet_decl_custom_field_little_endian.rs index 60d17f5c7cb..4a12f13ed4f 100644 --- a/tools/pdl/tests/generated/packet_decl_custom_field_little_endian.rs +++ b/tools/pdl/tests/generated/packet_decl_custom_field_little_endian.rs @@ -1,16 +1,18 @@ -#![rustfmt::skip] -/// @generated rust packets from test. +// @generated rust packets from test + use bytes::{Buf, BufMut, Bytes, BytesMut}; -use std::convert::{TryFrom, TryInto}; use std::cell::Cell; +use std::convert::{TryFrom, TryInto}; use std::fmt; use std::sync::Arc; use thiserror::Error; + type Result = std::result::Result; -/// Private prevents users from creating arbitrary scalar values -/// in situations where the value needs to be validated. -/// Users can freely deref the value, but only the backend -/// may create it. + +#[doc = r" Private prevents users from creating arbitrary scalar values"] +#[doc = r" in situations where the value needs to be validated."] +#[doc = r" Users can freely deref the value, but only the backend"] +#[doc = r" may create it."] #[derive(Debug, Clone, Copy, Hash, PartialEq, Eq, PartialOrd, Ord)] pub struct Private(T); impl std::ops::Deref for Private { @@ -19,6 +21,7 @@ impl std::ops::Deref for Private { &self.0 } } + #[derive(Debug, Error)] pub enum Error { #[error("Packet parsing failed")] @@ -29,9 +32,7 @@ pub enum Error { InvalidFixedValue { expected: u64, actual: u64 }, #[error("when parsing {obj} needed length of {wanted} but got {got}")] InvalidLengthError { obj: String, wanted: usize, got: usize }, - #[error( - "array size ({array} bytes) is not a multiple of the element size ({element} bytes)" - )] + #[error("array size ({array} bytes) is not a multiple of the element size ({element} bytes)")] InvalidArraySize { array: usize, element: usize }, #[error("Due to size restrictions a struct could not be parsed.")] ImpossibleStructError, @@ -40,10 +41,12 @@ pub enum Error { #[error("expected child {expected}, got {actual}")] InvalidChildError { expected: &'static str, actual: String }, } + pub trait Packet { fn to_bytes(self) -> Bytes; fn to_vec(self) -> Vec; } + #[derive(Debug, Clone, Copy, Hash, Eq, PartialEq)] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] #[cfg_attr(feature = "serde", serde(try_from = "u32", into = "u32"))] @@ -61,9 +64,14 @@ impl From for u32 { impl TryFrom for Bar1 { type Error = u32; fn try_from(value: u32) -> std::result::Result { - if value > 0xff_ffff { Err(value) } else { Ok(Bar1(value)) } + if value > 0xff_ffff { + Err(value) + } else { + Ok(Bar1(value)) + } } } + #[derive(Debug, Clone, Copy, Hash, Eq, PartialEq)] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] #[cfg_attr(feature = "serde", serde(from = "u32", into = "u32"))] @@ -83,6 +91,7 @@ impl From for Bar2 { Bar2(value) } } + #[derive(Debug, Clone, PartialEq, Eq)] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] pub struct FooData { diff --git a/tools/pdl/tests/generated/packet_decl_empty_big_endian.rs b/tools/pdl/tests/generated/packet_decl_empty_big_endian.rs index d05c2ff7505..cecac9589be 100644 --- a/tools/pdl/tests/generated/packet_decl_empty_big_endian.rs +++ b/tools/pdl/tests/generated/packet_decl_empty_big_endian.rs @@ -1,16 +1,18 @@ -#![rustfmt::skip] -/// @generated rust packets from test. +// @generated rust packets from test + use bytes::{Buf, BufMut, Bytes, BytesMut}; -use std::convert::{TryFrom, TryInto}; use std::cell::Cell; +use std::convert::{TryFrom, TryInto}; use std::fmt; use std::sync::Arc; use thiserror::Error; + type Result = std::result::Result; -/// Private prevents users from creating arbitrary scalar values -/// in situations where the value needs to be validated. -/// Users can freely deref the value, but only the backend -/// may create it. + +#[doc = r" Private prevents users from creating arbitrary scalar values"] +#[doc = r" in situations where the value needs to be validated."] +#[doc = r" Users can freely deref the value, but only the backend"] +#[doc = r" may create it."] #[derive(Debug, Clone, Copy, Hash, PartialEq, Eq, PartialOrd, Ord)] pub struct Private(T); impl std::ops::Deref for Private { @@ -19,6 +21,7 @@ impl std::ops::Deref for Private { &self.0 } } + #[derive(Debug, Error)] pub enum Error { #[error("Packet parsing failed")] @@ -29,9 +32,7 @@ pub enum Error { InvalidFixedValue { expected: u64, actual: u64 }, #[error("when parsing {obj} needed length of {wanted} but got {got}")] InvalidLengthError { obj: String, wanted: usize, got: usize }, - #[error( - "array size ({array} bytes) is not a multiple of the element size ({element} bytes)" - )] + #[error("array size ({array} bytes) is not a multiple of the element size ({element} bytes)")] InvalidArraySize { array: usize, element: usize }, #[error("Due to size restrictions a struct could not be parsed.")] ImpossibleStructError, @@ -40,10 +41,12 @@ pub enum Error { #[error("expected child {expected}, got {actual}")] InvalidChildError { expected: &'static str, actual: String }, } + pub trait Packet { fn to_bytes(self) -> Bytes; fn to_vec(self) -> Vec; } + #[derive(Debug, Clone, PartialEq, Eq)] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] pub struct FooData {} diff --git a/tools/pdl/tests/generated/packet_decl_empty_little_endian.rs b/tools/pdl/tests/generated/packet_decl_empty_little_endian.rs index d05c2ff7505..cecac9589be 100644 --- a/tools/pdl/tests/generated/packet_decl_empty_little_endian.rs +++ b/tools/pdl/tests/generated/packet_decl_empty_little_endian.rs @@ -1,16 +1,18 @@ -#![rustfmt::skip] -/// @generated rust packets from test. +// @generated rust packets from test + use bytes::{Buf, BufMut, Bytes, BytesMut}; -use std::convert::{TryFrom, TryInto}; use std::cell::Cell; +use std::convert::{TryFrom, TryInto}; use std::fmt; use std::sync::Arc; use thiserror::Error; + type Result = std::result::Result; -/// Private prevents users from creating arbitrary scalar values -/// in situations where the value needs to be validated. -/// Users can freely deref the value, but only the backend -/// may create it. + +#[doc = r" Private prevents users from creating arbitrary scalar values"] +#[doc = r" in situations where the value needs to be validated."] +#[doc = r" Users can freely deref the value, but only the backend"] +#[doc = r" may create it."] #[derive(Debug, Clone, Copy, Hash, PartialEq, Eq, PartialOrd, Ord)] pub struct Private(T); impl std::ops::Deref for Private { @@ -19,6 +21,7 @@ impl std::ops::Deref for Private { &self.0 } } + #[derive(Debug, Error)] pub enum Error { #[error("Packet parsing failed")] @@ -29,9 +32,7 @@ pub enum Error { InvalidFixedValue { expected: u64, actual: u64 }, #[error("when parsing {obj} needed length of {wanted} but got {got}")] InvalidLengthError { obj: String, wanted: usize, got: usize }, - #[error( - "array size ({array} bytes) is not a multiple of the element size ({element} bytes)" - )] + #[error("array size ({array} bytes) is not a multiple of the element size ({element} bytes)")] InvalidArraySize { array: usize, element: usize }, #[error("Due to size restrictions a struct could not be parsed.")] ImpossibleStructError, @@ -40,10 +41,12 @@ pub enum Error { #[error("expected child {expected}, got {actual}")] InvalidChildError { expected: &'static str, actual: String }, } + pub trait Packet { fn to_bytes(self) -> Bytes; fn to_vec(self) -> Vec; } + #[derive(Debug, Clone, PartialEq, Eq)] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] pub struct FooData {} diff --git a/tools/pdl/tests/generated/packet_decl_fixed_enum_field_big_endian.rs b/tools/pdl/tests/generated/packet_decl_fixed_enum_field_big_endian.rs index 8683e02959e..5736028b3da 100644 --- a/tools/pdl/tests/generated/packet_decl_fixed_enum_field_big_endian.rs +++ b/tools/pdl/tests/generated/packet_decl_fixed_enum_field_big_endian.rs @@ -1,16 +1,18 @@ -#![rustfmt::skip] -/// @generated rust packets from test. +// @generated rust packets from test + use bytes::{Buf, BufMut, Bytes, BytesMut}; -use std::convert::{TryFrom, TryInto}; use std::cell::Cell; +use std::convert::{TryFrom, TryInto}; use std::fmt; use std::sync::Arc; use thiserror::Error; + type Result = std::result::Result; -/// Private prevents users from creating arbitrary scalar values -/// in situations where the value needs to be validated. -/// Users can freely deref the value, but only the backend -/// may create it. + +#[doc = r" Private prevents users from creating arbitrary scalar values"] +#[doc = r" in situations where the value needs to be validated."] +#[doc = r" Users can freely deref the value, but only the backend"] +#[doc = r" may create it."] #[derive(Debug, Clone, Copy, Hash, PartialEq, Eq, PartialOrd, Ord)] pub struct Private(T); impl std::ops::Deref for Private { @@ -19,6 +21,7 @@ impl std::ops::Deref for Private { &self.0 } } + #[derive(Debug, Error)] pub enum Error { #[error("Packet parsing failed")] @@ -29,9 +32,7 @@ pub enum Error { InvalidFixedValue { expected: u64, actual: u64 }, #[error("when parsing {obj} needed length of {wanted} but got {got}")] InvalidLengthError { obj: String, wanted: usize, got: usize }, - #[error( - "array size ({array} bytes) is not a multiple of the element size ({element} bytes)" - )] + #[error("array size ({array} bytes) is not a multiple of the element size ({element} bytes)")] InvalidArraySize { array: usize, element: usize }, #[error("Due to size restrictions a struct could not be parsed.")] ImpossibleStructError, @@ -40,10 +41,12 @@ pub enum Error { #[error("expected child {expected}, got {actual}")] InvalidChildError { expected: &'static str, actual: String }, } + pub trait Packet { fn to_bytes(self) -> Bytes; fn to_vec(self) -> Vec; } + #[repr(u64)] #[derive(Debug, Clone, Copy, Hash, Eq, PartialEq)] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] @@ -110,6 +113,7 @@ impl From for u64 { u8::from(value) as Self } } + #[derive(Debug, Clone, PartialEq, Eq)] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] pub struct FooData { @@ -156,8 +160,8 @@ impl FooData { fn write_to(&self, buffer: &mut BytesMut) { if self.b > 0x1ff_ffff_ffff_ffff_u64 { panic!( - "Invalid value for {}::{}: {} > {}", "Foo", "b", self.b, - 0x1ff_ffff_ffff_ffff_u64 + "Invalid value for {}::{}: {} > {}", + "Foo", "b", self.b, 0x1ff_ffff_ffff_ffff_u64 ); } let value = (u8::from(Enum7::A) as u64) | (self.b << 7); diff --git a/tools/pdl/tests/generated/packet_decl_fixed_enum_field_little_endian.rs b/tools/pdl/tests/generated/packet_decl_fixed_enum_field_little_endian.rs index f598d3e7192..ec39ae01990 100644 --- a/tools/pdl/tests/generated/packet_decl_fixed_enum_field_little_endian.rs +++ b/tools/pdl/tests/generated/packet_decl_fixed_enum_field_little_endian.rs @@ -1,16 +1,18 @@ -#![rustfmt::skip] -/// @generated rust packets from test. +// @generated rust packets from test + use bytes::{Buf, BufMut, Bytes, BytesMut}; -use std::convert::{TryFrom, TryInto}; use std::cell::Cell; +use std::convert::{TryFrom, TryInto}; use std::fmt; use std::sync::Arc; use thiserror::Error; + type Result = std::result::Result; -/// Private prevents users from creating arbitrary scalar values -/// in situations where the value needs to be validated. -/// Users can freely deref the value, but only the backend -/// may create it. + +#[doc = r" Private prevents users from creating arbitrary scalar values"] +#[doc = r" in situations where the value needs to be validated."] +#[doc = r" Users can freely deref the value, but only the backend"] +#[doc = r" may create it."] #[derive(Debug, Clone, Copy, Hash, PartialEq, Eq, PartialOrd, Ord)] pub struct Private(T); impl std::ops::Deref for Private { @@ -19,6 +21,7 @@ impl std::ops::Deref for Private { &self.0 } } + #[derive(Debug, Error)] pub enum Error { #[error("Packet parsing failed")] @@ -29,9 +32,7 @@ pub enum Error { InvalidFixedValue { expected: u64, actual: u64 }, #[error("when parsing {obj} needed length of {wanted} but got {got}")] InvalidLengthError { obj: String, wanted: usize, got: usize }, - #[error( - "array size ({array} bytes) is not a multiple of the element size ({element} bytes)" - )] + #[error("array size ({array} bytes) is not a multiple of the element size ({element} bytes)")] InvalidArraySize { array: usize, element: usize }, #[error("Due to size restrictions a struct could not be parsed.")] ImpossibleStructError, @@ -40,10 +41,12 @@ pub enum Error { #[error("expected child {expected}, got {actual}")] InvalidChildError { expected: &'static str, actual: String }, } + pub trait Packet { fn to_bytes(self) -> Bytes; fn to_vec(self) -> Vec; } + #[repr(u64)] #[derive(Debug, Clone, Copy, Hash, Eq, PartialEq)] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] @@ -110,6 +113,7 @@ impl From for u64 { u8::from(value) as Self } } + #[derive(Debug, Clone, PartialEq, Eq)] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] pub struct FooData { @@ -156,8 +160,8 @@ impl FooData { fn write_to(&self, buffer: &mut BytesMut) { if self.b > 0x1ff_ffff_ffff_ffff_u64 { panic!( - "Invalid value for {}::{}: {} > {}", "Foo", "b", self.b, - 0x1ff_ffff_ffff_ffff_u64 + "Invalid value for {}::{}: {} > {}", + "Foo", "b", self.b, 0x1ff_ffff_ffff_ffff_u64 ); } let value = (u8::from(Enum7::A) as u64) | (self.b << 7); diff --git a/tools/pdl/tests/generated/packet_decl_fixed_scalar_field_big_endian.rs b/tools/pdl/tests/generated/packet_decl_fixed_scalar_field_big_endian.rs index a44732ebce9..8623d8b4b25 100644 --- a/tools/pdl/tests/generated/packet_decl_fixed_scalar_field_big_endian.rs +++ b/tools/pdl/tests/generated/packet_decl_fixed_scalar_field_big_endian.rs @@ -1,16 +1,18 @@ -#![rustfmt::skip] -/// @generated rust packets from test. +// @generated rust packets from test + use bytes::{Buf, BufMut, Bytes, BytesMut}; -use std::convert::{TryFrom, TryInto}; use std::cell::Cell; +use std::convert::{TryFrom, TryInto}; use std::fmt; use std::sync::Arc; use thiserror::Error; + type Result = std::result::Result; -/// Private prevents users from creating arbitrary scalar values -/// in situations where the value needs to be validated. -/// Users can freely deref the value, but only the backend -/// may create it. + +#[doc = r" Private prevents users from creating arbitrary scalar values"] +#[doc = r" in situations where the value needs to be validated."] +#[doc = r" Users can freely deref the value, but only the backend"] +#[doc = r" may create it."] #[derive(Debug, Clone, Copy, Hash, PartialEq, Eq, PartialOrd, Ord)] pub struct Private(T); impl std::ops::Deref for Private { @@ -19,6 +21,7 @@ impl std::ops::Deref for Private { &self.0 } } + #[derive(Debug, Error)] pub enum Error { #[error("Packet parsing failed")] @@ -29,9 +32,7 @@ pub enum Error { InvalidFixedValue { expected: u64, actual: u64 }, #[error("when parsing {obj} needed length of {wanted} but got {got}")] InvalidLengthError { obj: String, wanted: usize, got: usize }, - #[error( - "array size ({array} bytes) is not a multiple of the element size ({element} bytes)" - )] + #[error("array size ({array} bytes) is not a multiple of the element size ({element} bytes)")] InvalidArraySize { array: usize, element: usize }, #[error("Due to size restrictions a struct could not be parsed.")] ImpossibleStructError, @@ -40,10 +41,12 @@ pub enum Error { #[error("expected child {expected}, got {actual}")] InvalidChildError { expected: &'static str, actual: String }, } + pub trait Packet { fn to_bytes(self) -> Bytes; fn to_vec(self) -> Vec; } + #[derive(Debug, Clone, PartialEq, Eq)] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] pub struct FooData { @@ -90,8 +93,8 @@ impl FooData { fn write_to(&self, buffer: &mut BytesMut) { if self.b > 0x1ff_ffff_ffff_ffff_u64 { panic!( - "Invalid value for {}::{}: {} > {}", "Foo", "b", self.b, - 0x1ff_ffff_ffff_ffff_u64 + "Invalid value for {}::{}: {} > {}", + "Foo", "b", self.b, 0x1ff_ffff_ffff_ffff_u64 ); } let value = (7 as u64) | (self.b << 7); diff --git a/tools/pdl/tests/generated/packet_decl_fixed_scalar_field_little_endian.rs b/tools/pdl/tests/generated/packet_decl_fixed_scalar_field_little_endian.rs index d2c7985aa1b..42d4a8f3ffe 100644 --- a/tools/pdl/tests/generated/packet_decl_fixed_scalar_field_little_endian.rs +++ b/tools/pdl/tests/generated/packet_decl_fixed_scalar_field_little_endian.rs @@ -1,16 +1,18 @@ -#![rustfmt::skip] -/// @generated rust packets from test. +// @generated rust packets from test + use bytes::{Buf, BufMut, Bytes, BytesMut}; -use std::convert::{TryFrom, TryInto}; use std::cell::Cell; +use std::convert::{TryFrom, TryInto}; use std::fmt; use std::sync::Arc; use thiserror::Error; + type Result = std::result::Result; -/// Private prevents users from creating arbitrary scalar values -/// in situations where the value needs to be validated. -/// Users can freely deref the value, but only the backend -/// may create it. + +#[doc = r" Private prevents users from creating arbitrary scalar values"] +#[doc = r" in situations where the value needs to be validated."] +#[doc = r" Users can freely deref the value, but only the backend"] +#[doc = r" may create it."] #[derive(Debug, Clone, Copy, Hash, PartialEq, Eq, PartialOrd, Ord)] pub struct Private(T); impl std::ops::Deref for Private { @@ -19,6 +21,7 @@ impl std::ops::Deref for Private { &self.0 } } + #[derive(Debug, Error)] pub enum Error { #[error("Packet parsing failed")] @@ -29,9 +32,7 @@ pub enum Error { InvalidFixedValue { expected: u64, actual: u64 }, #[error("when parsing {obj} needed length of {wanted} but got {got}")] InvalidLengthError { obj: String, wanted: usize, got: usize }, - #[error( - "array size ({array} bytes) is not a multiple of the element size ({element} bytes)" - )] + #[error("array size ({array} bytes) is not a multiple of the element size ({element} bytes)")] InvalidArraySize { array: usize, element: usize }, #[error("Due to size restrictions a struct could not be parsed.")] ImpossibleStructError, @@ -40,10 +41,12 @@ pub enum Error { #[error("expected child {expected}, got {actual}")] InvalidChildError { expected: &'static str, actual: String }, } + pub trait Packet { fn to_bytes(self) -> Bytes; fn to_vec(self) -> Vec; } + #[derive(Debug, Clone, PartialEq, Eq)] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] pub struct FooData { @@ -90,8 +93,8 @@ impl FooData { fn write_to(&self, buffer: &mut BytesMut) { if self.b > 0x1ff_ffff_ffff_ffff_u64 { panic!( - "Invalid value for {}::{}: {} > {}", "Foo", "b", self.b, - 0x1ff_ffff_ffff_ffff_u64 + "Invalid value for {}::{}: {} > {}", + "Foo", "b", self.b, 0x1ff_ffff_ffff_ffff_u64 ); } let value = (7 as u64) | (self.b << 7); diff --git a/tools/pdl/tests/generated/packet_decl_grand_children_big_endian.rs b/tools/pdl/tests/generated/packet_decl_grand_children_big_endian.rs index 33432f3e01d..96bca77d887 100644 --- a/tools/pdl/tests/generated/packet_decl_grand_children_big_endian.rs +++ b/tools/pdl/tests/generated/packet_decl_grand_children_big_endian.rs @@ -1,16 +1,18 @@ -#![rustfmt::skip] -/// @generated rust packets from test. +// @generated rust packets from test + use bytes::{Buf, BufMut, Bytes, BytesMut}; -use std::convert::{TryFrom, TryInto}; use std::cell::Cell; +use std::convert::{TryFrom, TryInto}; use std::fmt; use std::sync::Arc; use thiserror::Error; + type Result = std::result::Result; -/// Private prevents users from creating arbitrary scalar values -/// in situations where the value needs to be validated. -/// Users can freely deref the value, but only the backend -/// may create it. + +#[doc = r" Private prevents users from creating arbitrary scalar values"] +#[doc = r" in situations where the value needs to be validated."] +#[doc = r" Users can freely deref the value, but only the backend"] +#[doc = r" may create it."] #[derive(Debug, Clone, Copy, Hash, PartialEq, Eq, PartialOrd, Ord)] pub struct Private(T); impl std::ops::Deref for Private { @@ -19,6 +21,7 @@ impl std::ops::Deref for Private { &self.0 } } + #[derive(Debug, Error)] pub enum Error { #[error("Packet parsing failed")] @@ -29,9 +32,7 @@ pub enum Error { InvalidFixedValue { expected: u64, actual: u64 }, #[error("when parsing {obj} needed length of {wanted} but got {got}")] InvalidLengthError { obj: String, wanted: usize, got: usize }, - #[error( - "array size ({array} bytes) is not a multiple of the element size ({element} bytes)" - )] + #[error("array size ({array} bytes) is not a multiple of the element size ({element} bytes)")] InvalidArraySize { array: usize, element: usize }, #[error("Due to size restrictions a struct could not be parsed.")] ImpossibleStructError, @@ -40,10 +41,12 @@ pub enum Error { #[error("expected child {expected}, got {actual}")] InvalidChildError { expected: &'static str, actual: String }, } + pub trait Packet { fn to_bytes(self) -> Bytes; fn to_vec(self) -> Vec; } + #[repr(u64)] #[derive(Debug, Clone, Copy, Hash, Eq, PartialEq)] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] @@ -95,6 +98,7 @@ impl From for u64 { u16::from(value) as Self } } + #[derive(Debug, Clone, PartialEq, Eq)] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] pub enum ParentDataChild { @@ -157,13 +161,14 @@ impl ParentData { got: bytes.get().remaining(), }); } - let foo = Enum16::try_from(bytes.get_mut().get_u16()) - .map_err(|_| Error::InvalidEnumValueError { + let foo = Enum16::try_from(bytes.get_mut().get_u16()).map_err(|_| { + Error::InvalidEnumValueError { obj: "Parent".to_string(), field: "foo".to_string(), value: bytes.get_mut().get_u16() as u64, type_: "Enum16".to_string(), - })?; + } + })?; if bytes.get().remaining() < 2 { return Err(Error::InvalidLengthError { obj: "Parent".to_string(), @@ -171,13 +176,14 @@ impl ParentData { got: bytes.get().remaining(), }); } - let bar = Enum16::try_from(bytes.get_mut().get_u16()) - .map_err(|_| Error::InvalidEnumValueError { + let bar = Enum16::try_from(bytes.get_mut().get_u16()).map_err(|_| { + Error::InvalidEnumValueError { obj: "Parent".to_string(), field: "bar".to_string(), value: bytes.get_mut().get_u16() as u64, type_: "Enum16".to_string(), - })?; + } + })?; if bytes.get().remaining() < 2 { return Err(Error::InvalidLengthError { obj: "Parent".to_string(), @@ -185,13 +191,14 @@ impl ParentData { got: bytes.get().remaining(), }); } - let baz = Enum16::try_from(bytes.get_mut().get_u16()) - .map_err(|_| Error::InvalidEnumValueError { + let baz = Enum16::try_from(bytes.get_mut().get_u16()).map_err(|_| { + Error::InvalidEnumValueError { obj: "Parent".to_string(), field: "baz".to_string(), value: bytes.get_mut().get_u16() as u64, type_: "Enum16".to_string(), - })?; + } + })?; if bytes.get().remaining() < 1 { return Err(Error::InvalidLengthError { obj: "Parent".to_string(), @@ -215,9 +222,7 @@ impl ParentData { let child_data = ChildData::parse_inner(&mut cell, bar, baz)?; ParentDataChild::Child(Arc::new(child_data)) } - _ if !payload.is_empty() => { - ParentDataChild::Payload(Bytes::copy_from_slice(payload)) - } + _ if !payload.is_empty() => ParentDataChild::Payload(Bytes::copy_from_slice(payload)), _ => ParentDataChild::None, }; Ok(Self { foo, bar, baz, child }) @@ -228,8 +233,11 @@ impl ParentData { buffer.put_u16(u16::from(self.baz)); if self.child.get_total_size() > 0xff { panic!( - "Invalid length for {}::{}: {} > {}", "Parent", "_payload_", self.child - .get_total_size(), 0xff + "Invalid length for {}::{}: {} > {}", + "Parent", + "_payload_", + self.child.get_total_size(), + 0xff ); } buffer.put_u8(self.child.get_total_size() as u8); @@ -323,6 +331,7 @@ impl From for Parent { builder.build().into() } } + #[derive(Debug, Clone, PartialEq, Eq)] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] pub enum ChildDataChild { @@ -377,11 +386,7 @@ impl ChildData { let packet = Self::parse_inner(&mut cell, bar, baz)?; Ok(packet) } - fn parse_inner( - mut bytes: &mut Cell<&[u8]>, - bar: Enum16, - baz: Enum16, - ) -> Result { + fn parse_inner(mut bytes: &mut Cell<&[u8]>, bar: Enum16, baz: Enum16) -> Result { if bytes.get().remaining() < 2 { return Err(Error::InvalidLengthError { obj: "Child".to_string(), @@ -389,13 +394,14 @@ impl ChildData { got: bytes.get().remaining(), }); } - let quux = Enum16::try_from(bytes.get_mut().get_u16()) - .map_err(|_| Error::InvalidEnumValueError { + let quux = Enum16::try_from(bytes.get_mut().get_u16()).map_err(|_| { + Error::InvalidEnumValueError { obj: "Child".to_string(), field: "quux".to_string(), value: bytes.get_mut().get_u16() as u64, type_: "Enum16".to_string(), - })?; + } + })?; let payload = bytes.get(); bytes.get_mut().advance(payload.len()); let child = match (bar, quux) { @@ -404,9 +410,7 @@ impl ChildData { let child_data = GrandChildData::parse_inner(&mut cell, baz)?; ChildDataChild::GrandChild(Arc::new(child_data)) } - _ if !payload.is_empty() => { - ChildDataChild::Payload(Bytes::copy_from_slice(payload)) - } + _ if !payload.is_empty() => ChildDataChild::Payload(Bytes::copy_from_slice(payload)), _ => ChildDataChild::None, }; Ok(Self { quux, child }) @@ -482,8 +486,8 @@ impl Child { _ => { return Err(Error::InvalidChildError { expected: stringify!(ParentDataChild::Child), - actual: format!("{:?}", & parent.child), - }); + actual: format!("{:?}", &parent.child), + }) } }; Ok(Self { parent, child }) @@ -535,6 +539,7 @@ impl From for Child { builder.build().into() } } + #[derive(Debug, Clone, PartialEq, Eq)] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] pub enum GrandChildDataChild { @@ -667,13 +672,9 @@ impl GrandChild { pub fn specialize(&self) -> GrandChildChild { match &self.grandchild.child { GrandChildDataChild::GrandGrandChild(_) => { - GrandChildChild::GrandGrandChild( - GrandGrandChild::new(self.parent.clone()).unwrap(), - ) - } - GrandChildDataChild::Payload(payload) => { - GrandChildChild::Payload(payload.clone()) + GrandChildChild::GrandGrandChild(GrandGrandChild::new(self.parent.clone()).unwrap()) } + GrandChildDataChild::Payload(payload) => GrandChildChild::Payload(payload.clone()), GrandChildDataChild::None => GrandChildChild::None, } } @@ -683,8 +684,8 @@ impl GrandChild { _ => { return Err(Error::InvalidChildError { expected: stringify!(ParentDataChild::Child), - actual: format!("{:?}", & parent.child), - }); + actual: format!("{:?}", &parent.child), + }) } }; let grandchild = match &child.child { @@ -692,8 +693,8 @@ impl GrandChild { _ => { return Err(Error::InvalidChildError { expected: stringify!(ChildDataChild::GrandChild), - actual: format!("{:?}", & child.child), - }); + actual: format!("{:?}", &child.child), + }) } }; Ok(Self { parent, child, grandchild }) @@ -725,10 +726,8 @@ impl GrandChildBuilder { Some(bytes) => GrandChildDataChild::Payload(bytes), }, }); - let child = Arc::new(ChildData { - quux: Enum16::A, - child: ChildDataChild::GrandChild(grandchild), - }); + let child = + Arc::new(ChildData { quux: Enum16::A, child: ChildDataChild::GrandChild(grandchild) }); let parent = Arc::new(ParentData { bar: Enum16::A, baz: self.baz, @@ -753,6 +752,7 @@ impl From for GrandChild { builder.build().into() } } + #[derive(Debug, Clone, PartialEq, Eq)] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] pub enum GrandGrandChildDataChild { @@ -893,8 +893,8 @@ impl GrandGrandChild { _ => { return Err(Error::InvalidChildError { expected: stringify!(ParentDataChild::Child), - actual: format!("{:?}", & parent.child), - }); + actual: format!("{:?}", &parent.child), + }) } }; let grandchild = match &child.child { @@ -902,8 +902,8 @@ impl GrandGrandChild { _ => { return Err(Error::InvalidChildError { expected: stringify!(ChildDataChild::GrandChild), - actual: format!("{:?}", & child.child), - }); + actual: format!("{:?}", &child.child), + }) } }; let grandgrandchild = match &grandchild.child { @@ -911,16 +911,11 @@ impl GrandGrandChild { _ => { return Err(Error::InvalidChildError { expected: stringify!(GrandChildDataChild::GrandGrandChild), - actual: format!("{:?}", & grandchild.child), - }); + actual: format!("{:?}", &grandchild.child), + }) } }; - Ok(Self { - parent, - child, - grandchild, - grandgrandchild, - }) + Ok(Self { parent, child, grandchild, grandgrandchild }) } pub fn get_bar(&self) -> Enum16 { self.parent.as_ref().bar @@ -958,10 +953,8 @@ impl GrandGrandChildBuilder { let grandchild = Arc::new(GrandChildData { child: GrandChildDataChild::GrandGrandChild(grandgrandchild), }); - let child = Arc::new(ChildData { - quux: Enum16::A, - child: ChildDataChild::GrandChild(grandchild), - }); + let child = + Arc::new(ChildData { quux: Enum16::A, child: ChildDataChild::GrandChild(grandchild) }); let parent = Arc::new(ParentData { bar: Enum16::A, baz: Enum16::A, diff --git a/tools/pdl/tests/generated/packet_decl_grand_children_little_endian.rs b/tools/pdl/tests/generated/packet_decl_grand_children_little_endian.rs index c223814d2b3..16af6fcfbab 100644 --- a/tools/pdl/tests/generated/packet_decl_grand_children_little_endian.rs +++ b/tools/pdl/tests/generated/packet_decl_grand_children_little_endian.rs @@ -1,16 +1,18 @@ -#![rustfmt::skip] -/// @generated rust packets from test. +// @generated rust packets from test + use bytes::{Buf, BufMut, Bytes, BytesMut}; -use std::convert::{TryFrom, TryInto}; use std::cell::Cell; +use std::convert::{TryFrom, TryInto}; use std::fmt; use std::sync::Arc; use thiserror::Error; + type Result = std::result::Result; -/// Private prevents users from creating arbitrary scalar values -/// in situations where the value needs to be validated. -/// Users can freely deref the value, but only the backend -/// may create it. + +#[doc = r" Private prevents users from creating arbitrary scalar values"] +#[doc = r" in situations where the value needs to be validated."] +#[doc = r" Users can freely deref the value, but only the backend"] +#[doc = r" may create it."] #[derive(Debug, Clone, Copy, Hash, PartialEq, Eq, PartialOrd, Ord)] pub struct Private(T); impl std::ops::Deref for Private { @@ -19,6 +21,7 @@ impl std::ops::Deref for Private { &self.0 } } + #[derive(Debug, Error)] pub enum Error { #[error("Packet parsing failed")] @@ -29,9 +32,7 @@ pub enum Error { InvalidFixedValue { expected: u64, actual: u64 }, #[error("when parsing {obj} needed length of {wanted} but got {got}")] InvalidLengthError { obj: String, wanted: usize, got: usize }, - #[error( - "array size ({array} bytes) is not a multiple of the element size ({element} bytes)" - )] + #[error("array size ({array} bytes) is not a multiple of the element size ({element} bytes)")] InvalidArraySize { array: usize, element: usize }, #[error("Due to size restrictions a struct could not be parsed.")] ImpossibleStructError, @@ -40,10 +41,12 @@ pub enum Error { #[error("expected child {expected}, got {actual}")] InvalidChildError { expected: &'static str, actual: String }, } + pub trait Packet { fn to_bytes(self) -> Bytes; fn to_vec(self) -> Vec; } + #[repr(u64)] #[derive(Debug, Clone, Copy, Hash, Eq, PartialEq)] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] @@ -95,6 +98,7 @@ impl From for u64 { u16::from(value) as Self } } + #[derive(Debug, Clone, PartialEq, Eq)] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] pub enum ParentDataChild { @@ -157,13 +161,14 @@ impl ParentData { got: bytes.get().remaining(), }); } - let foo = Enum16::try_from(bytes.get_mut().get_u16_le()) - .map_err(|_| Error::InvalidEnumValueError { + let foo = Enum16::try_from(bytes.get_mut().get_u16_le()).map_err(|_| { + Error::InvalidEnumValueError { obj: "Parent".to_string(), field: "foo".to_string(), value: bytes.get_mut().get_u16_le() as u64, type_: "Enum16".to_string(), - })?; + } + })?; if bytes.get().remaining() < 2 { return Err(Error::InvalidLengthError { obj: "Parent".to_string(), @@ -171,13 +176,14 @@ impl ParentData { got: bytes.get().remaining(), }); } - let bar = Enum16::try_from(bytes.get_mut().get_u16_le()) - .map_err(|_| Error::InvalidEnumValueError { + let bar = Enum16::try_from(bytes.get_mut().get_u16_le()).map_err(|_| { + Error::InvalidEnumValueError { obj: "Parent".to_string(), field: "bar".to_string(), value: bytes.get_mut().get_u16_le() as u64, type_: "Enum16".to_string(), - })?; + } + })?; if bytes.get().remaining() < 2 { return Err(Error::InvalidLengthError { obj: "Parent".to_string(), @@ -185,13 +191,14 @@ impl ParentData { got: bytes.get().remaining(), }); } - let baz = Enum16::try_from(bytes.get_mut().get_u16_le()) - .map_err(|_| Error::InvalidEnumValueError { + let baz = Enum16::try_from(bytes.get_mut().get_u16_le()).map_err(|_| { + Error::InvalidEnumValueError { obj: "Parent".to_string(), field: "baz".to_string(), value: bytes.get_mut().get_u16_le() as u64, type_: "Enum16".to_string(), - })?; + } + })?; if bytes.get().remaining() < 1 { return Err(Error::InvalidLengthError { obj: "Parent".to_string(), @@ -215,9 +222,7 @@ impl ParentData { let child_data = ChildData::parse_inner(&mut cell, bar, baz)?; ParentDataChild::Child(Arc::new(child_data)) } - _ if !payload.is_empty() => { - ParentDataChild::Payload(Bytes::copy_from_slice(payload)) - } + _ if !payload.is_empty() => ParentDataChild::Payload(Bytes::copy_from_slice(payload)), _ => ParentDataChild::None, }; Ok(Self { foo, bar, baz, child }) @@ -228,8 +233,11 @@ impl ParentData { buffer.put_u16_le(u16::from(self.baz)); if self.child.get_total_size() > 0xff { panic!( - "Invalid length for {}::{}: {} > {}", "Parent", "_payload_", self.child - .get_total_size(), 0xff + "Invalid length for {}::{}: {} > {}", + "Parent", + "_payload_", + self.child.get_total_size(), + 0xff ); } buffer.put_u8(self.child.get_total_size() as u8); @@ -323,6 +331,7 @@ impl From for Parent { builder.build().into() } } + #[derive(Debug, Clone, PartialEq, Eq)] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] pub enum ChildDataChild { @@ -377,11 +386,7 @@ impl ChildData { let packet = Self::parse_inner(&mut cell, bar, baz)?; Ok(packet) } - fn parse_inner( - mut bytes: &mut Cell<&[u8]>, - bar: Enum16, - baz: Enum16, - ) -> Result { + fn parse_inner(mut bytes: &mut Cell<&[u8]>, bar: Enum16, baz: Enum16) -> Result { if bytes.get().remaining() < 2 { return Err(Error::InvalidLengthError { obj: "Child".to_string(), @@ -389,13 +394,14 @@ impl ChildData { got: bytes.get().remaining(), }); } - let quux = Enum16::try_from(bytes.get_mut().get_u16_le()) - .map_err(|_| Error::InvalidEnumValueError { + let quux = Enum16::try_from(bytes.get_mut().get_u16_le()).map_err(|_| { + Error::InvalidEnumValueError { obj: "Child".to_string(), field: "quux".to_string(), value: bytes.get_mut().get_u16_le() as u64, type_: "Enum16".to_string(), - })?; + } + })?; let payload = bytes.get(); bytes.get_mut().advance(payload.len()); let child = match (bar, quux) { @@ -404,9 +410,7 @@ impl ChildData { let child_data = GrandChildData::parse_inner(&mut cell, baz)?; ChildDataChild::GrandChild(Arc::new(child_data)) } - _ if !payload.is_empty() => { - ChildDataChild::Payload(Bytes::copy_from_slice(payload)) - } + _ if !payload.is_empty() => ChildDataChild::Payload(Bytes::copy_from_slice(payload)), _ => ChildDataChild::None, }; Ok(Self { quux, child }) @@ -482,8 +486,8 @@ impl Child { _ => { return Err(Error::InvalidChildError { expected: stringify!(ParentDataChild::Child), - actual: format!("{:?}", & parent.child), - }); + actual: format!("{:?}", &parent.child), + }) } }; Ok(Self { parent, child }) @@ -535,6 +539,7 @@ impl From for Child { builder.build().into() } } + #[derive(Debug, Clone, PartialEq, Eq)] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] pub enum GrandChildDataChild { @@ -667,13 +672,9 @@ impl GrandChild { pub fn specialize(&self) -> GrandChildChild { match &self.grandchild.child { GrandChildDataChild::GrandGrandChild(_) => { - GrandChildChild::GrandGrandChild( - GrandGrandChild::new(self.parent.clone()).unwrap(), - ) - } - GrandChildDataChild::Payload(payload) => { - GrandChildChild::Payload(payload.clone()) + GrandChildChild::GrandGrandChild(GrandGrandChild::new(self.parent.clone()).unwrap()) } + GrandChildDataChild::Payload(payload) => GrandChildChild::Payload(payload.clone()), GrandChildDataChild::None => GrandChildChild::None, } } @@ -683,8 +684,8 @@ impl GrandChild { _ => { return Err(Error::InvalidChildError { expected: stringify!(ParentDataChild::Child), - actual: format!("{:?}", & parent.child), - }); + actual: format!("{:?}", &parent.child), + }) } }; let grandchild = match &child.child { @@ -692,8 +693,8 @@ impl GrandChild { _ => { return Err(Error::InvalidChildError { expected: stringify!(ChildDataChild::GrandChild), - actual: format!("{:?}", & child.child), - }); + actual: format!("{:?}", &child.child), + }) } }; Ok(Self { parent, child, grandchild }) @@ -725,10 +726,8 @@ impl GrandChildBuilder { Some(bytes) => GrandChildDataChild::Payload(bytes), }, }); - let child = Arc::new(ChildData { - quux: Enum16::A, - child: ChildDataChild::GrandChild(grandchild), - }); + let child = + Arc::new(ChildData { quux: Enum16::A, child: ChildDataChild::GrandChild(grandchild) }); let parent = Arc::new(ParentData { bar: Enum16::A, baz: self.baz, @@ -753,6 +752,7 @@ impl From for GrandChild { builder.build().into() } } + #[derive(Debug, Clone, PartialEq, Eq)] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] pub enum GrandGrandChildDataChild { @@ -893,8 +893,8 @@ impl GrandGrandChild { _ => { return Err(Error::InvalidChildError { expected: stringify!(ParentDataChild::Child), - actual: format!("{:?}", & parent.child), - }); + actual: format!("{:?}", &parent.child), + }) } }; let grandchild = match &child.child { @@ -902,8 +902,8 @@ impl GrandGrandChild { _ => { return Err(Error::InvalidChildError { expected: stringify!(ChildDataChild::GrandChild), - actual: format!("{:?}", & child.child), - }); + actual: format!("{:?}", &child.child), + }) } }; let grandgrandchild = match &grandchild.child { @@ -911,16 +911,11 @@ impl GrandGrandChild { _ => { return Err(Error::InvalidChildError { expected: stringify!(GrandChildDataChild::GrandGrandChild), - actual: format!("{:?}", & grandchild.child), - }); + actual: format!("{:?}", &grandchild.child), + }) } }; - Ok(Self { - parent, - child, - grandchild, - grandgrandchild, - }) + Ok(Self { parent, child, grandchild, grandgrandchild }) } pub fn get_bar(&self) -> Enum16 { self.parent.as_ref().bar @@ -958,10 +953,8 @@ impl GrandGrandChildBuilder { let grandchild = Arc::new(GrandChildData { child: GrandChildDataChild::GrandGrandChild(grandgrandchild), }); - let child = Arc::new(ChildData { - quux: Enum16::A, - child: ChildDataChild::GrandChild(grandchild), - }); + let child = + Arc::new(ChildData { quux: Enum16::A, child: ChildDataChild::GrandChild(grandchild) }); let parent = Arc::new(ParentData { bar: Enum16::A, baz: Enum16::A, diff --git a/tools/pdl/tests/generated/packet_decl_mask_scalar_value_big_endian.rs b/tools/pdl/tests/generated/packet_decl_mask_scalar_value_big_endian.rs index 581542d44e0..6879967e728 100644 --- a/tools/pdl/tests/generated/packet_decl_mask_scalar_value_big_endian.rs +++ b/tools/pdl/tests/generated/packet_decl_mask_scalar_value_big_endian.rs @@ -1,16 +1,18 @@ -#![rustfmt::skip] -/// @generated rust packets from test. +// @generated rust packets from test + use bytes::{Buf, BufMut, Bytes, BytesMut}; -use std::convert::{TryFrom, TryInto}; use std::cell::Cell; +use std::convert::{TryFrom, TryInto}; use std::fmt; use std::sync::Arc; use thiserror::Error; + type Result = std::result::Result; -/// Private prevents users from creating arbitrary scalar values -/// in situations where the value needs to be validated. -/// Users can freely deref the value, but only the backend -/// may create it. + +#[doc = r" Private prevents users from creating arbitrary scalar values"] +#[doc = r" in situations where the value needs to be validated."] +#[doc = r" Users can freely deref the value, but only the backend"] +#[doc = r" may create it."] #[derive(Debug, Clone, Copy, Hash, PartialEq, Eq, PartialOrd, Ord)] pub struct Private(T); impl std::ops::Deref for Private { @@ -19,6 +21,7 @@ impl std::ops::Deref for Private { &self.0 } } + #[derive(Debug, Error)] pub enum Error { #[error("Packet parsing failed")] @@ -29,9 +32,7 @@ pub enum Error { InvalidFixedValue { expected: u64, actual: u64 }, #[error("when parsing {obj} needed length of {wanted} but got {got}")] InvalidLengthError { obj: String, wanted: usize, got: usize }, - #[error( - "array size ({array} bytes) is not a multiple of the element size ({element} bytes)" - )] + #[error("array size ({array} bytes) is not a multiple of the element size ({element} bytes)")] InvalidArraySize { array: usize, element: usize }, #[error("Due to size restrictions a struct could not be parsed.")] ImpossibleStructError, @@ -40,10 +41,12 @@ pub enum Error { #[error("expected child {expected}, got {actual}")] InvalidChildError { expected: &'static str, actual: String }, } + pub trait Packet { fn to_bytes(self) -> Bytes; fn to_vec(self) -> Vec; } + #[derive(Debug, Clone, PartialEq, Eq)] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] pub struct FooData { @@ -158,11 +161,7 @@ impl Foo { } impl FooBuilder { pub fn build(self) -> Foo { - let foo = Arc::new(FooData { - a: self.a, - b: self.b, - c: self.c, - }); + let foo = Arc::new(FooData { a: self.a, b: self.b, c: self.c }); Foo::new(foo).unwrap() } } diff --git a/tools/pdl/tests/generated/packet_decl_mask_scalar_value_little_endian.rs b/tools/pdl/tests/generated/packet_decl_mask_scalar_value_little_endian.rs index 9bce70a0522..b4c5b3c3579 100644 --- a/tools/pdl/tests/generated/packet_decl_mask_scalar_value_little_endian.rs +++ b/tools/pdl/tests/generated/packet_decl_mask_scalar_value_little_endian.rs @@ -1,16 +1,18 @@ -#![rustfmt::skip] -/// @generated rust packets from test. +// @generated rust packets from test + use bytes::{Buf, BufMut, Bytes, BytesMut}; -use std::convert::{TryFrom, TryInto}; use std::cell::Cell; +use std::convert::{TryFrom, TryInto}; use std::fmt; use std::sync::Arc; use thiserror::Error; + type Result = std::result::Result; -/// Private prevents users from creating arbitrary scalar values -/// in situations where the value needs to be validated. -/// Users can freely deref the value, but only the backend -/// may create it. + +#[doc = r" Private prevents users from creating arbitrary scalar values"] +#[doc = r" in situations where the value needs to be validated."] +#[doc = r" Users can freely deref the value, but only the backend"] +#[doc = r" may create it."] #[derive(Debug, Clone, Copy, Hash, PartialEq, Eq, PartialOrd, Ord)] pub struct Private(T); impl std::ops::Deref for Private { @@ -19,6 +21,7 @@ impl std::ops::Deref for Private { &self.0 } } + #[derive(Debug, Error)] pub enum Error { #[error("Packet parsing failed")] @@ -29,9 +32,7 @@ pub enum Error { InvalidFixedValue { expected: u64, actual: u64 }, #[error("when parsing {obj} needed length of {wanted} but got {got}")] InvalidLengthError { obj: String, wanted: usize, got: usize }, - #[error( - "array size ({array} bytes) is not a multiple of the element size ({element} bytes)" - )] + #[error("array size ({array} bytes) is not a multiple of the element size ({element} bytes)")] InvalidArraySize { array: usize, element: usize }, #[error("Due to size restrictions a struct could not be parsed.")] ImpossibleStructError, @@ -40,10 +41,12 @@ pub enum Error { #[error("expected child {expected}, got {actual}")] InvalidChildError { expected: &'static str, actual: String }, } + pub trait Packet { fn to_bytes(self) -> Bytes; fn to_vec(self) -> Vec; } + #[derive(Debug, Clone, PartialEq, Eq)] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] pub struct FooData { @@ -158,11 +161,7 @@ impl Foo { } impl FooBuilder { pub fn build(self) -> Foo { - let foo = Arc::new(FooData { - a: self.a, - b: self.b, - c: self.c, - }); + let foo = Arc::new(FooData { a: self.a, b: self.b, c: self.c }); Foo::new(foo).unwrap() } } diff --git a/tools/pdl/tests/generated/packet_decl_mixed_scalars_enums_big_endian.rs b/tools/pdl/tests/generated/packet_decl_mixed_scalars_enums_big_endian.rs index 87d0ecf28ab..49982a0a4a4 100644 --- a/tools/pdl/tests/generated/packet_decl_mixed_scalars_enums_big_endian.rs +++ b/tools/pdl/tests/generated/packet_decl_mixed_scalars_enums_big_endian.rs @@ -1,16 +1,18 @@ -#![rustfmt::skip] -/// @generated rust packets from test. +// @generated rust packets from test + use bytes::{Buf, BufMut, Bytes, BytesMut}; -use std::convert::{TryFrom, TryInto}; use std::cell::Cell; +use std::convert::{TryFrom, TryInto}; use std::fmt; use std::sync::Arc; use thiserror::Error; + type Result = std::result::Result; -/// Private prevents users from creating arbitrary scalar values -/// in situations where the value needs to be validated. -/// Users can freely deref the value, but only the backend -/// may create it. + +#[doc = r" Private prevents users from creating arbitrary scalar values"] +#[doc = r" in situations where the value needs to be validated."] +#[doc = r" Users can freely deref the value, but only the backend"] +#[doc = r" may create it."] #[derive(Debug, Clone, Copy, Hash, PartialEq, Eq, PartialOrd, Ord)] pub struct Private(T); impl std::ops::Deref for Private { @@ -19,6 +21,7 @@ impl std::ops::Deref for Private { &self.0 } } + #[derive(Debug, Error)] pub enum Error { #[error("Packet parsing failed")] @@ -29,9 +32,7 @@ pub enum Error { InvalidFixedValue { expected: u64, actual: u64 }, #[error("when parsing {obj} needed length of {wanted} but got {got}")] InvalidLengthError { obj: String, wanted: usize, got: usize }, - #[error( - "array size ({array} bytes) is not a multiple of the element size ({element} bytes)" - )] + #[error("array size ({array} bytes) is not a multiple of the element size ({element} bytes)")] InvalidArraySize { array: usize, element: usize }, #[error("Due to size restrictions a struct could not be parsed.")] ImpossibleStructError, @@ -40,10 +41,12 @@ pub enum Error { #[error("expected child {expected}, got {actual}")] InvalidChildError { expected: &'static str, actual: String }, } + pub trait Packet { fn to_bytes(self) -> Bytes; fn to_vec(self) -> Vec; } + #[repr(u64)] #[derive(Debug, Clone, Copy, Hash, Eq, PartialEq)] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] @@ -110,6 +113,7 @@ impl From for u64 { u8::from(value) as Self } } + #[repr(u64)] #[derive(Debug, Clone, Copy, Hash, Eq, PartialEq)] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] @@ -166,6 +170,7 @@ impl From for u64 { u16::from(value) as Self } } + #[derive(Debug, Clone, PartialEq, Eq)] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] pub struct FooData { @@ -206,21 +211,22 @@ impl FooData { }); } let chunk = bytes.get_mut().get_uint(3) as u32; - let x = Enum7::try_from((chunk & 0x7f) as u8) - .map_err(|_| Error::InvalidEnumValueError { + let x = + Enum7::try_from((chunk & 0x7f) as u8).map_err(|_| Error::InvalidEnumValueError { obj: "Foo".to_string(), field: "x".to_string(), value: (chunk & 0x7f) as u8 as u64, type_: "Enum7".to_string(), })?; let y = ((chunk >> 7) & 0x1f) as u8; - let z = Enum9::try_from(((chunk >> 12) & 0x1ff) as u16) - .map_err(|_| Error::InvalidEnumValueError { + let z = Enum9::try_from(((chunk >> 12) & 0x1ff) as u16).map_err(|_| { + Error::InvalidEnumValueError { obj: "Foo".to_string(), field: "z".to_string(), value: ((chunk >> 12) & 0x1ff) as u16 as u64, type_: "Enum9".to_string(), - })?; + } + })?; let w = ((chunk >> 21) & 0x7) as u8; Ok(Self { x, y, z, w }) } @@ -231,8 +237,10 @@ impl FooData { if self.w > 0x7 { panic!("Invalid value for {}::{}: {} > {}", "Foo", "w", self.w, 0x7); } - let value = (u8::from(self.x) as u32) | ((self.y as u32) << 7) - | ((u16::from(self.z) as u32) << 12) | ((self.w as u32) << 21); + let value = (u8::from(self.x) as u32) + | ((self.y as u32) << 7) + | ((u16::from(self.z) as u32) << 12) + | ((self.w as u32) << 21); buffer.put_uint(value as u64, 3); } fn get_total_size(&self) -> usize { @@ -296,12 +304,7 @@ impl Foo { } impl FooBuilder { pub fn build(self) -> Foo { - let foo = Arc::new(FooData { - w: self.w, - x: self.x, - y: self.y, - z: self.z, - }); + let foo = Arc::new(FooData { w: self.w, x: self.x, y: self.y, z: self.z }); Foo::new(foo).unwrap() } } diff --git a/tools/pdl/tests/generated/packet_decl_mixed_scalars_enums_little_endian.rs b/tools/pdl/tests/generated/packet_decl_mixed_scalars_enums_little_endian.rs index 85297cc586e..0ca860b8076 100644 --- a/tools/pdl/tests/generated/packet_decl_mixed_scalars_enums_little_endian.rs +++ b/tools/pdl/tests/generated/packet_decl_mixed_scalars_enums_little_endian.rs @@ -1,16 +1,18 @@ -#![rustfmt::skip] -/// @generated rust packets from test. +// @generated rust packets from test + use bytes::{Buf, BufMut, Bytes, BytesMut}; -use std::convert::{TryFrom, TryInto}; use std::cell::Cell; +use std::convert::{TryFrom, TryInto}; use std::fmt; use std::sync::Arc; use thiserror::Error; + type Result = std::result::Result; -/// Private prevents users from creating arbitrary scalar values -/// in situations where the value needs to be validated. -/// Users can freely deref the value, but only the backend -/// may create it. + +#[doc = r" Private prevents users from creating arbitrary scalar values"] +#[doc = r" in situations where the value needs to be validated."] +#[doc = r" Users can freely deref the value, but only the backend"] +#[doc = r" may create it."] #[derive(Debug, Clone, Copy, Hash, PartialEq, Eq, PartialOrd, Ord)] pub struct Private(T); impl std::ops::Deref for Private { @@ -19,6 +21,7 @@ impl std::ops::Deref for Private { &self.0 } } + #[derive(Debug, Error)] pub enum Error { #[error("Packet parsing failed")] @@ -29,9 +32,7 @@ pub enum Error { InvalidFixedValue { expected: u64, actual: u64 }, #[error("when parsing {obj} needed length of {wanted} but got {got}")] InvalidLengthError { obj: String, wanted: usize, got: usize }, - #[error( - "array size ({array} bytes) is not a multiple of the element size ({element} bytes)" - )] + #[error("array size ({array} bytes) is not a multiple of the element size ({element} bytes)")] InvalidArraySize { array: usize, element: usize }, #[error("Due to size restrictions a struct could not be parsed.")] ImpossibleStructError, @@ -40,10 +41,12 @@ pub enum Error { #[error("expected child {expected}, got {actual}")] InvalidChildError { expected: &'static str, actual: String }, } + pub trait Packet { fn to_bytes(self) -> Bytes; fn to_vec(self) -> Vec; } + #[repr(u64)] #[derive(Debug, Clone, Copy, Hash, Eq, PartialEq)] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] @@ -110,6 +113,7 @@ impl From for u64 { u8::from(value) as Self } } + #[repr(u64)] #[derive(Debug, Clone, Copy, Hash, Eq, PartialEq)] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] @@ -166,6 +170,7 @@ impl From for u64 { u16::from(value) as Self } } + #[derive(Debug, Clone, PartialEq, Eq)] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] pub struct FooData { @@ -206,21 +211,22 @@ impl FooData { }); } let chunk = bytes.get_mut().get_uint_le(3) as u32; - let x = Enum7::try_from((chunk & 0x7f) as u8) - .map_err(|_| Error::InvalidEnumValueError { + let x = + Enum7::try_from((chunk & 0x7f) as u8).map_err(|_| Error::InvalidEnumValueError { obj: "Foo".to_string(), field: "x".to_string(), value: (chunk & 0x7f) as u8 as u64, type_: "Enum7".to_string(), })?; let y = ((chunk >> 7) & 0x1f) as u8; - let z = Enum9::try_from(((chunk >> 12) & 0x1ff) as u16) - .map_err(|_| Error::InvalidEnumValueError { + let z = Enum9::try_from(((chunk >> 12) & 0x1ff) as u16).map_err(|_| { + Error::InvalidEnumValueError { obj: "Foo".to_string(), field: "z".to_string(), value: ((chunk >> 12) & 0x1ff) as u16 as u64, type_: "Enum9".to_string(), - })?; + } + })?; let w = ((chunk >> 21) & 0x7) as u8; Ok(Self { x, y, z, w }) } @@ -231,8 +237,10 @@ impl FooData { if self.w > 0x7 { panic!("Invalid value for {}::{}: {} > {}", "Foo", "w", self.w, 0x7); } - let value = (u8::from(self.x) as u32) | ((self.y as u32) << 7) - | ((u16::from(self.z) as u32) << 12) | ((self.w as u32) << 21); + let value = (u8::from(self.x) as u32) + | ((self.y as u32) << 7) + | ((u16::from(self.z) as u32) << 12) + | ((self.w as u32) << 21); buffer.put_uint_le(value as u64, 3); } fn get_total_size(&self) -> usize { @@ -296,12 +304,7 @@ impl Foo { } impl FooBuilder { pub fn build(self) -> Foo { - let foo = Arc::new(FooData { - w: self.w, - x: self.x, - y: self.y, - z: self.z, - }); + let foo = Arc::new(FooData { w: self.w, x: self.x, y: self.y, z: self.z }); Foo::new(foo).unwrap() } } diff --git a/tools/pdl/tests/generated/packet_decl_payload_field_unknown_size_big_endian.rs b/tools/pdl/tests/generated/packet_decl_payload_field_unknown_size_big_endian.rs index 452c3657659..40f779a75a2 100644 --- a/tools/pdl/tests/generated/packet_decl_payload_field_unknown_size_big_endian.rs +++ b/tools/pdl/tests/generated/packet_decl_payload_field_unknown_size_big_endian.rs @@ -1,16 +1,18 @@ -#![rustfmt::skip] -/// @generated rust packets from test. +// @generated rust packets from test + use bytes::{Buf, BufMut, Bytes, BytesMut}; -use std::convert::{TryFrom, TryInto}; use std::cell::Cell; +use std::convert::{TryFrom, TryInto}; use std::fmt; use std::sync::Arc; use thiserror::Error; + type Result = std::result::Result; -/// Private prevents users from creating arbitrary scalar values -/// in situations where the value needs to be validated. -/// Users can freely deref the value, but only the backend -/// may create it. + +#[doc = r" Private prevents users from creating arbitrary scalar values"] +#[doc = r" in situations where the value needs to be validated."] +#[doc = r" Users can freely deref the value, but only the backend"] +#[doc = r" may create it."] #[derive(Debug, Clone, Copy, Hash, PartialEq, Eq, PartialOrd, Ord)] pub struct Private(T); impl std::ops::Deref for Private { @@ -19,6 +21,7 @@ impl std::ops::Deref for Private { &self.0 } } + #[derive(Debug, Error)] pub enum Error { #[error("Packet parsing failed")] @@ -29,9 +32,7 @@ pub enum Error { InvalidFixedValue { expected: u64, actual: u64 }, #[error("when parsing {obj} needed length of {wanted} but got {got}")] InvalidLengthError { obj: String, wanted: usize, got: usize }, - #[error( - "array size ({array} bytes) is not a multiple of the element size ({element} bytes)" - )] + #[error("array size ({array} bytes) is not a multiple of the element size ({element} bytes)")] InvalidArraySize { array: usize, element: usize }, #[error("Due to size restrictions a struct could not be parsed.")] ImpossibleStructError, @@ -40,10 +41,12 @@ pub enum Error { #[error("expected child {expected}, got {actual}")] InvalidChildError { expected: &'static str, actual: String }, } + pub trait Packet { fn to_bytes(self) -> Bytes; fn to_vec(self) -> Vec; } + #[derive(Debug, Clone, PartialEq, Eq)] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] pub enum FooDataChild { @@ -103,9 +106,7 @@ impl FooData { let payload = bytes.get(); bytes.get_mut().advance(payload.len()); let child = match () { - _ if !payload.is_empty() => { - FooDataChild::Payload(Bytes::copy_from_slice(payload)) - } + _ if !payload.is_empty() => FooDataChild::Payload(Bytes::copy_from_slice(payload)), _ => FooDataChild::None, }; Ok(Self { a, child }) diff --git a/tools/pdl/tests/generated/packet_decl_payload_field_unknown_size_little_endian.rs b/tools/pdl/tests/generated/packet_decl_payload_field_unknown_size_little_endian.rs index 99c06b9ccf3..36bcca6553a 100644 --- a/tools/pdl/tests/generated/packet_decl_payload_field_unknown_size_little_endian.rs +++ b/tools/pdl/tests/generated/packet_decl_payload_field_unknown_size_little_endian.rs @@ -1,16 +1,18 @@ -#![rustfmt::skip] -/// @generated rust packets from test. +// @generated rust packets from test + use bytes::{Buf, BufMut, Bytes, BytesMut}; -use std::convert::{TryFrom, TryInto}; use std::cell::Cell; +use std::convert::{TryFrom, TryInto}; use std::fmt; use std::sync::Arc; use thiserror::Error; + type Result = std::result::Result; -/// Private prevents users from creating arbitrary scalar values -/// in situations where the value needs to be validated. -/// Users can freely deref the value, but only the backend -/// may create it. + +#[doc = r" Private prevents users from creating arbitrary scalar values"] +#[doc = r" in situations where the value needs to be validated."] +#[doc = r" Users can freely deref the value, but only the backend"] +#[doc = r" may create it."] #[derive(Debug, Clone, Copy, Hash, PartialEq, Eq, PartialOrd, Ord)] pub struct Private(T); impl std::ops::Deref for Private { @@ -19,6 +21,7 @@ impl std::ops::Deref for Private { &self.0 } } + #[derive(Debug, Error)] pub enum Error { #[error("Packet parsing failed")] @@ -29,9 +32,7 @@ pub enum Error { InvalidFixedValue { expected: u64, actual: u64 }, #[error("when parsing {obj} needed length of {wanted} but got {got}")] InvalidLengthError { obj: String, wanted: usize, got: usize }, - #[error( - "array size ({array} bytes) is not a multiple of the element size ({element} bytes)" - )] + #[error("array size ({array} bytes) is not a multiple of the element size ({element} bytes)")] InvalidArraySize { array: usize, element: usize }, #[error("Due to size restrictions a struct could not be parsed.")] ImpossibleStructError, @@ -40,10 +41,12 @@ pub enum Error { #[error("expected child {expected}, got {actual}")] InvalidChildError { expected: &'static str, actual: String }, } + pub trait Packet { fn to_bytes(self) -> Bytes; fn to_vec(self) -> Vec; } + #[derive(Debug, Clone, PartialEq, Eq)] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] pub enum FooDataChild { @@ -103,9 +106,7 @@ impl FooData { let payload = bytes.get(); bytes.get_mut().advance(payload.len()); let child = match () { - _ if !payload.is_empty() => { - FooDataChild::Payload(Bytes::copy_from_slice(payload)) - } + _ if !payload.is_empty() => FooDataChild::Payload(Bytes::copy_from_slice(payload)), _ => FooDataChild::None, }; Ok(Self { a, child }) diff --git a/tools/pdl/tests/generated/packet_decl_payload_field_unknown_size_terminal_big_endian.rs b/tools/pdl/tests/generated/packet_decl_payload_field_unknown_size_terminal_big_endian.rs index f54477a12c5..fcfbb99ba8d 100644 --- a/tools/pdl/tests/generated/packet_decl_payload_field_unknown_size_terminal_big_endian.rs +++ b/tools/pdl/tests/generated/packet_decl_payload_field_unknown_size_terminal_big_endian.rs @@ -1,16 +1,18 @@ -#![rustfmt::skip] -/// @generated rust packets from test. +// @generated rust packets from test + use bytes::{Buf, BufMut, Bytes, BytesMut}; -use std::convert::{TryFrom, TryInto}; use std::cell::Cell; +use std::convert::{TryFrom, TryInto}; use std::fmt; use std::sync::Arc; use thiserror::Error; + type Result = std::result::Result; -/// Private prevents users from creating arbitrary scalar values -/// in situations where the value needs to be validated. -/// Users can freely deref the value, but only the backend -/// may create it. + +#[doc = r" Private prevents users from creating arbitrary scalar values"] +#[doc = r" in situations where the value needs to be validated."] +#[doc = r" Users can freely deref the value, but only the backend"] +#[doc = r" may create it."] #[derive(Debug, Clone, Copy, Hash, PartialEq, Eq, PartialOrd, Ord)] pub struct Private(T); impl std::ops::Deref for Private { @@ -19,6 +21,7 @@ impl std::ops::Deref for Private { &self.0 } } + #[derive(Debug, Error)] pub enum Error { #[error("Packet parsing failed")] @@ -29,9 +32,7 @@ pub enum Error { InvalidFixedValue { expected: u64, actual: u64 }, #[error("when parsing {obj} needed length of {wanted} but got {got}")] InvalidLengthError { obj: String, wanted: usize, got: usize }, - #[error( - "array size ({array} bytes) is not a multiple of the element size ({element} bytes)" - )] + #[error("array size ({array} bytes) is not a multiple of the element size ({element} bytes)")] InvalidArraySize { array: usize, element: usize }, #[error("Due to size restrictions a struct could not be parsed.")] ImpossibleStructError, @@ -40,10 +41,12 @@ pub enum Error { #[error("expected child {expected}, got {actual}")] InvalidChildError { expected: &'static str, actual: String }, } + pub trait Packet { fn to_bytes(self) -> Bytes; fn to_vec(self) -> Vec; } + #[derive(Debug, Clone, PartialEq, Eq)] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] pub enum FooDataChild { @@ -110,9 +113,7 @@ impl FooData { } let a = bytes.get_mut().get_uint(3) as u32; let child = match () { - _ if !payload.is_empty() => { - FooDataChild::Payload(Bytes::copy_from_slice(payload)) - } + _ if !payload.is_empty() => FooDataChild::Payload(Bytes::copy_from_slice(payload)), _ => FooDataChild::None, }; Ok(Self { a, child }) diff --git a/tools/pdl/tests/generated/packet_decl_payload_field_unknown_size_terminal_little_endian.rs b/tools/pdl/tests/generated/packet_decl_payload_field_unknown_size_terminal_little_endian.rs index 616c87f212a..277eddd0a1b 100644 --- a/tools/pdl/tests/generated/packet_decl_payload_field_unknown_size_terminal_little_endian.rs +++ b/tools/pdl/tests/generated/packet_decl_payload_field_unknown_size_terminal_little_endian.rs @@ -1,16 +1,18 @@ -#![rustfmt::skip] -/// @generated rust packets from test. +// @generated rust packets from test + use bytes::{Buf, BufMut, Bytes, BytesMut}; -use std::convert::{TryFrom, TryInto}; use std::cell::Cell; +use std::convert::{TryFrom, TryInto}; use std::fmt; use std::sync::Arc; use thiserror::Error; + type Result = std::result::Result; -/// Private prevents users from creating arbitrary scalar values -/// in situations where the value needs to be validated. -/// Users can freely deref the value, but only the backend -/// may create it. + +#[doc = r" Private prevents users from creating arbitrary scalar values"] +#[doc = r" in situations where the value needs to be validated."] +#[doc = r" Users can freely deref the value, but only the backend"] +#[doc = r" may create it."] #[derive(Debug, Clone, Copy, Hash, PartialEq, Eq, PartialOrd, Ord)] pub struct Private(T); impl std::ops::Deref for Private { @@ -19,6 +21,7 @@ impl std::ops::Deref for Private { &self.0 } } + #[derive(Debug, Error)] pub enum Error { #[error("Packet parsing failed")] @@ -29,9 +32,7 @@ pub enum Error { InvalidFixedValue { expected: u64, actual: u64 }, #[error("when parsing {obj} needed length of {wanted} but got {got}")] InvalidLengthError { obj: String, wanted: usize, got: usize }, - #[error( - "array size ({array} bytes) is not a multiple of the element size ({element} bytes)" - )] + #[error("array size ({array} bytes) is not a multiple of the element size ({element} bytes)")] InvalidArraySize { array: usize, element: usize }, #[error("Due to size restrictions a struct could not be parsed.")] ImpossibleStructError, @@ -40,10 +41,12 @@ pub enum Error { #[error("expected child {expected}, got {actual}")] InvalidChildError { expected: &'static str, actual: String }, } + pub trait Packet { fn to_bytes(self) -> Bytes; fn to_vec(self) -> Vec; } + #[derive(Debug, Clone, PartialEq, Eq)] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] pub enum FooDataChild { @@ -110,9 +113,7 @@ impl FooData { } let a = bytes.get_mut().get_uint_le(3) as u32; let child = match () { - _ if !payload.is_empty() => { - FooDataChild::Payload(Bytes::copy_from_slice(payload)) - } + _ if !payload.is_empty() => FooDataChild::Payload(Bytes::copy_from_slice(payload)), _ => FooDataChild::None, }; Ok(Self { a, child }) diff --git a/tools/pdl/tests/generated/packet_decl_payload_field_variable_size_big_endian.rs b/tools/pdl/tests/generated/packet_decl_payload_field_variable_size_big_endian.rs index fd2a3c1891a..3b57129bf79 100644 --- a/tools/pdl/tests/generated/packet_decl_payload_field_variable_size_big_endian.rs +++ b/tools/pdl/tests/generated/packet_decl_payload_field_variable_size_big_endian.rs @@ -1,16 +1,18 @@ -#![rustfmt::skip] -/// @generated rust packets from test. +// @generated rust packets from test + use bytes::{Buf, BufMut, Bytes, BytesMut}; -use std::convert::{TryFrom, TryInto}; use std::cell::Cell; +use std::convert::{TryFrom, TryInto}; use std::fmt; use std::sync::Arc; use thiserror::Error; + type Result = std::result::Result; -/// Private prevents users from creating arbitrary scalar values -/// in situations where the value needs to be validated. -/// Users can freely deref the value, but only the backend -/// may create it. + +#[doc = r" Private prevents users from creating arbitrary scalar values"] +#[doc = r" in situations where the value needs to be validated."] +#[doc = r" Users can freely deref the value, but only the backend"] +#[doc = r" may create it."] #[derive(Debug, Clone, Copy, Hash, PartialEq, Eq, PartialOrd, Ord)] pub struct Private(T); impl std::ops::Deref for Private { @@ -19,6 +21,7 @@ impl std::ops::Deref for Private { &self.0 } } + #[derive(Debug, Error)] pub enum Error { #[error("Packet parsing failed")] @@ -29,9 +32,7 @@ pub enum Error { InvalidFixedValue { expected: u64, actual: u64 }, #[error("when parsing {obj} needed length of {wanted} but got {got}")] InvalidLengthError { obj: String, wanted: usize, got: usize }, - #[error( - "array size ({array} bytes) is not a multiple of the element size ({element} bytes)" - )] + #[error("array size ({array} bytes) is not a multiple of the element size ({element} bytes)")] InvalidArraySize { array: usize, element: usize }, #[error("Due to size restrictions a struct could not be parsed.")] ImpossibleStructError, @@ -40,10 +41,12 @@ pub enum Error { #[error("expected child {expected}, got {actual}")] InvalidChildError { expected: &'static str, actual: String }, } + pub trait Packet { fn to_bytes(self) -> Bytes; fn to_vec(self) -> Vec; } + #[derive(Debug, Clone, PartialEq, Eq)] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] pub enum FooDataChild { @@ -128,9 +131,7 @@ impl FooData { } let b = bytes.get_mut().get_u16(); let child = match () { - _ if !payload.is_empty() => { - FooDataChild::Payload(Bytes::copy_from_slice(payload)) - } + _ if !payload.is_empty() => FooDataChild::Payload(Bytes::copy_from_slice(payload)), _ => FooDataChild::None, }; Ok(Self { a, b, child }) @@ -139,8 +140,11 @@ impl FooData { buffer.put_u8(self.a); if self.child.get_total_size() > 0xff { panic!( - "Invalid length for {}::{}: {} > {}", "Foo", "_payload_", self.child - .get_total_size(), 0xff + "Invalid length for {}::{}: {} > {}", + "Foo", + "_payload_", + self.child.get_total_size(), + 0xff ); } buffer.put_u8(self.child.get_total_size() as u8); diff --git a/tools/pdl/tests/generated/packet_decl_payload_field_variable_size_little_endian.rs b/tools/pdl/tests/generated/packet_decl_payload_field_variable_size_little_endian.rs index 65f18097ee5..d7ae81fec5a 100644 --- a/tools/pdl/tests/generated/packet_decl_payload_field_variable_size_little_endian.rs +++ b/tools/pdl/tests/generated/packet_decl_payload_field_variable_size_little_endian.rs @@ -1,16 +1,18 @@ -#![rustfmt::skip] -/// @generated rust packets from test. +// @generated rust packets from test + use bytes::{Buf, BufMut, Bytes, BytesMut}; -use std::convert::{TryFrom, TryInto}; use std::cell::Cell; +use std::convert::{TryFrom, TryInto}; use std::fmt; use std::sync::Arc; use thiserror::Error; + type Result = std::result::Result; -/// Private prevents users from creating arbitrary scalar values -/// in situations where the value needs to be validated. -/// Users can freely deref the value, but only the backend -/// may create it. + +#[doc = r" Private prevents users from creating arbitrary scalar values"] +#[doc = r" in situations where the value needs to be validated."] +#[doc = r" Users can freely deref the value, but only the backend"] +#[doc = r" may create it."] #[derive(Debug, Clone, Copy, Hash, PartialEq, Eq, PartialOrd, Ord)] pub struct Private(T); impl std::ops::Deref for Private { @@ -19,6 +21,7 @@ impl std::ops::Deref for Private { &self.0 } } + #[derive(Debug, Error)] pub enum Error { #[error("Packet parsing failed")] @@ -29,9 +32,7 @@ pub enum Error { InvalidFixedValue { expected: u64, actual: u64 }, #[error("when parsing {obj} needed length of {wanted} but got {got}")] InvalidLengthError { obj: String, wanted: usize, got: usize }, - #[error( - "array size ({array} bytes) is not a multiple of the element size ({element} bytes)" - )] + #[error("array size ({array} bytes) is not a multiple of the element size ({element} bytes)")] InvalidArraySize { array: usize, element: usize }, #[error("Due to size restrictions a struct could not be parsed.")] ImpossibleStructError, @@ -40,10 +41,12 @@ pub enum Error { #[error("expected child {expected}, got {actual}")] InvalidChildError { expected: &'static str, actual: String }, } + pub trait Packet { fn to_bytes(self) -> Bytes; fn to_vec(self) -> Vec; } + #[derive(Debug, Clone, PartialEq, Eq)] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] pub enum FooDataChild { @@ -128,9 +131,7 @@ impl FooData { } let b = bytes.get_mut().get_u16_le(); let child = match () { - _ if !payload.is_empty() => { - FooDataChild::Payload(Bytes::copy_from_slice(payload)) - } + _ if !payload.is_empty() => FooDataChild::Payload(Bytes::copy_from_slice(payload)), _ => FooDataChild::None, }; Ok(Self { a, b, child }) @@ -139,8 +140,11 @@ impl FooData { buffer.put_u8(self.a); if self.child.get_total_size() > 0xff { panic!( - "Invalid length for {}::{}: {} > {}", "Foo", "_payload_", self.child - .get_total_size(), 0xff + "Invalid length for {}::{}: {} > {}", + "Foo", + "_payload_", + self.child.get_total_size(), + 0xff ); } buffer.put_u8(self.child.get_total_size() as u8); diff --git a/tools/pdl/tests/generated/packet_decl_reserved_field_big_endian.rs b/tools/pdl/tests/generated/packet_decl_reserved_field_big_endian.rs index f03c7bfcd12..6cfe597634c 100644 --- a/tools/pdl/tests/generated/packet_decl_reserved_field_big_endian.rs +++ b/tools/pdl/tests/generated/packet_decl_reserved_field_big_endian.rs @@ -1,16 +1,18 @@ -#![rustfmt::skip] -/// @generated rust packets from test. +// @generated rust packets from test + use bytes::{Buf, BufMut, Bytes, BytesMut}; -use std::convert::{TryFrom, TryInto}; use std::cell::Cell; +use std::convert::{TryFrom, TryInto}; use std::fmt; use std::sync::Arc; use thiserror::Error; + type Result = std::result::Result; -/// Private prevents users from creating arbitrary scalar values -/// in situations where the value needs to be validated. -/// Users can freely deref the value, but only the backend -/// may create it. + +#[doc = r" Private prevents users from creating arbitrary scalar values"] +#[doc = r" in situations where the value needs to be validated."] +#[doc = r" Users can freely deref the value, but only the backend"] +#[doc = r" may create it."] #[derive(Debug, Clone, Copy, Hash, PartialEq, Eq, PartialOrd, Ord)] pub struct Private(T); impl std::ops::Deref for Private { @@ -19,6 +21,7 @@ impl std::ops::Deref for Private { &self.0 } } + #[derive(Debug, Error)] pub enum Error { #[error("Packet parsing failed")] @@ -29,9 +32,7 @@ pub enum Error { InvalidFixedValue { expected: u64, actual: u64 }, #[error("when parsing {obj} needed length of {wanted} but got {got}")] InvalidLengthError { obj: String, wanted: usize, got: usize }, - #[error( - "array size ({array} bytes) is not a multiple of the element size ({element} bytes)" - )] + #[error("array size ({array} bytes) is not a multiple of the element size ({element} bytes)")] InvalidArraySize { array: usize, element: usize }, #[error("Due to size restrictions a struct could not be parsed.")] ImpossibleStructError, @@ -40,10 +41,12 @@ pub enum Error { #[error("expected child {expected}, got {actual}")] InvalidChildError { expected: &'static str, actual: String }, } + pub trait Packet { fn to_bytes(self) -> Bytes; fn to_vec(self) -> Vec; } + #[derive(Debug, Clone, PartialEq, Eq)] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] pub struct FooData {} diff --git a/tools/pdl/tests/generated/packet_decl_reserved_field_little_endian.rs b/tools/pdl/tests/generated/packet_decl_reserved_field_little_endian.rs index f03c7bfcd12..6cfe597634c 100644 --- a/tools/pdl/tests/generated/packet_decl_reserved_field_little_endian.rs +++ b/tools/pdl/tests/generated/packet_decl_reserved_field_little_endian.rs @@ -1,16 +1,18 @@ -#![rustfmt::skip] -/// @generated rust packets from test. +// @generated rust packets from test + use bytes::{Buf, BufMut, Bytes, BytesMut}; -use std::convert::{TryFrom, TryInto}; use std::cell::Cell; +use std::convert::{TryFrom, TryInto}; use std::fmt; use std::sync::Arc; use thiserror::Error; + type Result = std::result::Result; -/// Private prevents users from creating arbitrary scalar values -/// in situations where the value needs to be validated. -/// Users can freely deref the value, but only the backend -/// may create it. + +#[doc = r" Private prevents users from creating arbitrary scalar values"] +#[doc = r" in situations where the value needs to be validated."] +#[doc = r" Users can freely deref the value, but only the backend"] +#[doc = r" may create it."] #[derive(Debug, Clone, Copy, Hash, PartialEq, Eq, PartialOrd, Ord)] pub struct Private(T); impl std::ops::Deref for Private { @@ -19,6 +21,7 @@ impl std::ops::Deref for Private { &self.0 } } + #[derive(Debug, Error)] pub enum Error { #[error("Packet parsing failed")] @@ -29,9 +32,7 @@ pub enum Error { InvalidFixedValue { expected: u64, actual: u64 }, #[error("when parsing {obj} needed length of {wanted} but got {got}")] InvalidLengthError { obj: String, wanted: usize, got: usize }, - #[error( - "array size ({array} bytes) is not a multiple of the element size ({element} bytes)" - )] + #[error("array size ({array} bytes) is not a multiple of the element size ({element} bytes)")] InvalidArraySize { array: usize, element: usize }, #[error("Due to size restrictions a struct could not be parsed.")] ImpossibleStructError, @@ -40,10 +41,12 @@ pub enum Error { #[error("expected child {expected}, got {actual}")] InvalidChildError { expected: &'static str, actual: String }, } + pub trait Packet { fn to_bytes(self) -> Bytes; fn to_vec(self) -> Vec; } + #[derive(Debug, Clone, PartialEq, Eq)] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] pub struct FooData {} diff --git a/tools/pdl/tests/generated/packet_decl_simple_scalars_big_endian.rs b/tools/pdl/tests/generated/packet_decl_simple_scalars_big_endian.rs index 303a7855e9a..244ed08e671 100644 --- a/tools/pdl/tests/generated/packet_decl_simple_scalars_big_endian.rs +++ b/tools/pdl/tests/generated/packet_decl_simple_scalars_big_endian.rs @@ -1,16 +1,18 @@ -#![rustfmt::skip] -/// @generated rust packets from test. +// @generated rust packets from test + use bytes::{Buf, BufMut, Bytes, BytesMut}; -use std::convert::{TryFrom, TryInto}; use std::cell::Cell; +use std::convert::{TryFrom, TryInto}; use std::fmt; use std::sync::Arc; use thiserror::Error; + type Result = std::result::Result; -/// Private prevents users from creating arbitrary scalar values -/// in situations where the value needs to be validated. -/// Users can freely deref the value, but only the backend -/// may create it. + +#[doc = r" Private prevents users from creating arbitrary scalar values"] +#[doc = r" in situations where the value needs to be validated."] +#[doc = r" Users can freely deref the value, but only the backend"] +#[doc = r" may create it."] #[derive(Debug, Clone, Copy, Hash, PartialEq, Eq, PartialOrd, Ord)] pub struct Private(T); impl std::ops::Deref for Private { @@ -19,6 +21,7 @@ impl std::ops::Deref for Private { &self.0 } } + #[derive(Debug, Error)] pub enum Error { #[error("Packet parsing failed")] @@ -29,9 +32,7 @@ pub enum Error { InvalidFixedValue { expected: u64, actual: u64 }, #[error("when parsing {obj} needed length of {wanted} but got {got}")] InvalidLengthError { obj: String, wanted: usize, got: usize }, - #[error( - "array size ({array} bytes) is not a multiple of the element size ({element} bytes)" - )] + #[error("array size ({array} bytes) is not a multiple of the element size ({element} bytes)")] InvalidArraySize { array: usize, element: usize }, #[error("Due to size restrictions a struct could not be parsed.")] ImpossibleStructError, @@ -40,10 +41,12 @@ pub enum Error { #[error("expected child {expected}, got {actual}")] InvalidChildError { expected: &'static str, actual: String }, } + pub trait Packet { fn to_bytes(self) -> Bytes; fn to_vec(self) -> Vec; } + #[derive(Debug, Clone, PartialEq, Eq)] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] pub struct FooData { @@ -166,11 +169,7 @@ impl Foo { } impl FooBuilder { pub fn build(self) -> Foo { - let foo = Arc::new(FooData { - x: self.x, - y: self.y, - z: self.z, - }); + let foo = Arc::new(FooData { x: self.x, y: self.y, z: self.z }); Foo::new(foo).unwrap() } } diff --git a/tools/pdl/tests/generated/packet_decl_simple_scalars_little_endian.rs b/tools/pdl/tests/generated/packet_decl_simple_scalars_little_endian.rs index 043a72f1133..775d7a09129 100644 --- a/tools/pdl/tests/generated/packet_decl_simple_scalars_little_endian.rs +++ b/tools/pdl/tests/generated/packet_decl_simple_scalars_little_endian.rs @@ -1,16 +1,18 @@ -#![rustfmt::skip] -/// @generated rust packets from test. +// @generated rust packets from test + use bytes::{Buf, BufMut, Bytes, BytesMut}; -use std::convert::{TryFrom, TryInto}; use std::cell::Cell; +use std::convert::{TryFrom, TryInto}; use std::fmt; use std::sync::Arc; use thiserror::Error; + type Result = std::result::Result; -/// Private prevents users from creating arbitrary scalar values -/// in situations where the value needs to be validated. -/// Users can freely deref the value, but only the backend -/// may create it. + +#[doc = r" Private prevents users from creating arbitrary scalar values"] +#[doc = r" in situations where the value needs to be validated."] +#[doc = r" Users can freely deref the value, but only the backend"] +#[doc = r" may create it."] #[derive(Debug, Clone, Copy, Hash, PartialEq, Eq, PartialOrd, Ord)] pub struct Private(T); impl std::ops::Deref for Private { @@ -19,6 +21,7 @@ impl std::ops::Deref for Private { &self.0 } } + #[derive(Debug, Error)] pub enum Error { #[error("Packet parsing failed")] @@ -29,9 +32,7 @@ pub enum Error { InvalidFixedValue { expected: u64, actual: u64 }, #[error("when parsing {obj} needed length of {wanted} but got {got}")] InvalidLengthError { obj: String, wanted: usize, got: usize }, - #[error( - "array size ({array} bytes) is not a multiple of the element size ({element} bytes)" - )] + #[error("array size ({array} bytes) is not a multiple of the element size ({element} bytes)")] InvalidArraySize { array: usize, element: usize }, #[error("Due to size restrictions a struct could not be parsed.")] ImpossibleStructError, @@ -40,10 +41,12 @@ pub enum Error { #[error("expected child {expected}, got {actual}")] InvalidChildError { expected: &'static str, actual: String }, } + pub trait Packet { fn to_bytes(self) -> Bytes; fn to_vec(self) -> Vec; } + #[derive(Debug, Clone, PartialEq, Eq)] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] pub struct FooData { @@ -166,11 +169,7 @@ impl Foo { } impl FooBuilder { pub fn build(self) -> Foo { - let foo = Arc::new(FooData { - x: self.x, - y: self.y, - z: self.z, - }); + let foo = Arc::new(FooData { x: self.x, y: self.y, z: self.z }); Foo::new(foo).unwrap() } } diff --git a/tools/pdl/tests/generated/preamble.rs b/tools/pdl/tests/generated/preamble.rs index e200e6d7b1e..c7d0fad1b92 100644 --- a/tools/pdl/tests/generated/preamble.rs +++ b/tools/pdl/tests/generated/preamble.rs @@ -1,16 +1,18 @@ -#![rustfmt::skip] -/// @generated rust packets from foo.pdl. +// @generated rust packets from foo.pdl + use bytes::{Buf, BufMut, Bytes, BytesMut}; -use std::convert::{TryFrom, TryInto}; use std::cell::Cell; +use std::convert::{TryFrom, TryInto}; use std::fmt; use std::sync::Arc; use thiserror::Error; + type Result = std::result::Result; -/// Private prevents users from creating arbitrary scalar values -/// in situations where the value needs to be validated. -/// Users can freely deref the value, but only the backend -/// may create it. + +#[doc = r" Private prevents users from creating arbitrary scalar values"] +#[doc = r" in situations where the value needs to be validated."] +#[doc = r" Users can freely deref the value, but only the backend"] +#[doc = r" may create it."] #[derive(Debug, Clone, Copy, Hash, PartialEq, Eq, PartialOrd, Ord)] pub struct Private(T); impl std::ops::Deref for Private { @@ -19,6 +21,7 @@ impl std::ops::Deref for Private { &self.0 } } + #[derive(Debug, Error)] pub enum Error { #[error("Packet parsing failed")] @@ -29,9 +32,7 @@ pub enum Error { InvalidFixedValue { expected: u64, actual: u64 }, #[error("when parsing {obj} needed length of {wanted} but got {got}")] InvalidLengthError { obj: String, wanted: usize, got: usize }, - #[error( - "array size ({array} bytes) is not a multiple of the element size ({element} bytes)" - )] + #[error("array size ({array} bytes) is not a multiple of the element size ({element} bytes)")] InvalidArraySize { array: usize, element: usize }, #[error("Due to size restrictions a struct could not be parsed.")] ImpossibleStructError, @@ -40,6 +41,7 @@ pub enum Error { #[error("expected child {expected}, got {actual}")] InvalidChildError { expected: &'static str, actual: String }, } + pub trait Packet { fn to_bytes(self) -> Bytes; fn to_vec(self) -> Vec; diff --git a/tools/pdl/tests/generated/struct_decl_complex_scalars_big_endian.rs b/tools/pdl/tests/generated/struct_decl_complex_scalars_big_endian.rs index 8ea2bb92ba7..35cbe95eb3b 100644 --- a/tools/pdl/tests/generated/struct_decl_complex_scalars_big_endian.rs +++ b/tools/pdl/tests/generated/struct_decl_complex_scalars_big_endian.rs @@ -1,16 +1,18 @@ -#![rustfmt::skip] -/// @generated rust packets from test. +// @generated rust packets from test + use bytes::{Buf, BufMut, Bytes, BytesMut}; -use std::convert::{TryFrom, TryInto}; use std::cell::Cell; +use std::convert::{TryFrom, TryInto}; use std::fmt; use std::sync::Arc; use thiserror::Error; + type Result = std::result::Result; -/// Private prevents users from creating arbitrary scalar values -/// in situations where the value needs to be validated. -/// Users can freely deref the value, but only the backend -/// may create it. + +#[doc = r" Private prevents users from creating arbitrary scalar values"] +#[doc = r" in situations where the value needs to be validated."] +#[doc = r" Users can freely deref the value, but only the backend"] +#[doc = r" may create it."] #[derive(Debug, Clone, Copy, Hash, PartialEq, Eq, PartialOrd, Ord)] pub struct Private(T); impl std::ops::Deref for Private { @@ -19,6 +21,7 @@ impl std::ops::Deref for Private { &self.0 } } + #[derive(Debug, Error)] pub enum Error { #[error("Packet parsing failed")] @@ -29,9 +32,7 @@ pub enum Error { InvalidFixedValue { expected: u64, actual: u64 }, #[error("when parsing {obj} needed length of {wanted} but got {got}")] InvalidLengthError { obj: String, wanted: usize, got: usize }, - #[error( - "array size ({array} bytes) is not a multiple of the element size ({element} bytes)" - )] + #[error("array size ({array} bytes) is not a multiple of the element size ({element} bytes)")] InvalidArraySize { array: usize, element: usize }, #[error("Due to size restrictions a struct could not be parsed.")] ImpossibleStructError, @@ -40,10 +41,12 @@ pub enum Error { #[error("expected child {expected}, got {actual}")] InvalidChildError { expected: &'static str, actual: String }, } + pub trait Packet { fn to_bytes(self) -> Bytes; fn to_vec(self) -> Vec; } + #[derive(Debug, Clone, PartialEq, Eq)] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] pub struct Foo { diff --git a/tools/pdl/tests/generated/struct_decl_complex_scalars_little_endian.rs b/tools/pdl/tests/generated/struct_decl_complex_scalars_little_endian.rs index 0ec2c384b4e..d227b3846fd 100644 --- a/tools/pdl/tests/generated/struct_decl_complex_scalars_little_endian.rs +++ b/tools/pdl/tests/generated/struct_decl_complex_scalars_little_endian.rs @@ -1,16 +1,18 @@ -#![rustfmt::skip] -/// @generated rust packets from test. +// @generated rust packets from test + use bytes::{Buf, BufMut, Bytes, BytesMut}; -use std::convert::{TryFrom, TryInto}; use std::cell::Cell; +use std::convert::{TryFrom, TryInto}; use std::fmt; use std::sync::Arc; use thiserror::Error; + type Result = std::result::Result; -/// Private prevents users from creating arbitrary scalar values -/// in situations where the value needs to be validated. -/// Users can freely deref the value, but only the backend -/// may create it. + +#[doc = r" Private prevents users from creating arbitrary scalar values"] +#[doc = r" in situations where the value needs to be validated."] +#[doc = r" Users can freely deref the value, but only the backend"] +#[doc = r" may create it."] #[derive(Debug, Clone, Copy, Hash, PartialEq, Eq, PartialOrd, Ord)] pub struct Private(T); impl std::ops::Deref for Private { @@ -19,6 +21,7 @@ impl std::ops::Deref for Private { &self.0 } } + #[derive(Debug, Error)] pub enum Error { #[error("Packet parsing failed")] @@ -29,9 +32,7 @@ pub enum Error { InvalidFixedValue { expected: u64, actual: u64 }, #[error("when parsing {obj} needed length of {wanted} but got {got}")] InvalidLengthError { obj: String, wanted: usize, got: usize }, - #[error( - "array size ({array} bytes) is not a multiple of the element size ({element} bytes)" - )] + #[error("array size ({array} bytes) is not a multiple of the element size ({element} bytes)")] InvalidArraySize { array: usize, element: usize }, #[error("Due to size restrictions a struct could not be parsed.")] ImpossibleStructError, @@ -40,10 +41,12 @@ pub enum Error { #[error("expected child {expected}, got {actual}")] InvalidChildError { expected: &'static str, actual: String }, } + pub trait Packet { fn to_bytes(self) -> Bytes; fn to_vec(self) -> Vec; } + #[derive(Debug, Clone, PartialEq, Eq)] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] pub struct Foo { diff --git a/tools/pdl/tests/generated_files_compile.sh b/tools/pdl/tests/generated_files_compile.sh index 89d12ba2148..583abac8337 100755 --- a/tools/pdl/tests/generated_files_compile.sh +++ b/tools/pdl/tests/generated_files_compile.sh @@ -25,9 +25,7 @@ for input_path in "$@"; do echo "mod $(basename -s .rs "$input_path") {" - # The inner (module) attribute needs to be removed to produce a - # valid file. - grep -v '#!\[rustfmt::skip\]' "$input_path" + cat "$input_path" echo "}" done -- GitLab From 653770969efea9cf09868688df4f930d5450e9de Mon Sep 17 00:00:00 2001 From: Sal Savage Date: Wed, 17 May 2023 12:23:54 -0700 Subject: [PATCH 0093/2405] Update BluetoothProfile.getProfileName to include the unknown profile id Tag: #refactor Bug: 282988270 Test: atest BluetoothInstrumentationTests Change-Id: I51c6725bf0b579a48fb12f612eadec6ff1b545bc --- framework/java/android/bluetooth/BluetoothProfile.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/framework/java/android/bluetooth/BluetoothProfile.java b/framework/java/android/bluetooth/BluetoothProfile.java index 58521c2512b..84719753e85 100644 --- a/framework/java/android/bluetooth/BluetoothProfile.java +++ b/framework/java/android/bluetooth/BluetoothProfile.java @@ -537,7 +537,7 @@ public interface BluetoothProfile { case BATTERY: return "BATTERY"; default: - return "UNKNOWN_PROFILE"; + return "UNKNOWN_PROFILE (" + profile + ")"; } } } -- GitLab From 3077040acdb30534296d645da4cbb3dd1a5e6497 Mon Sep 17 00:00:00 2001 From: Rahul Sabnis Date: Wed, 17 May 2023 11:51:54 -0700 Subject: [PATCH 0094/2405] Account for oob generation returning a tuple Bug: 283124370 Test: system/gd/cert/run --sl4a_sl4a --clean Ignore-AOSP-First: Test not in AOSP Change-Id: I66006a4ecc1e2694bb76a619ef875029894bea13 --- .../blueberry/tests/sl4a_sl4a/security/oob_pairing_test.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/system/blueberry/tests/sl4a_sl4a/security/oob_pairing_test.py b/system/blueberry/tests/sl4a_sl4a/security/oob_pairing_test.py index 17ff46079b8..610f2f3c7ea 100644 --- a/system/blueberry/tests/sl4a_sl4a/security/oob_pairing_test.py +++ b/system/blueberry/tests/sl4a_sl4a/security/oob_pairing_test.py @@ -132,8 +132,9 @@ class OobPairingTest(sl4a_sl4a_base_test.Sl4aSl4aBaseTestClass): def test_le_oob_advertiser_not_using_public_address(self): #TODO(optedoblivion): Use sysprop and make another test to handle non privacy case oob_data = self.dut_security_.generate_oob_data(Security.TRANSPORT_LE) - assertThat(oob_data).isNotNone() - advertiser_address = oob_data.to_sl4a_address() + assertThat(oob_data[0]).isEqualTo(0) + assertThat(oob_data[1]).isNotNone() + advertiser_address = oob_data[1].to_sl4a_address() public_address = self.dut_advertiser_.get_local_public_address() logging.info("DUT Advertiser Address: %s " % advertiser_address) logging.info("DUT Public Address: %s " % public_address) -- GitLab From d6c6d68524ec26b0f9c243a7a6e9066f40a6aeee Mon Sep 17 00:00:00 2001 From: Himanshu Rawat Date: Wed, 17 May 2023 21:48:00 +0000 Subject: [PATCH 0095/2405] Ensure services are searched over BR/EDR transport after BR/EDR pairing After pairing over BR/EDR transport, service search is scheduled over the transport depending upon device type. If device type is not correct for any reason, service search may get started over LE transport. In such case, btif_dm may continue to wait for SDP search results for reseting pairing state, thus blocking further pairing attempts. Bug: 282733852 Change-Id: Ib5124fcf334a357495a57abee5bd6050248c7eb2 Test: Pair with dual mode devices --- system/btif/src/btif_dm.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/system/btif/src/btif_dm.cc b/system/btif/src/btif_dm.cc index 480d80609fa..8bd407bcdbe 100644 --- a/system/btif/src/btif_dm.cc +++ b/system/btif/src/btif_dm.cc @@ -1250,7 +1250,7 @@ static void btif_dm_auth_cmpl_evt(tBTA_DM_AUTH_CMPL* p_auth_cmpl) { LOG_INFO("scheduling SDP for %s", ADDRESS_TO_LOGGABLE_CSTR(bd_addr)); pairing_cb.sdp_over_classic = btif_dm_pairing_cb_t::ServiceDiscoveryState::SCHEDULED; - btif_dm_get_remote_services(bd_addr, BT_TRANSPORT_AUTO); + btif_dm_get_remote_services(bd_addr, BT_TRANSPORT_BR_EDR); } } } -- GitLab From 8d71ba7f275aeb8978587f03aedc13b927d49c05 Mon Sep 17 00:00:00 2001 From: Chris Manton Date: Mon, 15 May 2023 09:46:23 -0700 Subject: [PATCH 0096/2405] Break out stack::include::sdp_device_id.h Bug: 282936084 Test: Compiles and links Change-Id: Ifdd62d8b9a9c4ad29dcae60c93892bac4ca6a19e --- system/stack/include/sdp_api.h | 21 +------------ system/stack/include/sdp_device_id.h | 44 ++++++++++++++++++++++++++++ 2 files changed, 45 insertions(+), 20 deletions(-) create mode 100644 system/stack/include/sdp_device_id.h diff --git a/system/stack/include/sdp_api.h b/system/stack/include/sdp_api.h index 2808cffb914..7ab3b76df69 100644 --- a/system/stack/include/sdp_api.h +++ b/system/stack/include/sdp_api.h @@ -23,6 +23,7 @@ #include #include "bt_target.h" +#include "stack/include/sdp_device_id.h" #include "stack/include/sdp_status.h" #include "stack/include/sdpdefs.h" #include "stack/sdp/sdp_discovery_db.h" @@ -41,26 +42,6 @@ typedef void(tSDP_DISC_CMPL_CB)(tSDP_RESULT result); typedef void(tSDP_DISC_CMPL_CB2)(tSDP_RESULT result, const void* user_data); -/* Device Identification (DI) data structure -*/ -/* Used to set the DI record */ -typedef struct t_sdp_di_record { - uint16_t vendor; - uint16_t vendor_id_source; - uint16_t product; - uint16_t version; - bool primary_record; - char client_executable_url[SDP_MAX_ATTR_LEN]; /* optional */ - char service_description[SDP_MAX_ATTR_LEN]; /* optional */ - char documentation_url[SDP_MAX_ATTR_LEN]; /* optional */ -} tSDP_DI_RECORD; - -/* Used to get the DI record */ -typedef struct t_sdp_di_get_record { - uint16_t spec_id; - tSDP_DI_RECORD rec; -} tSDP_DI_GET_RECORD; - /* API into the SDP layer for service discovery. */ /******************************************************************************* diff --git a/system/stack/include/sdp_device_id.h b/system/stack/include/sdp_device_id.h new file mode 100644 index 00000000000..cb0f3fe44f2 --- /dev/null +++ b/system/stack/include/sdp_device_id.h @@ -0,0 +1,44 @@ +/****************************************************************************** + * + * Copyright 1999-2012 Broadcom Corporation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + ******************************************************************************/ + +#pragma once + +#include + +#include "bt_target.h" +#include "stack/include/sdp_status.h" + +/* Device Identification (DI) data structure + */ +/* Used to set the DI record */ +typedef struct t_sdp_di_record { + uint16_t vendor; + uint16_t vendor_id_source; + uint16_t product; + uint16_t version; + bool primary_record; + char client_executable_url[SDP_MAX_ATTR_LEN]; /* optional */ + char service_description[SDP_MAX_ATTR_LEN]; /* optional */ + char documentation_url[SDP_MAX_ATTR_LEN]; /* optional */ +} tSDP_DI_RECORD; + +/* Used to get the DI record */ +typedef struct t_sdp_di_get_record { + uint16_t spec_id; + tSDP_DI_RECORD rec; +} tSDP_DI_GET_RECORD; -- GitLab From f6f263728542a3fcce9117af3584c29c30f5db6d Mon Sep 17 00:00:00 2001 From: Alice Kuo Date: Thu, 18 May 2023 13:20:41 +0800 Subject: [PATCH 0097/2405] Add TbsService to mLeAudioUnicastProfiles Folow Android 13 CDD, isLeAudioSupported should make sure Tbs service is enabled as well Bug: 283182363 Test: Manual Change-Id: Icfaaf8f55e6acb4a626e52a3ae87bb5073bef8d7 --- .../android/bluetooth/btservice/Config.java | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/android/app/src/com/android/bluetooth/btservice/Config.java b/android/app/src/com/android/bluetooth/btservice/Config.java index 7eaa804af88..bc0ed8408c5 100644 --- a/android/app/src/com/android/bluetooth/btservice/Config.java +++ b/android/app/src/com/android/bluetooth/btservice/Config.java @@ -91,14 +91,15 @@ public class Config { } } - /** - * List of profile services related to LE audio - */ - private static final HashSet mLeAudioUnicastProfiles = new HashSet( - Arrays.asList(LeAudioService.class, - VolumeControlService.class, - McpService.class, - CsipSetCoordinatorService.class)); + /** List of profile services related to LE audio */ + private static final HashSet LE_AUDIO_UNICAST_PROFILES = + new HashSet( + Arrays.asList( + LeAudioService.class, + VolumeControlService.class, + McpService.class, + CsipSetCoordinatorService.class, + TbsService.class)); /** * List of profile services with the profile-supported resource flag and bit mask. @@ -281,7 +282,7 @@ public class Config { } static HashSet getLeAudioUnicastProfiles() { - return mLeAudioUnicastProfiles; + return LE_AUDIO_UNICAST_PROFILES; } static Class[] getSupportedProfiles() { -- GitLab From 41000d71011aa5d0e5b293f38a5a5cb2c38c69d9 Mon Sep 17 00:00:00 2001 From: Benson Li Date: Wed, 17 May 2023 06:21:56 +0000 Subject: [PATCH 0098/2405] Add init_flag for SCO LC3 codec Bug: 282824342 Test: Manual Change-Id: I7378459c3a7738b22e53bf8c5d3bdda417c288ef --- system/gd/rust/common/src/init_flags.rs | 1 + system/gd/rust/shim/src/init_flags.rs | 1 + system/stack/btm/btm_sco_hfp_hal.cc | 4 +++- 3 files changed, 5 insertions(+), 1 deletion(-) diff --git a/system/gd/rust/common/src/init_flags.rs b/system/gd/rust/common/src/init_flags.rs index fdb0bcee5f3..9e10ec7ee30 100644 --- a/system/gd/rust/common/src/init_flags.rs +++ b/system/gd/rust/common/src/init_flags.rs @@ -392,6 +392,7 @@ init_flags!( read_encryption_key_size = true, redact_log = true, rust_event_loop = true, + sco_codec_select_lc3, sco_codec_timeout_clear, sdp_serialization = true, sdp_skip_rnr_if_known = true, diff --git a/system/gd/rust/shim/src/init_flags.rs b/system/gd/rust/shim/src/init_flags.rs index 09750d11e4f..25498bce903 100644 --- a/system/gd/rust/shim/src/init_flags.rs +++ b/system/gd/rust/shim/src/init_flags.rs @@ -46,6 +46,7 @@ mod ffi { fn read_encryption_key_size_is_enabled() -> bool; fn redact_log_is_enabled() -> bool; fn rust_event_loop_is_enabled() -> bool; + fn sco_codec_select_lc3_is_enabled() -> bool; fn sco_codec_timeout_clear_is_enabled() -> bool; fn sdp_serialization_is_enabled() -> bool; fn sdp_skip_rnr_if_known_is_enabled() -> bool; diff --git a/system/stack/btm/btm_sco_hfp_hal.cc b/system/stack/btm/btm_sco_hfp_hal.cc index 01c4522e295..664068b5906 100644 --- a/system/stack/btm/btm_sco_hfp_hal.cc +++ b/system/stack/btm/btm_sco_hfp_hal.cc @@ -18,6 +18,7 @@ #include +#include "common/init_flags.h" #include "device/include/esco_parameters.h" #include "osi/include/properties.h" @@ -50,7 +51,8 @@ void init() { bool get_wbs_supported() { return !DISABLE_WBS; } bool get_swb_supported() { - return osi_property_get_bool("bluetooth.hfp.swb.supported", false); + return osi_property_get_bool("bluetooth.hfp.swb.supported", false) && + bluetooth::common::init_flags::sco_codec_select_lc3_is_enabled(); } // Checks the supported codecs -- GitLab From afa629f333924303fe9f565a17e068c7e691e041 Mon Sep 17 00:00:00 2001 From: David Duarte Date: Thu, 18 May 2023 09:52:47 +0000 Subject: [PATCH 0099/2405] Remove grpc from apex Testing code was linked inside Gabeldorsche Rust and pulled the grpcio dependency into our APEX Remove the grpc by cutting the dependency with Gabeldorsche Rust Fix: 220806135 Test: mma Change-Id: Ic455f2d1236b33610146de3d88f5a28b56b8da1d --- system/gd/rust/common/Android.bp | 47 +++++++++++-------- system/gd/rust/common/src/lib.rs | 39 +-------------- .../gd/rust/common/src/lib_only_init_flags.rs | 7 +++ system/gd/rust/common/src/logging.rs | 37 +++++++++++++++ system/gd/rust/facade/Android.bp | 3 -- system/gd/rust/gddi/Android.bp | 3 -- system/gd/rust/shim/Android.bp | 11 +---- system/gd/rust/stack/Android.bp | 6 --- system/rust/Android.bp | 2 +- 9 files changed, 75 insertions(+), 80 deletions(-) create mode 100644 system/gd/rust/common/src/lib_only_init_flags.rs create mode 100644 system/gd/rust/common/src/logging.rs diff --git a/system/gd/rust/common/Android.bp b/system/gd/rust/common/Android.bp index fd889115dfa..ea87f8b60f5 100644 --- a/system/gd/rust/common/Android.bp +++ b/system/gd/rust/common/Android.bp @@ -34,8 +34,34 @@ rust_library { ], }, }, + min_sdk_version: "Tiramisu", +} + +rust_library { + name: "libbt_common_only_init_flags", + defaults: ["gd_rust_defaults"], + crate_name: "bt_common", + srcs: ["src/lib_only_init_flags.rs"], + rustlibs: [ + "liblazy_static", + "liblog_rust", + ], + target: { + android: { + rustlibs: [ + "libandroid_logger", + ], + }, + host: { + rustlibs: [ + "libenv_logger", + ], + }, + }, + proc_macros: [ + "libpaste", + ], apex_available: [ - "//apex_available:platform", "com.android.btservices", ], min_sdk_version: "Tiramisu", @@ -80,9 +106,6 @@ rust_ffi_static { ], }, }, - apex_available: [ - "com.android.btservices", - ], min_sdk_version: "30", } @@ -110,10 +133,6 @@ cc_library_static { "-Wno-unused-const-variable", ], host_supported: true, - apex_available: [ - "//apex_available:platform", - "com.android.btservices", - ], shared_libs: [ "libchrome", ], @@ -137,10 +156,6 @@ cc_library_static { "libchrome", ], host_supported: true, - apex_available: [ - "//apex_available:platform", - "com.android.btservices", - ], min_sdk_version: "30", } @@ -148,10 +163,6 @@ cc_library_headers { name: "libbt_keystore_cc_headers", local_include_dirs: ["keystore"], host_supported: true, - apex_available: [ - "//apex_available:platform", - "com.android.btservices", - ], min_sdk_version: "30", } @@ -163,10 +174,6 @@ cc_library_static { "libbt_common_ffi", ], host_supported: true, - apex_available: [ - "//apex_available:platform", - "com.android.btservices", - ], min_sdk_version: "30", } diff --git a/system/gd/rust/common/src/lib.rs b/system/gd/rust/common/src/lib.rs index 095adfbb534..50fd92087d0 100644 --- a/system/gd/rust/common/src/lib.rs +++ b/system/gd/rust/common/src/lib.rs @@ -1,10 +1,5 @@ //! Bluetooth common library -use init_flags::{ - get_log_level_for_tag, LOG_TAG_DEBUG, LOG_TAG_ERROR, LOG_TAG_FATAL, LOG_TAG_INFO, - LOG_TAG_NOTICE, LOG_TAG_VERBOSE, LOG_TAG_WARN, -}; - /// Provides waking timer abstractions pub mod time; @@ -26,38 +21,8 @@ pub mod init_flags; /// Provides runtime configured system properties. Stubbed for non-Android. pub mod sys_prop; -fn get_log_level() -> log::Level { - match get_log_level_for_tag("bluetooth_core") { - LOG_TAG_FATAL => log::Level::Error, - LOG_TAG_ERROR => log::Level::Error, - LOG_TAG_WARN => log::Level::Warn, - LOG_TAG_NOTICE => log::Level::Info, - LOG_TAG_INFO => log::Level::Info, - LOG_TAG_DEBUG => log::Level::Debug, - LOG_TAG_VERBOSE => log::Level::Trace, - _ => log::Level::Info, // default level - } -} - -/// Inits logging for Android -#[cfg(target_os = "android")] -pub fn init_logging() { - android_logger::init_once( - android_logger::Config::default().with_tag("bt").with_min_level(get_log_level()), - ); - log::set_max_level(get_log_level().to_level_filter()) -} - -/// Inits logging for host -#[cfg(not(target_os = "android"))] -pub fn init_logging() { - env_logger::Builder::new() - .filter(None, get_log_level().to_level_filter()) - .parse_default_env() - .try_init() - .ok(); - log::set_max_level(get_log_level().to_level_filter()) -} +mod logging; +pub use logging::*; /// Indicates the object can be converted to a GRPC service pub trait GrpcFacade { diff --git a/system/gd/rust/common/src/lib_only_init_flags.rs b/system/gd/rust/common/src/lib_only_init_flags.rs new file mode 100644 index 00000000000..c4001f575af --- /dev/null +++ b/system/gd/rust/common/src/lib_only_init_flags.rs @@ -0,0 +1,7 @@ +//! Bluetooth common library + +/// Provides runtime configured-at-startup flags +pub mod init_flags; + +mod logging; +pub use logging::*; diff --git a/system/gd/rust/common/src/logging.rs b/system/gd/rust/common/src/logging.rs new file mode 100644 index 00000000000..d51e5b3b66b --- /dev/null +++ b/system/gd/rust/common/src/logging.rs @@ -0,0 +1,37 @@ +use crate::init_flags::{ + get_log_level_for_tag, LOG_TAG_DEBUG, LOG_TAG_ERROR, LOG_TAG_FATAL, LOG_TAG_INFO, + LOG_TAG_NOTICE, LOG_TAG_VERBOSE, LOG_TAG_WARN, +}; + +fn get_log_level() -> log::Level { + match get_log_level_for_tag("bluetooth_core") { + LOG_TAG_FATAL => log::Level::Error, + LOG_TAG_ERROR => log::Level::Error, + LOG_TAG_WARN => log::Level::Warn, + LOG_TAG_NOTICE => log::Level::Info, + LOG_TAG_INFO => log::Level::Info, + LOG_TAG_DEBUG => log::Level::Debug, + LOG_TAG_VERBOSE => log::Level::Trace, + _ => log::Level::Info, // default level + } +} + +/// Inits logging for Android +#[cfg(target_os = "android")] +pub fn init_logging() { + android_logger::init_once( + android_logger::Config::default().with_tag("bt").with_min_level(get_log_level()), + ); + log::set_max_level(get_log_level().to_level_filter()) +} + +/// Inits logging for host +#[cfg(not(target_os = "android"))] +pub fn init_logging() { + env_logger::Builder::new() + .filter(None, get_log_level().to_level_filter()) + .parse_default_env() + .try_init() + .ok(); + log::set_max_level(get_log_level().to_level_filter()) +} diff --git a/system/gd/rust/facade/Android.bp b/system/gd/rust/facade/Android.bp index 4444ccfce34..2261e594d47 100644 --- a/system/gd/rust/facade/Android.bp +++ b/system/gd/rust/facade/Android.bp @@ -78,8 +78,5 @@ rust_library { "libprotobuf_deprecated", "libtokio", ], - apex_available: [ - "com.android.btservices", - ], min_sdk_version: "30", } diff --git a/system/gd/rust/gddi/Android.bp b/system/gd/rust/gddi/Android.bp index ac8ed8b475a..f004ba48455 100644 --- a/system/gd/rust/gddi/Android.bp +++ b/system/gd/rust/gddi/Android.bp @@ -15,9 +15,6 @@ rust_library { edition: "2018", proc_macros: ["libgddi_macros"], rustlibs: ["libtokio"], - apex_available: [ - "com.android.btservices", - ], min_sdk_version: "30", } diff --git a/system/gd/rust/shim/Android.bp b/system/gd/rust/shim/Android.bp index 3bce89aecac..0a14a8f6222 100644 --- a/system/gd/rust/shim/Android.bp +++ b/system/gd/rust/shim/Android.bp @@ -32,17 +32,8 @@ rust_defaults { crate_name: "bt_shim", srcs: ["src/lib.rs"], rustlibs: [ - "libbluetooth_rs", - "libbt_common", - "libbt_facade_helpers", - "libbt_packets", + "libbt_common_only_init_flags", "libcxx", - "libfutures", - "liblazy_static", - "liblog_rust", - "libnix", - "libnum_traits", - "libtokio", ], proc_macros: [ "libpaste", diff --git a/system/gd/rust/stack/Android.bp b/system/gd/rust/stack/Android.bp index 6e0c5c67f89..05c77022b5d 100644 --- a/system/gd/rust/stack/Android.bp +++ b/system/gd/rust/stack/Android.bp @@ -35,9 +35,6 @@ rust_library { proc_macros: [ "libnum_derive", ], - apex_available: [ - "com.android.btservices", - ], min_sdk_version: "30", target: { android: { @@ -122,8 +119,5 @@ cc_library_static { "libhidlbase", "libutils", ], - apex_available: [ - "com.android.btservices", - ], min_sdk_version: "30", } diff --git a/system/rust/Android.bp b/system/rust/Android.bp index 738a0ed5b13..dd24b57591d 100644 --- a/system/rust/Android.bp +++ b/system/rust/Android.bp @@ -36,7 +36,7 @@ rust_defaults { rustlibs: [ "libanyhow", "libbitflags", - "libbt_common", + "libbt_common_only_init_flags", "libcxx", "liblog_rust", "libscopeguard", -- GitLab From 3fbf41261fef69f66af2fb5f3700429c2da34aaa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Rymanowski?= Date: Thu, 18 May 2023 00:02:42 +0000 Subject: [PATCH 0100/2405] leaudio: Fix reconnect after disconnected by Java Disconnect from Java can happen in two cases 1.Profile connection timeout - this can happen on single device while other is connected 2. Intentional user disconnection - this will end up with all members being disconnected. With this patch, if 1) happens, we want to be sure that device will get back on allow list if other set members are connected Bug: 281937978 Test: atest bluetooth_le_audio_client_test Test: atest BluetoothInstrumentationtTests Tag: #feature Change-Id: I1e446e611400659fc58a5a14ec13ba1e53f7eb65 --- system/bta/le_audio/client.cc | 31 +++------------------ system/bta/le_audio/devices.cc | 3 +- system/bta/le_audio/le_audio_client_test.cc | 19 +++++++------ 3 files changed, 16 insertions(+), 37 deletions(-) diff --git a/system/bta/le_audio/client.cc b/system/bta/le_audio/client.cc index b1c69f29af0..91ab90dbecf 100644 --- a/system/bta/le_audio/client.cc +++ b/system/bta/le_audio/client.cc @@ -1433,30 +1433,12 @@ class LeAudioClientImpl : public LeAudioClient { } void BackgroundConnectIfNeeded(LeAudioDevice* leAudioDevice) { - auto group = GetGroupIfEnabled(leAudioDevice->group_id_); - if (group == nullptr) { - LOG_INFO(" Device %s is not yet part of the group %d. ", - ADDRESS_TO_LOGGABLE_CSTR(leAudioDevice->address_), - leAudioDevice->group_id_); - return; - } - - if (!leAudioDevice->autoconnect_flag_ && !group->IsAnyDeviceConnected()) { + if (!leAudioDevice->autoconnect_flag_) { LOG_DEBUG("Device %s not in the background connect", ADDRESS_TO_LOGGABLE_CSTR(leAudioDevice->address_)); return; } - - LOG_INFO( - "Add %s added to background connect. autoconnect flag: %d " - "group_connected: %d", - ADDRESS_TO_LOGGABLE_CSTR(leAudioDevice->address_), - leAudioDevice->group_id_, group->IsAnyDeviceConnected()); - - leAudioDevice->SetConnectionState( - DeviceConnectState::CONNECTING_AUTOCONNECT); - BTA_GATTC_Open(gatt_if_, leAudioDevice->address_, reconnection_mode_, - false); + AddToBackgroundConnectCheckGroupConnected(leAudioDevice); } void Disconnect(const RawAddress& address) override { @@ -2259,6 +2241,8 @@ class LeAudioClientImpl : public LeAudioClient { return; } + leAudioDevice->SetConnectionState(DeviceConnectState::DISCONNECTED); + /* Attempt background re-connect if disconnect was not initiated locally * or if autoconnect is set and device got disconnected because of some * issues @@ -2266,7 +2250,6 @@ class LeAudioClientImpl : public LeAudioClient { if (group == nullptr || !group->IsEnabled()) { LOG_ERROR("Group id %d (%p) disabled or null", leAudioDevice->group_id_, group); - leAudioDevice->SetConnectionState(DeviceConnectState::DISCONNECTED); return; } @@ -2274,9 +2257,6 @@ class LeAudioClientImpl : public LeAudioClient { if (leAudioDevice->autoconnect_flag_) { /* In this case ACL might not yet been disconnected */ scheduleAutoConnect(address); - } else { - /* Just acknowledge disconnected state*/ - leAudioDevice->SetConnectionState(DeviceConnectState::DISCONNECTED); } return; } @@ -2305,9 +2285,6 @@ class LeAudioClientImpl : public LeAudioClient { */ scheduleGroupConnectedCheck(leAudioDevice->group_id_); } - } else { - /* Just acknowledge disconnected state*/ - leAudioDevice->SetConnectionState(DeviceConnectState::DISCONNECTED); } } diff --git a/system/bta/le_audio/devices.cc b/system/bta/le_audio/devices.cc index 80c65951b9c..890eeee7dcd 100644 --- a/system/bta/le_audio/devices.cc +++ b/system/bta/le_audio/devices.cc @@ -3114,7 +3114,8 @@ void LeAudioDevices::Dump(int fd, int group_id) { void LeAudioDevices::Cleanup(tGATT_IF client_if) { for (auto const& device : leAudioDevices_) { auto connection_state = device->GetConnectionState(); - if (connection_state == DeviceConnectState::DISCONNECTED) { + if (connection_state == DeviceConnectState::DISCONNECTED || + connection_state == DeviceConnectState::DISCONNECTING) { continue; } diff --git a/system/bta/le_audio/le_audio_client_test.cc b/system/bta/le_audio/le_audio_client_test.cc index 31be98c36df..3de6210470e 100644 --- a/system/bta/le_audio/le_audio_client_test.cc +++ b/system/bta/le_audio/le_audio_client_test.cc @@ -4204,21 +4204,22 @@ TEST_F(UnicastTest, TwoEarbudsStreamingProfileDisconnect) { EXPECT_CALL(mock_gatt_interface_, Open(_, _, BTM_BLE_BKG_CONNECT_TARGETED_ANNOUNCEMENTS, _)) - .Times(1); + .Times(2); EXPECT_CALL(mock_state_machine_, StopStream(_)).Times(1); - DisconnectLeAudio(test_address0, 1); - SyncOnMainLoop(); - Mock::VerifyAndClearExpectations(&mock_gatt_interface_); - Mock::VerifyAndClearExpectations(&mock_state_machine_); - - EXPECT_CALL(mock_gatt_interface_, - Open(_, _, BTM_BLE_BKG_CONNECT_TARGETED_ANNOUNCEMENTS, _)) - .Times(1); + /* Do not inject OPEN_EVENT by default */ + ON_CALL(mock_gatt_interface_, Open(_, _, _, _)) + .WillByDefault(DoAll(Return())); + ON_CALL(mock_gatt_interface_, Close(_)).WillByDefault(DoAll(Return())); + DisconnectLeAudio(test_address0, 1); DisconnectLeAudio(test_address1, 2); + InjectDisconnectedEvent(1); + InjectDisconnectedEvent(2); + SyncOnMainLoop(); + Mock::VerifyAndClearExpectations(&mock_state_machine_); Mock::VerifyAndClearExpectations(&mock_gatt_interface_); } -- GitLab From 78ba78c9c2029632885b24ecbf0125ef6cff0174 Mon Sep 17 00:00:00 2001 From: Jakub Tyszkowski Date: Wed, 17 May 2023 11:22:01 +0000 Subject: [PATCH 0101/2405] AudioUtils: Extract a generic event logger This will allow us to use the same logging mechanism in not audio related use cases, without the hard-codded and confusing "BT Audio" title. This logger was also extended with 'logw' and 'loge' methods for convenience. Bug: 278964409 Test: atest BluetoothInstrumentationTests Change-Id: If12dc7b429cc7d1b65be68971a389a7c96131762 --- ...tLogger.java => BluetoothEventLogger.java} | 30 ++++++++++++++----- .../bluetooth/audio_util/MediaPlayerList.java | 15 ++++++---- .../audio_util/MediaPlayerWrapper.java | 11 ++++--- .../bluetooth/avrcp/AvrcpTargetService.java | 8 ++--- .../bluetooth/avrcp/AvrcpVolumeManager.java | 8 ++--- 5 files changed, 46 insertions(+), 26 deletions(-) rename android/app/src/com/android/bluetooth/{audio_util/BTAudioEventLogger.java => BluetoothEventLogger.java} (71%) diff --git a/android/app/src/com/android/bluetooth/audio_util/BTAudioEventLogger.java b/android/app/src/com/android/bluetooth/BluetoothEventLogger.java similarity index 71% rename from android/app/src/com/android/bluetooth/audio_util/BTAudioEventLogger.java rename to android/app/src/com/android/bluetooth/BluetoothEventLogger.java index 5a247721c4c..ed682a38eb1 100644 --- a/android/app/src/com/android/bluetooth/audio_util/BTAudioEventLogger.java +++ b/android/app/src/com/android/bluetooth/BluetoothEventLogger.java @@ -14,17 +14,14 @@ * limitations under the License. */ -package com.android.bluetooth.audio_util; +package com.android.bluetooth; import android.util.Log; -import com.android.bluetooth.Utils; - import com.google.common.collect.EvictingQueue; - -// This class is to store logs for Audio for given size. -public class BTAudioEventLogger { +/** This class is to store logs for given size. */ +public class BluetoothEventLogger { private final String mTitle; private final EvictingQueue mEvents; @@ -44,25 +41,29 @@ public class BTAudioEventLogger { } } - public BTAudioEventLogger(int size, String title) { + public BluetoothEventLogger(int size, String title) { mEvents = EvictingQueue.create(size); mTitle = title; } + /** Add the event record */ public synchronized void add(String msg) { Event event = new Event(msg); mEvents.add(event); } + /** Add the event record and log message */ public synchronized void logv(String tag, String msg) { add(msg); Log.v(tag, msg); } + /** Add the event record and log debug message */ public synchronized void logd(String tag, String msg) { logd(true, tag, msg); } + /** Add the event record and log debug message */ public synchronized void logd(boolean debug, String tag, String msg) { add(msg); if (debug) { @@ -70,8 +71,21 @@ public class BTAudioEventLogger { } } + /** Add the event record and log warning message */ + public synchronized void logw(String tag, String msg) { + add(msg); + Log.w(tag, msg); + } + + /** Add the event record and log error message */ + public synchronized void loge(String tag, String msg) { + add(msg); + Log.e(tag, msg); + } + + /** Dump all the events */ public synchronized void dump(StringBuilder sb) { - sb.append("BTAudio ").append(mTitle).append(":\n"); + sb.append(mTitle).append(":\n"); for (Event event : mEvents) { sb.append(" ").append(event.toString()).append("\n"); } diff --git a/android/app/src/com/android/bluetooth/audio_util/MediaPlayerList.java b/android/app/src/com/android/bluetooth/audio_util/MediaPlayerList.java index f598b7e5887..b05302e529a 100644 --- a/android/app/src/com/android/bluetooth/audio_util/MediaPlayerList.java +++ b/android/app/src/com/android/bluetooth/audio_util/MediaPlayerList.java @@ -36,6 +36,7 @@ import android.text.TextUtils; import android.util.Log; import android.view.KeyEvent; +import com.android.bluetooth.BluetoothEventLogger; import com.android.bluetooth.Utils; import com.android.internal.annotations.VisibleForTesting; @@ -71,9 +72,10 @@ public class MediaPlayerList { private static final int BLUETOOTH_PLAYER_ID = 0; private static final String BLUETOOTH_PLAYER_NAME = "Bluetooth Player"; private static final int ACTIVE_PLAYER_LOGGER_SIZE = 5; - private static final String ACTIVE_PLAYER_LOGGER_TITLE = "Active Player Events"; + private static final String ACTIVE_PLAYER_LOGGER_TITLE = "BTAudio Active Player Events"; private static final int AUDIO_PLAYBACK_STATE_LOGGER_SIZE = 15; - private static final String AUDIO_PLAYBACK_STATE_LOGGER_TITLE = "Audio Playback State Events"; + private static final String AUDIO_PLAYBACK_STATE_LOGGER_TITLE = + "BTAudio Audio Playback State Events"; // mediaId's for the now playing list will be in the form of "NowPlayingId[XX]" where [XX] // is the Queue ID for the requested item. @@ -90,10 +92,11 @@ public class MediaPlayerList { private MediaData mCurrMediaData = null; private final AudioManager mAudioManager; - private final BTAudioEventLogger mActivePlayerLogger = new BTAudioEventLogger( - ACTIVE_PLAYER_LOGGER_SIZE, ACTIVE_PLAYER_LOGGER_TITLE); - private final BTAudioEventLogger mAudioPlaybackStateLogger = new BTAudioEventLogger( - AUDIO_PLAYBACK_STATE_LOGGER_SIZE, AUDIO_PLAYBACK_STATE_LOGGER_TITLE); + private final BluetoothEventLogger mActivePlayerLogger = + new BluetoothEventLogger(ACTIVE_PLAYER_LOGGER_SIZE, ACTIVE_PLAYER_LOGGER_TITLE); + private final BluetoothEventLogger mAudioPlaybackStateLogger = + new BluetoothEventLogger( + AUDIO_PLAYBACK_STATE_LOGGER_SIZE, AUDIO_PLAYBACK_STATE_LOGGER_TITLE); private Map mMediaPlayers = Collections.synchronizedMap(new HashMap()); diff --git a/android/app/src/com/android/bluetooth/audio_util/MediaPlayerWrapper.java b/android/app/src/com/android/bluetooth/audio_util/MediaPlayerWrapper.java index aa85c956976..3225244b3be 100644 --- a/android/app/src/com/android/bluetooth/audio_util/MediaPlayerWrapper.java +++ b/android/app/src/com/android/bluetooth/audio_util/MediaPlayerWrapper.java @@ -26,6 +26,7 @@ import android.os.Looper; import android.os.Message; import android.util.Log; +import com.android.bluetooth.BluetoothEventLogger; import com.android.internal.annotations.GuardedBy; import com.android.internal.annotations.VisibleForTesting; @@ -45,13 +46,13 @@ public class MediaPlayerWrapper { static boolean sTesting = false; private static final int PLAYBACK_STATE_CHANGE_EVENT_LOGGER_SIZE = 5; private static final String PLAYBACK_STATE_CHANGE_LOGGER_EVENT_TITLE = - "Playback State change Event"; + "BTAudio Playback State change Event"; final Context mContext; private MediaController mMediaController; private String mPackageName; private Looper mLooper; - private final BTAudioEventLogger mPlaybackStateChangeEventLogger; + private final BluetoothEventLogger mPlaybackStateChangeEventLogger; private MediaData mCurrentData; @@ -88,8 +89,10 @@ public class MediaPlayerWrapper { mMediaController = controller; mPackageName = controller.getPackageName(); mLooper = looper; - mPlaybackStateChangeEventLogger = new BTAudioEventLogger( - PLAYBACK_STATE_CHANGE_EVENT_LOGGER_SIZE, PLAYBACK_STATE_CHANGE_LOGGER_EVENT_TITLE); + mPlaybackStateChangeEventLogger = + new BluetoothEventLogger( + PLAYBACK_STATE_CHANGE_EVENT_LOGGER_SIZE, + PLAYBACK_STATE_CHANGE_LOGGER_EVENT_TITLE); mCurrentData = new MediaData(null, null, null); mCurrentData.queue = Util.toMetadataList(mContext, getQueue()); diff --git a/android/app/src/com/android/bluetooth/avrcp/AvrcpTargetService.java b/android/app/src/com/android/bluetooth/avrcp/AvrcpTargetService.java index 61f6aaffc42..d9e84357597 100644 --- a/android/app/src/com/android/bluetooth/avrcp/AvrcpTargetService.java +++ b/android/app/src/com/android/bluetooth/avrcp/AvrcpTargetService.java @@ -32,11 +32,11 @@ import android.sysprop.BluetoothProperties; import android.text.TextUtils; import android.util.Log; +import com.android.bluetooth.BluetoothEventLogger; import com.android.bluetooth.BluetoothMetricsProto; import com.android.bluetooth.R; import com.android.bluetooth.Utils; import com.android.bluetooth.a2dp.A2dpService; -import com.android.bluetooth.audio_util.BTAudioEventLogger; import com.android.bluetooth.audio_util.MediaData; import com.android.bluetooth.audio_util.MediaPlayerList; import com.android.bluetooth.audio_util.MediaPlayerWrapper; @@ -63,10 +63,10 @@ public class AvrcpTargetService extends ProfileService { private static final int AVRCP_MAX_VOL = 127; private static final int MEDIA_KEY_EVENT_LOGGER_SIZE = 20; - private static final String MEDIA_KEY_EVENT_LOGGER_TITLE = "Media Key Events"; + private static final String MEDIA_KEY_EVENT_LOGGER_TITLE = "BTAudio Media Key Events"; private static int sDeviceMaxVolume = 0; - private final BTAudioEventLogger mMediaKeyEventLogger = new BTAudioEventLogger( - MEDIA_KEY_EVENT_LOGGER_SIZE, MEDIA_KEY_EVENT_LOGGER_TITLE); + private final BluetoothEventLogger mMediaKeyEventLogger = + new BluetoothEventLogger(MEDIA_KEY_EVENT_LOGGER_SIZE, MEDIA_KEY_EVENT_LOGGER_TITLE); private AvrcpVersion mAvrcpVersion; private MediaPlayerList mMediaPlayerList; diff --git a/android/app/src/com/android/bluetooth/avrcp/AvrcpVolumeManager.java b/android/app/src/com/android/bluetooth/avrcp/AvrcpVolumeManager.java index 4fcc2edb458..14a9dfdb24f 100644 --- a/android/app/src/com/android/bluetooth/avrcp/AvrcpVolumeManager.java +++ b/android/app/src/com/android/bluetooth/avrcp/AvrcpVolumeManager.java @@ -28,7 +28,7 @@ import android.media.AudioDeviceInfo; import android.media.AudioManager; import android.util.Log; -import com.android.bluetooth.audio_util.BTAudioEventLogger; +import com.android.bluetooth.BluetoothEventLogger; import com.android.internal.annotations.VisibleForTesting; import java.util.HashMap; @@ -42,7 +42,7 @@ class AvrcpVolumeManager extends AudioDeviceCallback { // All volumes are stored at system volume values, not AVRCP values private static final String VOLUME_MAP = "bluetooth_volume_map"; private static final String VOLUME_REJECTLIST = "absolute_volume_rejectlist"; - private static final String VOLUME_CHANGE_LOG_TITLE = "Volume Events"; + private static final String VOLUME_CHANGE_LOG_TITLE = "BTAudio Volume Events"; @VisibleForTesting static final int AVRCP_MAX_VOL = 127; @@ -50,8 +50,8 @@ class AvrcpVolumeManager extends AudioDeviceCallback { private static final int VOLUME_CHANGE_LOGGER_SIZE = 30; private static int sDeviceMaxVolume = 0; private static int sNewDeviceVolume = 0; - private final BTAudioEventLogger mVolumeEventLogger = new BTAudioEventLogger( - VOLUME_CHANGE_LOGGER_SIZE, VOLUME_CHANGE_LOG_TITLE); + private final BluetoothEventLogger mVolumeEventLogger = + new BluetoothEventLogger(VOLUME_CHANGE_LOGGER_SIZE, VOLUME_CHANGE_LOG_TITLE); Context mContext; AudioManager mAudioManager; -- GitLab From 6653a60c3c9d0b92d1862e2f3b4e0cc31879ae0d Mon Sep 17 00:00:00 2001 From: Jakub Tyszkowski Date: Wed, 17 May 2023 11:29:28 +0000 Subject: [PATCH 0102/2405] MediaControl: Improve logging Adds the event history logging and improves the existing logs. Bug: 278964409 Test: atest BluetoothInstrumentationTests Change-Id: I1f44a3efd67f26f48ad11f2da68734c10c1679fb --- .../mcp/MediaControlGattService.java | 205 ++++++++++++++---- .../bluetooth/mcp/MediaControlProfile.java | 117 +++++++--- .../com/android/bluetooth/mcp/MediaState.java | 16 ++ .../com/android/bluetooth/mcp/Request.java | 69 ++++++ .../mcp/MediaControlGattServiceTest.java | 8 +- 5 files changed, 337 insertions(+), 78 deletions(-) diff --git a/android/app/src/com/android/bluetooth/mcp/MediaControlGattService.java b/android/app/src/com/android/bluetooth/mcp/MediaControlGattService.java index 36bfa45d3a0..f4f8d2f1d15 100644 --- a/android/app/src/com/android/bluetooth/mcp/MediaControlGattService.java +++ b/android/app/src/com/android/bluetooth/mcp/MediaControlGattService.java @@ -47,6 +47,7 @@ import android.os.RemoteException; import android.util.Log; import android.util.Pair; +import com.android.bluetooth.BluetoothEventLogger; import com.android.bluetooth.Utils; import com.android.bluetooth.a2dp.A2dpService; import com.android.bluetooth.btservice.AdapterService; @@ -133,7 +134,7 @@ public class MediaControlGattService implements MediaControlGattServiceInterface private static final int INTERVAL_UNAVAILABLE = 0xFFFFFFFF; private final int mCcid; - private HashMap> mCccDescriptorValues; + private Map> mCccDescriptorValues = new HashMap<>(); private long mFeatures; private Context mContext; private MediaControlServiceCallbacks mCallbacks; @@ -147,6 +148,9 @@ public class MediaControlGattService implements MediaControlGattServiceInterface private LeAudioService mLeAudioService; private AdapterService mAdapterService; + private static final int LOG_NB_EVENTS = 200; + private final BluetoothEventLogger mEventLogger; + private static String mcsUuidToString(UUID uuid) { if (uuid.equals(UUID_PLAYER_NAME)) { return "PLAYER_NAME"; @@ -388,9 +392,20 @@ public class MediaControlGattService implements MediaControlGattServiceInterface } private void onUnauthorizedGattOperation(BluetoothDevice device, GattOpContext op) { - if (VDBG) { - Log.d(TAG, "onUnauthorizedGattOperation device: " + device); - } + UUID charUuid = + (op.mCharacteristic != null + ? op.mCharacteristic.getUuid() + : (op.mDescriptor != null + ? op.mDescriptor.getCharacteristic().getUuid() + : null)); + mEventLogger.logw( + TAG, + "onUnauthorizedGattOperation: device= " + + device + + ", opcode= " + + op.mOperation + + ", characteristic= " + + (charUuid != null ? mcsUuidToString(charUuid) : "UNKNOWN")); synchronized (mPendingGattOperations) { List operations = mPendingGattOperations.get(device); @@ -408,11 +423,23 @@ public class MediaControlGattService implements MediaControlGattServiceInterface } private void onAuthorizedGattOperation(BluetoothDevice device, GattOpContext op) { - int status = BluetoothGatt.GATT_SUCCESS; + UUID charUuid = + (op.mCharacteristic != null + ? op.mCharacteristic.getUuid() + : (op.mDescriptor != null + ? op.mDescriptor.getCharacteristic().getUuid() + : null)); + mEventLogger.logd( + DBG, + TAG, + "onAuthorizedGattOperation: device= " + + device + + ", opcode= " + + op.mOperation + + ", characteristic= " + + (charUuid != null ? mcsUuidToString(charUuid) : "UNKNOWN")); - if (VDBG) { - Log.d(TAG, "onAuthorizedGattOperation device: " + device); - } + int status = BluetoothGatt.GATT_SUCCESS; switch (op.mOperation) { case READ_CHARACTERISTIC: @@ -511,7 +538,20 @@ public class MediaControlGattService implements MediaControlGattServiceInterface } private void onRejectedAuthorizationGattOperation(BluetoothDevice device, GattOpContext op) { - Log.w(TAG, "onRejectedAuthorizationGattOperation device: " + device); + UUID charUuid = + (op.mCharacteristic != null + ? op.mCharacteristic.getUuid() + : (op.mDescriptor != null + ? op.mDescriptor.getCharacteristic().getUuid() + : null)); + mEventLogger.logw( + TAG, + "onRejectedAuthorizationGattOperation: device= " + + device + + ", opcode= " + + op.mOperation + + ", characteristic= " + + (charUuid != null ? mcsUuidToString(charUuid) : "UNKNOWN")); switch (op.mOperation) { case READ_CHARACTERISTIC: @@ -548,7 +588,7 @@ public class MediaControlGattService implements MediaControlGattServiceInterface private void ClearUnauthorizedGattOperations(BluetoothDevice device) { if (VDBG) { - Log.d(TAG, "ClearUnauthorizedGattOperations device: " + device); + Log.d(TAG, "ClearUnauthorizedGattOperations: device= " + device); } synchronized (mPendingGattOperations) { @@ -558,7 +598,7 @@ public class MediaControlGattService implements MediaControlGattServiceInterface private void ProcessPendingGattOperations(BluetoothDevice device) { if (VDBG) { - Log.d(TAG, "ProcessPendingGattOperations device: " + device); + Log.d(TAG, "ProcessPendingGattOperations: device= " + device); } synchronized (mPendingGattOperations) { @@ -589,6 +629,10 @@ public class MediaControlGattService implements MediaControlGattServiceInterface /* Restore CCCD values for device */ for (ParcelUuid uuid : uuidList) { + mEventLogger.logd( + DBG, + TAG, + "restoreCccValuesForStoredDevices: device= " + device + ", char= " + uuid); setCcc(device, uuid.getUuid(), 0, BluetoothGattDescriptor.ENABLE_NOTIFICATION_VALUE, false); } @@ -797,6 +841,7 @@ public class MediaControlGattService implements MediaControlGattServiceInterface } private void setInitialCharacteristicValues(boolean notify) { + mEventLogger.logd(DBG, TAG, "setInitialCharacteristicValues"); updateMediaStateChar(mCurrentMediaState.getValue()); updatePlayerNameChar("", notify); updatePlayerIconUrlChar(""); @@ -889,11 +934,13 @@ public class MediaControlGattService implements MediaControlGattServiceInterface throw e.rethrowFromSystemServer(); } } + + mEventLogger = + new BluetoothEventLogger( + LOG_NB_EVENTS, TAG + " instance (CCID= " + ccid + ") event log"); } protected boolean init(UUID scvUuid) { - mCccDescriptorValues = new HashMap<>(); - mFeatures = mCallbacks.onGetFeatureFlags(); // Verify the minimum required set of supported player features @@ -903,20 +950,25 @@ public class MediaControlGattService implements MediaControlGattServiceInterface return false; } + mEventLogger.add("Initializing"); + // Init attribute database return initGattService(scvUuid); } private void handleObjectIdRequest(int objField, long objId) { + mEventLogger.add("handleObjectIdRequest: obj= " + objField + ", objId= " + objId); mCallbacks.onSetObjectIdRequest(objField, objId); } private void handlePlayingOrderRequest(int order) { + mEventLogger.add("handlePlayingOrderRequest: order= " + order); mCallbacks.onPlayingOrderSetRequest(order); } private void handlePlaybackSpeedRequest(int speed) { float floatingSpeed = (float) Math.pow(2, speed / 64); + mEventLogger.add("handlePlaybackSpeedRequest: floatingSpeed= " + floatingSpeed); mCallbacks.onPlaybackSpeedSetRequest(floatingSpeed); } @@ -924,7 +976,7 @@ public class MediaControlGattService implements MediaControlGattServiceInterface final long positionMs = (position != INTERVAL_UNAVAILABLE) ? mcsIntervalToMilliseconds(position) : TRACK_POSITION_UNAVAILABLE; - + mEventLogger.add("handleTrackPositionRequest: positionMs= " + positionMs); mCallbacks.onTrackPositionSetRequest(positionMs); } @@ -979,11 +1031,12 @@ public class MediaControlGattService implements MediaControlGattServiceInterface } Request req = new Request(opcode, intVal); - - if (DBG) { - Log.d(TAG, "handleMediaControlPointRequest: sending " + Request.Opcodes.toString(opcode) - + " request up"); - } + mEventLogger.logd( + DBG, + TAG, + "handleMediaControlPointRequest: sending " + + Request.Opcodes.toString(opcode) + + " request up"); // TODO: Activate/deactivate devices with ActiveDeviceManager if (req.getOpcode() == Request.Opcodes.PLAY) { @@ -1023,9 +1076,7 @@ public class MediaControlGattService implements MediaControlGattServiceInterface } private boolean initGattService(UUID serviceUuid) { - if (DBG) { - Log.d(TAG, "initGattService uuid: " + serviceUuid); - } + mEventLogger.logd(DBG, TAG, "initGattService: uuid= " + serviceUuid); if (mBluetoothGattServer == null) { BluetoothManager manager = mContext.getSystemService(BluetoothManager.class); @@ -1099,6 +1150,10 @@ public class MediaControlGattService implements MediaControlGattServiceInterface uuidList.remove(charUuid); + mEventLogger.logd( + DBG, + TAG, + "removeUuidFromMetadata: device= " + device + ", char= " + charUuid.toString()); if (!device.setMetadata(METADATA_GMCS_CCCD, Utils.uuidsToByteArray(uuidList.toArray(new ParcelUuid[0])))) { Log.e(TAG, "Can't set CCCD for GMCS characteristic UUID: " + charUuid.toString() @@ -1123,6 +1178,10 @@ public class MediaControlGattService implements MediaControlGattServiceInterface uuidList.add(charUuid); + mEventLogger.logd( + DBG, + TAG, + "addUuidToMetadata: device= " + device + ", char= " + charUuid.toString()); if (!device.setMetadata(METADATA_GMCS_CCCD, Utils.uuidsToByteArray(uuidList.toArray(new ParcelUuid[0])))) { Log.e(TAG, "Can't set CCCD for GMCS characteristic UUID: " + charUuid.toString() @@ -1132,7 +1191,7 @@ public class MediaControlGattService implements MediaControlGattServiceInterface @VisibleForTesting void setCcc(BluetoothDevice device, UUID charUuid, int offset, byte[] value, boolean store) { - HashMap characteristicCcc = mCccDescriptorValues.get(device.getAddress()); + Map characteristicCcc = mCccDescriptorValues.get(device.getAddress()); if (characteristicCcc == null) { characteristicCcc = new HashMap<>(); mCccDescriptorValues.put(device.getAddress(), characteristicCcc); @@ -1146,8 +1205,10 @@ public class MediaControlGattService implements MediaControlGattServiceInterface } if (Arrays.equals(value, BluetoothGattDescriptor.ENABLE_NOTIFICATION_VALUE)) { + mEventLogger.add("setCcc: device= " + device + ", notify= " + true); addUuidToMetadata(new ParcelUuid(charUuid), device); } else if (Arrays.equals(value, BluetoothGattDescriptor.DISABLE_NOTIFICATION_VALUE)) { + mEventLogger.add("setCcc: device= " + device + ", notify= " + false); removeUuidFromMetadata(new ParcelUuid(charUuid), device); } else { Log.e(TAG, "Not handled CCC value: " + Arrays.toString(value)); @@ -1196,14 +1257,12 @@ public class MediaControlGattService implements MediaControlGattServiceInterface @VisibleForTesting void updateMediaStateChar(int state) { if (DBG) { - Log.d(TAG, "updateMediaStateChar"); + Log.d(TAG, "updateMediaStateChar: state= " + MediaState.toString(state)); } if (!isFeatureSupported(ServiceFeature.MEDIA_STATE)) return; - if (DBG) { - Log.d(TAG, "updateMediaStateChar setting to state= " + state); - } + mEventLogger.logd(DBG, TAG, "updateMediaStateChar: state= " + MediaState.toString(state)); BluetoothGattCharacteristic stateChar = mCharacteristics.get(CharId.MEDIA_STATE); @@ -1219,6 +1278,13 @@ public class MediaControlGattService implements MediaControlGattServiceInterface if (!isFeatureSupported(feature)) return; + mEventLogger.logd( + DBG, + TAG, + "updateObjectIdChar: charId= " + + CharId.FromFeature(feature) + + ", objId= " + + objectIdValue); updateObjectIdChar(mCharacteristics.get(CharId.FromFeature(feature)), objectIdValue, null, notify); } @@ -1420,6 +1486,18 @@ public class MediaControlGattService implements MediaControlGattServiceInterface @Override public void onDeviceAuthorizationSet(BluetoothDevice device) { + int auth = getDeviceAuthorization(device); + mEventLogger.logd( + DBG, + TAG, + "onDeviceAuthorizationSet: device= " + + device + + ", authorization= " + + (auth == BluetoothDevice.ACCESS_ALLOWED + ? "ALLOWED" + : (auth == BluetoothDevice.ACCESS_REJECTED + ? "REJECTED" + : "UNKNOWN"))); ProcessPendingGattOperations(device); } @@ -1445,7 +1523,7 @@ public class MediaControlGattService implements MediaControlGattServiceInterface @VisibleForTesting void updatePlayingOrderChar(PlayingOrder order, boolean notify) { if (VDBG) { - Log.d(TAG, "updatePlayingOrderChar: " + order); + Log.d(TAG, "updatePlayingOrderChar: order= " + order); } if (!isFeatureSupported(ServiceFeature.PLAYING_ORDER)) return; @@ -1461,6 +1539,7 @@ public class MediaControlGattService implements MediaControlGattServiceInterface if (notify && isFeatureSupported(ServiceFeature.PLAYING_ORDER_NOTIFY)) { notifyCharacteristic(orderChar, null); } + mEventLogger.logd(DBG, TAG, "updatePlayingOrderChar: order= " + order); } } @@ -1472,19 +1551,22 @@ public class MediaControlGattService implements MediaControlGattServiceInterface continue; } - HashMap charCccMap = mCccDescriptorValues.get(device.getAddress()); + Map charCccMap = mCccDescriptorValues.get(device.getAddress()); if (charCccMap == null) continue; byte[] ccc = getCccBytes(device, characteristic.getUuid()); if (VDBG) { - Log.d(TAG, "notifyCharacteristic char= " + characteristic.getUuid().toString() - + " cccVal= " - + ByteBuffer.wrap(ccc).order(ByteOrder.LITTLE_ENDIAN).getShort()); + Log.d( + TAG, + "notifyCharacteristic: char= " + + characteristic.getUuid().toString() + + " cccVal= " + + ByteBuffer.wrap(ccc).order(ByteOrder.LITTLE_ENDIAN).getShort()); } if (!Arrays.equals(ccc, BluetoothGattDescriptor.ENABLE_NOTIFICATION_VALUE)) continue; - if (VDBG) Log.d(TAG, "notifyCharacteristic sending notification"); + if (VDBG) Log.d(TAG, "notifyCharacteristic: sending notification"); mBluetoothGattServer.notifyCharacteristicChanged(device, characteristic, false); } @@ -1529,7 +1611,7 @@ public class MediaControlGattService implements MediaControlGattServiceInterface @VisibleForTesting void updateSeekingSpeedChar(float speed, boolean notify) { if (VDBG) { - Log.d(TAG, "updateSeekingSpeedChar: " + speed); + Log.d(TAG, "updateSeekingSpeedChar: speed= " + speed); } if (isFeatureSupported(ServiceFeature.SEEKING_SPEED)) { if ((getSeekingSpeedChar() == null) || (getSeekingSpeedChar() != speed)) { @@ -1540,6 +1622,10 @@ public class MediaControlGattService implements MediaControlGattServiceInterface if (notify && isFeatureSupported(ServiceFeature.SEEKING_SPEED_NOTIFY)) { notifyCharacteristic(characteristic, null); } + mEventLogger.logd( + DBG, + TAG, + "updateSeekingSpeedChar: intSpeed=" + intSpeed + ", speed= " + speed); } } } @@ -1577,6 +1663,10 @@ public class MediaControlGattService implements MediaControlGattServiceInterface if (notify && isFeatureSupported(ServiceFeature.PLAYBACK_SPEED_NOTIFY)) { notifyCharacteristic(characteristic, null); } + mEventLogger.logd( + DBG, + TAG, + "updatePlaybackSpeedChar: intSpeed=" + intSpeed + ", speed= " + speed); } } @@ -1604,6 +1694,10 @@ public class MediaControlGattService implements MediaControlGattServiceInterface notifyCharacteristic(characteristic, null); } } + mEventLogger.logd( + DBG, + TAG, + "updateTrackPositionChar: positionMs= " + positionMs + ", position= " + position); } private long getTrackDurationChar() { @@ -1635,6 +1729,13 @@ public class MediaControlGattService implements MediaControlGattServiceInterface if (notify && isFeatureSupported(ServiceFeature.TRACK_DURATION_NOTIFY)) { notifyCharacteristic(characteristic, null); } + mEventLogger.logd( + DBG, + TAG, + "updateTrackDurationChar: durationMs= " + + durationMs + + ", duration= " + + duration); } } @@ -1662,15 +1763,18 @@ public class MediaControlGattService implements MediaControlGattServiceInterface if (notify && isFeatureSupported(ServiceFeature.TRACK_TITLE_NOTIFY)) { notifyCharacteristic(characteristic, null); } + mEventLogger.logd(DBG, TAG, "updateTrackTitleChar: title= '" + title + "'"); } } @VisibleForTesting void updateSupportedOpcodesChar(int opcodes, boolean notify) { if (VDBG) { - Log.d(TAG, "updateSupportedOpcodesChar: " + opcodes); + Log.d( + TAG, + "updateSupportedOpcodesChar: opcodes= " + + Request.SupportedOpcodes.toString(opcodes)); } - if (!isFeatureSupported(ServiceFeature.MEDIA_CONTROL_POINT_OPCODES_SUPPORTED)) return; BluetoothGattCharacteristic characteristic = mCharacteristics.get( @@ -1681,17 +1785,17 @@ public class MediaControlGattService implements MediaControlGattServiceInterface return; } - if (VDBG) { - Log.d(TAG, "updateSupportedOpcodesChar setting char"); - } - characteristic.setValue(opcodes, BluetoothGattCharacteristic.FORMAT_UINT32, 0); if (notify && isFeatureSupported( ServiceFeature.MEDIA_CONTROL_POINT_OPCODES_SUPPORTED_NOTIFY)) { notifyCharacteristic(characteristic, null); } - + mEventLogger.logd( + DBG, + TAG, + "updateSupportedOpcodesChar: opcodes= " + + Request.SupportedOpcodes.toString(opcodes)); } @VisibleForTesting @@ -1702,11 +1806,20 @@ public class MediaControlGattService implements MediaControlGattServiceInterface if (isFeatureSupported(ServiceFeature.PLAYING_ORDER_SUPPORTED)) { mCharacteristics.get(CharId.PLAYING_ORDER_SUPPORTED) .setValue(supportedOrder, BluetoothGattCharacteristic.FORMAT_UINT16, 0); + mEventLogger.logd( + DBG, TAG, "updatePlayingOrderSupportedChar: order= " + supportedOrder); } } private void updateIconObjIdChar(Long objId) { if (isFeatureSupported(ServiceFeature.PLAYER_ICON_OBJ_ID)) { + mEventLogger.logd( + DBG, + TAG, + "updateObjectIdChar charId= " + + CharId.PLAYER_ICON_OBJ_ID + + ", objId= " + + objId); updateObjectIdChar(mCharacteristics.get(CharId.PLAYER_ICON_OBJ_ID), objId, null, true); } @@ -1751,6 +1864,7 @@ public class MediaControlGattService implements MediaControlGattServiceInterface } if (isFeatureSupported(ServiceFeature.PLAYER_ICON_URL)) { mCharacteristics.get(CharId.PLAYER_ICON_URL).setValue(url); + mEventLogger.logd(DBG, TAG, "updatePlayerIconUrlChar: " + url); } } @@ -1775,6 +1889,7 @@ public class MediaControlGattService implements MediaControlGattServiceInterface BluetoothGattCharacteristic characteristic = mCharacteristics.get(CharId.PLAYER_NAME); characteristic.setValue(name); + mEventLogger.logd(DBG, TAG, "updatePlayerNameChar: name= '" + name + "'"); if (notify && isFeatureSupported(ServiceFeature.PLAYER_NAME_NOTIFY)) { notifyCharacteristic(characteristic, null); } @@ -2000,7 +2115,7 @@ public class MediaControlGattService implements MediaControlGattServiceInterface } public void dump(StringBuilder sb) { - sb.append("\tMediaControlService instance:"); + sb.append("\tMediaControlService instance current state:"); sb.append("\n\t\tCcid = " + mCcid); sb.append("\n\t\tFeatures:" + ServiceFeature.featuresToString(mFeatures, "\n\t\t\t")); @@ -2013,8 +2128,7 @@ public class MediaControlGattService implements MediaControlGattServiceInterface } sb.append("\n\t\tCurrentPlaybackState = " + mCurrentMediaState); - for (Map.Entry> deviceEntry - : mCccDescriptorValues.entrySet()) { + for (Map.Entry> deviceEntry : mCccDescriptorValues.entrySet()) { sb.append("\n\t\tCCC states for device: " + "xx:xx:xx:xx:" + deviceEntry.getKey().substring(12)); for (Map.Entry entry : deviceEntry.getValue().entrySet()) { @@ -2022,5 +2136,8 @@ public class MediaControlGattService implements MediaControlGattServiceInterface + Utils.cccIntToStr(entry.getValue())); } } + + sb.append("\n\n"); + mEventLogger.dump(sb); } } diff --git a/android/app/src/com/android/bluetooth/mcp/MediaControlProfile.java b/android/app/src/com/android/bluetooth/mcp/MediaControlProfile.java index e44ce9ccd48..e957addea4f 100644 --- a/android/app/src/com/android/bluetooth/mcp/MediaControlProfile.java +++ b/android/app/src/com/android/bluetooth/mcp/MediaControlProfile.java @@ -30,6 +30,7 @@ import android.os.Looper; import android.os.SystemClock; import android.util.Log; +import com.android.bluetooth.BluetoothEventLogger; import com.android.bluetooth.audio_util.MediaData; import com.android.bluetooth.audio_util.MediaPlayerList; import com.android.bluetooth.audio_util.MediaPlayerWrapper; @@ -59,6 +60,9 @@ public class MediaControlProfile implements MediaControlServiceCallbacks { private static final boolean DBG = Log.isLoggable(TAG, Log.DEBUG); private final Context mContext; + private static final int LOG_NB_EVENTS = 100; + private final BluetoothEventLogger mEventLogger; + // Media players data private MediaPlayerList mMediaPlayerList; private MediaData mCurrentData; @@ -84,9 +88,16 @@ public class MediaControlProfile implements MediaControlServiceCallbacks { boolean state = !MediaPlayerWrapper.playstateEquals(mCurrentData.state, data.state); boolean queue = !Objects.equals(mCurrentData.queue, data.queue); - if (DBG) { - Log.d(TAG, "onMediaUpdated: track_changed=" + metadata + " state=" + state - + " queue=" + queue); + if (metadata || state || queue) { + mEventLogger.logd( + DBG, + TAG, + "onMediaUpdated: track_changed=" + + metadata + + " state_changed=" + + state + + " queue_changed=" + + queue); } mCurrentData = data; @@ -98,10 +109,15 @@ public class MediaControlProfile implements MediaControlServiceCallbacks { @Override public void run(boolean availablePlayers, boolean addressedPlayers, boolean uids) { - if (DBG) { - Log.d(TAG, "onFolderUpdated: available_players= " + availablePlayers - + " addressedPlayers=" + addressedPlayers + " uids=" + uids); - } + mEventLogger.logd( + DBG, + TAG, + "onFolderUpdated: available_players= " + + availablePlayers + + " addressedPlayers=" + + addressedPlayers + + " uids=" + + uids); } } @@ -133,11 +149,11 @@ public class MediaControlProfile implements MediaControlServiceCallbacks { if (stateChanged) { if (mCurrentData.state != null) { - if (DBG) Log.d(TAG, "onCurrentPlayerStateUpdated state."); MediaState playback_state = playerState2McsState(mCurrentData.state.getState()); state_map.put(PlayerStateField.PLAYBACK_STATE, playback_state); - state_map.put(PlayerStateField.OPCODES_SUPPORTED, - playerActions2McsSupportedOpcodes(mCurrentData.state.getActions())); + + int opcodes = playerActions2McsSupportedOpcodes(mCurrentData.state.getActions()); + state_map.put(PlayerStateField.OPCODES_SUPPORTED, opcodes); if (playback_state != MediaState.INACTIVE) { state_map.put( @@ -147,6 +163,19 @@ public class MediaControlProfile implements MediaControlServiceCallbacks { state_map.put(PlayerStateField.TRACK_POSITION, getDriftCorrectedTrackPosition(mCurrentData.state)); } + + mEventLogger.logd( + DBG, + TAG, + "onCurrentPlayerStateUpdated state= " + + playback_state + + ", supported opcodes= " + + Request.SupportedOpcodes.toString(opcodes) + + ", track position= " + + getDriftCorrectedTrackPosition(mCurrentData.state) + + " (" + + mCurrentData.state.getPosition() + + ")"); } else { // Just update the state and the service should set it's characteristics as required state_map.put(PlayerStateField.PLAYBACK_STATE, MediaState.INACTIVE); @@ -155,11 +184,13 @@ public class MediaControlProfile implements MediaControlServiceCallbacks { if (metadataChanged) { if (mCurrentData.metadata != null) { - if (DBG) { - Log.d(TAG, "onCurrentPlayerStateUpdated metadata: title= " - + mCurrentData.metadata.title + " duration= " - + mCurrentData.metadata.duration); - } + mEventLogger.logd( + DBG, + TAG, + "onCurrentPlayerStateUpdated metadata: title= '" + + mCurrentData.metadata.title + + "', duration= " + + mCurrentData.metadata.duration); state_map.put(PlayerStateField.TRACK_DURATION, mCurrentData.metadata.duration != null @@ -215,18 +246,20 @@ public class MediaControlProfile implements MediaControlServiceCallbacks { } else { mMediaPlayerList = new MediaPlayerList(Looper.myLooper(), mContext); } + + mEventLogger = new BluetoothEventLogger(LOG_NB_EVENTS, TAG + " event log"); } @Override public void onServiceInstanceRegistered(ServiceStatus status, MediaControlGattServiceInterface service) { - if (DBG) Log.d(TAG, "onServiceInstanceRegistered: status= " + status); + mEventLogger.logd(DBG, TAG, "onServiceInstanceRegistered: status= " + status); mGMcsService = service; } @Override public void onServiceInstanceUnregistered(ServiceStatus status) { - if (DBG) Log.d(TAG, "GMCS onServiceInstanceUnregistered: status= " + status); + mEventLogger.logd(DBG, TAG, "onServiceInstanceUnregistered: status= " + status); mGMcsService = null; } @@ -277,13 +310,13 @@ public class MediaControlProfile implements MediaControlServiceCallbacks { @Override public long onGetCurrentTrackPosition() { - if (DBG) Log.d(TAG, "getCurrentTrackPosition"); + mEventLogger.logd(DBG, TAG, "getCurrentTrackPosition"); return getLatestTrackPosition(); } @Override public void onTrackPositionSetRequest(long position) { - if (DBG) Log.d(TAG, "GMCS onTrackPositionSetRequest"); + mEventLogger.logd(DBG, TAG, "GMCS onTrackPositionSetRequest"); if (mMediaPlayerList.getActivePlayer() == null) return; if ((mCurrentData.state.getActions() & PlaybackState.ACTION_SEEK_TO) != 0) { @@ -301,41 +334,44 @@ public class MediaControlProfile implements MediaControlServiceCallbacks { @Override public void onCurrentTrackMetadataRequest() { - if (DBG) Log.d(TAG, "GMCS onCurrentTrackMetadataRequest"); + mEventLogger.logd(DBG, TAG, "GMCS onCurrentTrackMetadataRequest"); // FIXME: Seems to be not used right now } @Override public void onPlayingOrderSetRequest(int order) { - if (DBG) Log.d(TAG, "GMCS onPlayingOrderSetRequest"); + mEventLogger.logd(DBG, TAG, "GMCS onPlayingOrderSetRequest"); // Notice: MediaPlayerWrapper does not support play order control. // Ignore the request for now. } @Override public void onPlaybackSpeedSetRequest(float speed) { - if (DBG) Log.d(TAG, "GMCS onPlaybackSpeedSetRequest"); + mEventLogger.logd(DBG, TAG, "GMCS onPlaybackSpeedSetRequest"); if (mMediaPlayerList.getActivePlayer() == null) return; mMediaPlayerList.getActivePlayer().setPlaybackSpeed(speed); } @Override public void onSetObjectIdRequest(int objField, long objectId) { - if (DBG) Log.d(TAG, "GMCS onSetObjectIdRequest"); + mEventLogger.logd(DBG, TAG, "GMCS onSetObjectIdRequest"); // TODO: Implement once we have the Object Transfer Service } @Override public void onSearchRequest(SearchRequest request) { - if (DBG) Log.d(TAG, "GMCS onSearchRequest"); + mEventLogger.logd(DBG, TAG, "GMCS onSearchRequest"); // TODO: Implement once we have the Object Transfer Service } @Override public void onMediaControlRequest(Request request) { - if (DBG) Log.d(TAG, "GMCS onMediaControlRequest: posted task"); - + mEventLogger.logd( + DBG, + TAG, + "GMCS onMediaControlRequest: opcode= " + + Request.Opcodes.toString(request.getOpcode())); Request.Results status = Request.Results.COMMAND_CANNOT_BE_COMPLETED; if (mMediaPlayerList.getActivePlayer() == null && mGMcsService != null) { @@ -508,9 +544,6 @@ public class MediaControlProfile implements MediaControlServiceCallbacks { // PlaybackState.ACTION_PREPARE_FROM_SEARCH // PlaybackState.ACTION_PREPARE_FROM_URI - if (DBG) { - Log.d(TAG, "updateSupportedOpcodes setting supported opcodes to: " + opcodesSupported); - } return opcodesSupported; } @@ -583,9 +616,15 @@ public class MediaControlProfile implements MediaControlServiceCallbacks { break; case OPCODES_SUPPORTED: if (mCurrentData.state != null) { - handled_request_map.put(settings_field, + int opcodes = playerActions2McsSupportedOpcodes( - mCurrentData.state.getActions())); + mCurrentData.state.getActions()); + handled_request_map.put(settings_field, opcodes); + mEventLogger.logd( + DBG, + TAG, + "updateSupportedOpcodes setting supported opcodes to: " + + opcodes); } break; } @@ -689,6 +728,14 @@ public class MediaControlProfile implements MediaControlServiceCallbacks { // Only the bluetooth app is allowed to create generic media control service boolean isGenericMcs = appToken.equals(mContext.getPackageName()); + mEventLogger.logd( + DBG, + TAG, + "Register MediaControlGattService instance ccid= " + + ccid + + ", features= " + + ServiceFeature.featuresToString(SUPPORTED_FEATURES, "\n\t\t\t")); + MediaControlGattService svc = new MediaControlGattService(mMcpService, this, ccid); svc.init(isGenericMcs ? BluetoothUuid.GENERIC_MEDIA_CONTROL.getUuid() : BluetoothUuid.MEDIA_CONTROL.getUuid()); @@ -758,7 +805,7 @@ public class MediaControlProfile implements MediaControlServiceCallbacks { private final Map mServiceMap; public void unregisterServiceInstance(String appToken) { - Log.d(TAG, "unregisterServiceInstance"); + mEventLogger.logd(DBG, TAG, "unregisterServiceInstance"); synchronized (mServiceMap) { MediaControlGattServiceInterface service = mServiceMap.get(appToken); @@ -784,9 +831,13 @@ public class MediaControlProfile implements MediaControlServiceCallbacks { } public void dump(StringBuilder sb) { - sb.append("Media Control Service instance list:\n"); + sb.append("Media Control Service instance list:\n"); for (MediaControlGattServiceInterface svc : mServiceMap.values()) { svc.dump(sb); + sb.append("\n"); } + + mEventLogger.dump(sb); + sb.append("\n"); } } diff --git a/android/app/src/com/android/bluetooth/mcp/MediaState.java b/android/app/src/com/android/bluetooth/mcp/MediaState.java index a7f69c0c371..a543d413c5d 100644 --- a/android/app/src/com/android/bluetooth/mcp/MediaState.java +++ b/android/app/src/com/android/bluetooth/mcp/MediaState.java @@ -37,4 +37,20 @@ public enum MediaState { public int getValue() { return mValue; } + + /** Converts the state to string. */ + public static String toString(int value) { + switch (value) { + case 0x00: + return "INACTIVE(0x00)"; + case 0x01: + return "PLAYING(0x01)"; + case 0x02: + return "PAUSED(0x02)"; + case 0x03: + return "SEEKING(0x03)"; + default: + return "UNKNOWN(0x" + Integer.toHexString(value) + ")"; + } + } } diff --git a/android/app/src/com/android/bluetooth/mcp/Request.java b/android/app/src/com/android/bluetooth/mcp/Request.java index c100a6b9458..cb656a966ea 100644 --- a/android/app/src/com/android/bluetooth/mcp/Request.java +++ b/android/app/src/com/android/bluetooth/mcp/Request.java @@ -103,6 +103,75 @@ public final class Request { public static final int FIRST_GROUP = 0x040000; public static final int LAST_GROUP = 0x080000; public static final int GOTO_GROUP = 0x100000; + + static String toString(int opcodes) { + StringBuilder sb = new StringBuilder(); + boolean is_complex = false; + + sb.append("0x" + Integer.toHexString(opcodes) + " ("); + for (int i = 1; i <= opcodes; i <<= 1) { + int opcode = opcodes & i; + if (opcode != 0) { + if (is_complex) { + sb.append(" | "); + } else { + is_complex = true; + } + sb.append(singleOpcodeToString(opcode)); + } + } + sb.append(")"); + return sb.toString(); + } + + private static String singleOpcodeToString(int opcode) { + switch (opcode) { + case 0x01: + return "PLAY"; + case 0x02: + return "PAUSE"; + case 0x04: + return "FAST_REWIND"; + case 0x08: + return "FAST_FORWARD"; + case 0x10: + return "STOP"; + case 0x20: + return "MOVE_RELATIVE"; + case 0x40: + return "PREVIOUS_SEGMENT"; + case 0x80: + return "NEXT_SEGMENT"; + case 0x0100: + return "FIRST_SEGMENT"; + case 0x0200: + return "LAST_SEGMENT"; + case 0x0400: + return "GOTO_SEGMENT"; + case 0x0800: + return "PREVIOUS_TRACK"; + case 0x1000: + return "NEXT_TRACK"; + case 0x2000: + return "FIRST_TRACK"; + case 0x4000: + return "LAST_TRACK"; + case 0x8000: + return "GOTO_TRACK"; + case 0x010000: + return "PREVIOUS_GROUP"; + case 0x020000: + return "NEXT_GROUP"; + case 0x040000: + return "FIRST_GROUP"; + case 0x080000: + return "LAST_GROUP"; + case 0x100000: + return "GOTO_GROUP"; + default: + return "0x" + Integer.toHexString(opcode); + } + } } /** diff --git a/android/app/tests/unit/src/com/android/bluetooth/mcp/MediaControlGattServiceTest.java b/android/app/tests/unit/src/com/android/bluetooth/mcp/MediaControlGattServiceTest.java index 9e415873dcb..d7f95f50926 100644 --- a/android/app/tests/unit/src/com/android/bluetooth/mcp/MediaControlGattServiceTest.java +++ b/android/app/tests/unit/src/com/android/bluetooth/mcp/MediaControlGattServiceTest.java @@ -32,7 +32,6 @@ import androidx.test.InstrumentationRegistry; import androidx.test.filters.MediumTest; import androidx.test.runner.AndroidJUnit4; -import com.android.bluetooth.R; import com.android.bluetooth.TestUtils; import com.android.bluetooth.btservice.AdapterService; import com.android.bluetooth.le_audio.LeAudioService; @@ -1187,4 +1186,11 @@ public class MediaControlGattServiceTest { state_map.put(PlayerStateField.PLAYBACK_STATE, playback_state); mMcpService.updatePlayerState(state_map); } + + @Test + public void testDumpDoesNotCrash() { + mMcpService.dump(new StringBuilder()); + BluetoothGattService service = initAllFeaturesGattService(); + mMcpService.dump(new StringBuilder()); + } } -- GitLab From aa63e449fce69d2682023bf7f1b90244249479ee Mon Sep 17 00:00:00 2001 From: Jakub Tyszkowski Date: Mon, 15 May 2023 14:07:18 +0000 Subject: [PATCH 0103/2405] MediaControl: Allow basic GATT ops before authorized by LeAudioService Before authorized by LeAudioService, the device should be able to read GATT attributes without errors, but will get just some basic inf and filtered-out data. This is to prevent some of the devices to giving up on MCP control when they receive the first unathorized error response for GATT operation on MCS. Bug: 282938041 Test: atest BluetoothInstrumentationTests Change-Id: I1bc365ab3a7cff662a7480fa2b895024cdd2c93c --- .../mcp/MediaControlGattService.java | 214 ++++++++++++++++-- .../mcp/MediaControlGattServiceTest.java | 116 +++++++++- 2 files changed, 307 insertions(+), 23 deletions(-) diff --git a/android/app/src/com/android/bluetooth/mcp/MediaControlGattService.java b/android/app/src/com/android/bluetooth/mcp/MediaControlGattService.java index f4f8d2f1d15..31de7725e12 100644 --- a/android/app/src/com/android/bluetooth/mcp/MediaControlGattService.java +++ b/android/app/src/com/android/bluetooth/mcp/MediaControlGattService.java @@ -391,6 +391,119 @@ public class MediaControlGattService implements MediaControlGattServiceInterface return mMcpService.getDeviceAuthorization(device); } + private void onUnauthorizedCharRead(BluetoothDevice device, GattOpContext op) { + UUID charUuid = op.mCharacteristic.getUuid(); + boolean allowToReadRealValue = false; + byte[] buffer = null; + + if (charUuid.equals(UUID_PLAYER_NAME)) { + allowToReadRealValue = true; + + } else if (charUuid.equals(UUID_PLAYER_ICON_OBJ_ID)) { + buffer = objId2ByteArray(-1); + + } else if (charUuid.equals(UUID_PLAYER_ICON_URL)) { + ByteBuffer bb = ByteBuffer.allocate(0).order(ByteOrder.LITTLE_ENDIAN); + bb.put("".getBytes()); + buffer = bb.array(); + + } else if (charUuid.equals(UUID_TRACK_CHANGED)) { + // No read is available on this characteristic + + } else if (charUuid.equals(UUID_TRACK_TITLE)) { + ByteBuffer bb = ByteBuffer.allocate(0).order(ByteOrder.LITTLE_ENDIAN); + bb.put("".getBytes()); + buffer = bb.array(); + + } else if (charUuid.equals(UUID_TRACK_DURATION)) { + ByteBuffer bb = ByteBuffer.allocate(4).order(ByteOrder.LITTLE_ENDIAN); + bb.putInt((int) TRACK_DURATION_UNAVAILABLE); + buffer = bb.array(); + + } else if (charUuid.equals(UUID_TRACK_POSITION)) { + ByteBuffer bb = ByteBuffer.allocate(4).order(ByteOrder.LITTLE_ENDIAN); + bb.putInt((int) TRACK_POSITION_UNAVAILABLE); + buffer = bb.array(); + + } else if (charUuid.equals(UUID_PLAYBACK_SPEED)) { + ByteBuffer bb = ByteBuffer.allocate(1).order(ByteOrder.LITTLE_ENDIAN); + bb.put((byte) 1); + buffer = bb.array(); + + } else if (charUuid.equals(UUID_SEEKING_SPEED)) { + ByteBuffer bb = ByteBuffer.allocate(1).order(ByteOrder.LITTLE_ENDIAN); + bb.put((byte) 1); + buffer = bb.array(); + + } else if (charUuid.equals(UUID_CURRENT_TRACK_SEGMENT_OBJ_ID)) { + buffer = objId2ByteArray(-1); + + } else if (charUuid.equals(UUID_CURRENT_TRACK_OBJ_ID)) { + buffer = objId2ByteArray(-1); + + } else if (charUuid.equals(UUID_NEXT_TRACK_OBJ_ID)) { + buffer = objId2ByteArray(-1); + + } else if (charUuid.equals(UUID_CURRENT_GROUP_OBJ_ID)) { + buffer = objId2ByteArray(-1); + + } else if (charUuid.equals(UUID_PARENT_GROUP_OBJ_ID)) { + buffer = objId2ByteArray(-1); + + } else if (charUuid.equals(UUID_PLAYING_ORDER)) { + ByteBuffer bb = ByteBuffer.allocate(1).order(ByteOrder.LITTLE_ENDIAN); + bb.put((byte) PlayingOrder.SINGLE_ONCE.getValue()); + buffer = bb.array(); + + } else if (charUuid.equals(UUID_PLAYING_ORDER_SUPPORTED)) { + ByteBuffer bb = ByteBuffer.allocate(2).order(ByteOrder.LITTLE_ENDIAN); + bb.putShort((short) SupportedPlayingOrder.SINGLE_ONCE); + buffer = bb.array(); + + } else if (charUuid.equals(UUID_MEDIA_STATE)) { + allowToReadRealValue = true; + + } else if (charUuid.equals(UUID_MEDIA_CONTROL_POINT)) { + // No read is available on this characteristic + + } else if (charUuid.equals(UUID_MEDIA_CONTROL_POINT_OPCODES_SUPPORTED)) { + allowToReadRealValue = true; + + } else if (charUuid.equals(UUID_SEARCH_RESULT_OBJ_ID)) { + buffer = objId2ByteArray(-1); + + } else if (charUuid.equals(UUID_SEARCH_CONTROL_POINT)) { + // No read is available on this characteristic + + } else if (charUuid.equals(UUID_CONTENT_CONTROL_ID)) { + allowToReadRealValue = true; + } + + if (allowToReadRealValue) { + if (op.mCharacteristic.getValue() != null) { + buffer = + Arrays.copyOfRange( + op.mCharacteristic.getValue(), + op.mOffset, + op.mCharacteristic.getValue().length); + } + } + + if (buffer != null) { + mBluetoothGattServer.sendResponse( + device, op.mRequestId, BluetoothGatt.GATT_SUCCESS, op.mOffset, buffer); + } else { + mEventLogger.loge( + TAG, "Missing characteristic value for char: " + mcsUuidToString(charUuid)); + mBluetoothGattServer.sendResponse( + device, + op.mRequestId, + BluetoothGatt.GATT_INVALID_ATTRIBUTE_LENGTH, + op.mOffset, + buffer); + } + } + private void onUnauthorizedGattOperation(BluetoothDevice device, GattOpContext op) { UUID charUuid = (op.mCharacteristic != null @@ -407,6 +520,61 @@ public class MediaControlGattService implements MediaControlGattServiceInterface + ", characteristic= " + (charUuid != null ? mcsUuidToString(charUuid) : "UNKNOWN")); + switch (op.mOperation) { + /* Allow not yet authorized devices to subscribe for notifications */ + case READ_DESCRIPTOR: + if (op.mOffset > 1) { + mBluetoothGattServer.sendResponse( + device, + op.mRequestId, + BluetoothGatt.GATT_INVALID_OFFSET, + op.mOffset, + null); + return; + } + + byte[] value = getCccBytes(device, op.mDescriptor.getCharacteristic().getUuid()); + if (value == null) { + mBluetoothGattServer.sendResponse( + device, op.mRequestId, BluetoothGatt.GATT_FAILURE, op.mOffset, null); + return; + } + + value = Arrays.copyOfRange(value, op.mOffset, value.length); + mBluetoothGattServer.sendResponse( + device, op.mRequestId, BluetoothGatt.GATT_SUCCESS, op.mOffset, value); + return; + case WRITE_DESCRIPTOR: + int status = BluetoothGatt.GATT_SUCCESS; + if (op.mPreparedWrite) { + status = BluetoothGatt.GATT_FAILURE; + } else if (op.mOffset > 0) { + status = BluetoothGatt.GATT_INVALID_OFFSET; + } else { + status = BluetoothGatt.GATT_SUCCESS; + setCcc( + device, + op.mDescriptor.getCharacteristic().getUuid(), + op.mOffset, + op.mValue, + true); + } + + if (op.mResponseNeeded) { + mBluetoothGattServer.sendResponse( + device, op.mRequestId, status, op.mOffset, op.mValue); + } + return; + case READ_CHARACTERISTIC: + onUnauthorizedCharRead(device, op); + return; + case WRITE_CHARACTERISTIC: + // store as pending operation + break; + default: + break; + } + synchronized (mPendingGattOperations) { List operations = mPendingGattOperations.get(device); if (operations == null) { @@ -914,6 +1082,11 @@ public class MediaControlGattService implements MediaControlGattServiceInterface public List getConnectedDevices() { return mBluetoothManager.getConnectedDevices(BluetoothProfile.GATT_SERVER); } + + public boolean isDeviceConnected(BluetoothDevice device) { + return mBluetoothManager.getConnectionState(device, BluetoothProfile.GATT_SERVER) + == BluetoothProfile.STATE_CONNECTED; + } } protected MediaControlGattService(McpService mcpService, @@ -1499,6 +1672,9 @@ public class MediaControlGattService implements MediaControlGattServiceInterface ? "REJECTED" : "UNKNOWN"))); ProcessPendingGattOperations(device); + for (BluetoothGattCharacteristic characteristic : mCharacteristics.values()) { + notifyCharacteristic(device, characteristic); + } } @Override @@ -1543,32 +1719,38 @@ public class MediaControlGattService implements MediaControlGattServiceInterface } } - private void notifyCharacteristic(@NonNull BluetoothGattCharacteristic characteristic, - @Nullable BluetoothDevice originDevice) { - for (BluetoothDevice device : mBluetoothGattServer.getConnectedDevices()) { - // Skip the origin device who changed the characteristic - if (device.equals(originDevice)) { - continue; - } + private void notifyCharacteristic( + @NonNull BluetoothDevice device, @NonNull BluetoothGattCharacteristic characteristic) { + if (!mBluetoothGattServer.isDeviceConnected(device)) return; + if (getDeviceAuthorization(device) != BluetoothDevice.ACCESS_ALLOWED) return; - Map charCccMap = mCccDescriptorValues.get(device.getAddress()); - if (charCccMap == null) continue; + Map charCccMap = mCccDescriptorValues.get(device.getAddress()); + if (charCccMap == null) return; - byte[] ccc = getCccBytes(device, characteristic.getUuid()); - if (VDBG) { + byte[] ccc = getCccBytes(device, characteristic.getUuid()); + if (VDBG) { Log.d( TAG, "notifyCharacteristic: char= " + characteristic.getUuid().toString() + " cccVal= " + ByteBuffer.wrap(ccc).order(ByteOrder.LITTLE_ENDIAN).getShort()); - } - - if (!Arrays.equals(ccc, BluetoothGattDescriptor.ENABLE_NOTIFICATION_VALUE)) continue; + } + if (!Arrays.equals(ccc, BluetoothGattDescriptor.ENABLE_NOTIFICATION_VALUE)) return; - if (VDBG) Log.d(TAG, "notifyCharacteristic: sending notification"); + if (VDBG) Log.d(TAG, "notifyCharacteristic: sending notification"); + mBluetoothGattServer.notifyCharacteristicChanged(device, characteristic, false); + } - mBluetoothGattServer.notifyCharacteristicChanged(device, characteristic, false); + private void notifyCharacteristic( + @NonNull BluetoothGattCharacteristic characteristic, + @Nullable BluetoothDevice originDevice) { + for (BluetoothDevice device : mBluetoothGattServer.getConnectedDevices()) { + // Skip the origin device who changed the characteristic + if (device.equals(originDevice)) { + continue; + } + notifyCharacteristic(device, characteristic); } } diff --git a/android/app/tests/unit/src/com/android/bluetooth/mcp/MediaControlGattServiceTest.java b/android/app/tests/unit/src/com/android/bluetooth/mcp/MediaControlGattServiceTest.java index d7f95f50926..4501baed5d2 100644 --- a/android/app/tests/unit/src/com/android/bluetooth/mcp/MediaControlGattServiceTest.java +++ b/android/app/tests/unit/src/com/android/bluetooth/mcp/MediaControlGattServiceTest.java @@ -112,15 +112,16 @@ public class MediaControlGattServiceTest { private void prepareConnectedDevice() { if (mCurrentDevice == null) { mCurrentDevice = TestUtils.getTestDevice(mAdapter, 0); + List devices = new ArrayList(); + devices.add(mCurrentDevice); + doReturn(devices).when(mMockGattServer).getConnectedDevices(); + doReturn(true).when(mMockGattServer).isDeviceConnected(eq(mCurrentDevice)); } } private void prepareConnectedDevicesCccVal( BluetoothGattCharacteristic characteristic, byte[] value) { prepareConnectedDevice(); - List devices = new ArrayList(); - devices.add(mCurrentDevice); - doReturn(devices).when(mMockGattServer).getConnectedDevices(); mMcpService.setCcc(mCurrentDevice, characteristic.getUuid(), 0, value, true); } @@ -1054,7 +1055,7 @@ public class MediaControlGattServiceTest { } @Test - public void testCharacteristicReadUnauthorized() { + public void testCharacteristicReadRejectedUnauthorized() { BluetoothGattService service = initAllFeaturesGattService(); BluetoothGattCharacteristic characteristic = @@ -1074,7 +1075,31 @@ public class MediaControlGattServiceTest { } @Test - public void testCharacteristicWriteUnauthorized() { + public void testCharacteristicReadUnknownUnauthorized() { + BluetoothGattService service = initAllFeaturesGattService(); + + BluetoothGattCharacteristic characteristic = + service.getCharacteristic(MediaControlGattService.UUID_TRACK_POSITION); + + prepareConnectedDevice(); + doReturn(BluetoothDevice.ACCESS_UNKNOWN) + .when(mMockMcpService) + .getDeviceAuthorization(any(BluetoothDevice.class)); + + mMcpService.mServerCallback.onCharacteristicReadRequest( + mCurrentDevice, 1, 0, characteristic); + verify(mMockMcpService, times(0)).onDeviceUnauthorized(eq(mCurrentDevice)); + verify(mMockGattServer, times(0)) + .sendResponse( + eq(mCurrentDevice), + eq(1), + eq(BluetoothGatt.GATT_INSUFFICIENT_AUTHORIZATION), + eq(0), + any()); + } + + @Test + public void testCharacteristicWriteRejectedUnauthorized() { BluetoothGattService service = initAllFeaturesGattService(); int track_position = 100; @@ -1099,7 +1124,29 @@ public class MediaControlGattServiceTest { } @Test - public void testDescriptorReadUnauthorized() { + public void testCharacteristicWriteUnknownUnauthorized() { + BluetoothGattService service = initAllFeaturesGattService(); + int track_position = 100; + + BluetoothGattCharacteristic characteristic = + service.getCharacteristic(MediaControlGattService.UUID_TRACK_POSITION); + + ByteBuffer bb = ByteBuffer.allocate(Integer.BYTES + 1).order(ByteOrder.LITTLE_ENDIAN); + bb.putInt((int) track_position); + bb.put((byte) 0); + + prepareConnectedDevice(); + doReturn(BluetoothDevice.ACCESS_UNKNOWN) + .when(mMockMcpService) + .getDeviceAuthorization(any(BluetoothDevice.class)); + + mMcpService.mServerCallback.onCharacteristicWriteRequest( + mCurrentDevice, 1, characteristic, false, true, 0, bb.array()); + verify(mMockMcpService).onDeviceUnauthorized(eq(mCurrentDevice)); + } + + @Test + public void testDescriptorReadRejectedUnauthorized() { BluetoothGattService service = initAllFeaturesGattService(); BluetoothGattDescriptor descriptor = @@ -1120,7 +1167,32 @@ public class MediaControlGattServiceTest { } @Test - public void testDescriptorWriteUnauthorized() { + public void testDescriptorReadUnknownUnauthorized() { + BluetoothGattService service = initAllFeaturesGattService(); + + BluetoothGattDescriptor descriptor = + service.getCharacteristic(MediaControlGattService.UUID_TRACK_POSITION) + .getDescriptor(UUID_CCCD); + Assert.assertNotNull(descriptor); + + prepareConnectedDevice(); + doReturn(BluetoothDevice.ACCESS_UNKNOWN) + .when(mMockMcpService) + .getDeviceAuthorization(any(BluetoothDevice.class)); + + mMcpService.mServerCallback.onDescriptorReadRequest(mCurrentDevice, 1, 0, descriptor); + verify(mMockMcpService, times(0)).onDeviceUnauthorized(eq(mCurrentDevice)); + verify(mMockGattServer, times(0)) + .sendResponse( + eq(mCurrentDevice), + eq(1), + eq(BluetoothGatt.GATT_INSUFFICIENT_AUTHORIZATION), + eq(0), + any()); + } + + @Test + public void testDescriptorWriteRejectedUnauthorized() { BluetoothGattService service = initAllFeaturesGattService(); BluetoothGattDescriptor descriptor = @@ -1145,6 +1217,36 @@ public class MediaControlGattServiceTest { eq(BluetoothGatt.GATT_INSUFFICIENT_AUTHORIZATION), eq(0), any()); } + @Test + public void testDescriptorWriteUnknownUnauthorized() { + BluetoothGattService service = initAllFeaturesGattService(); + + BluetoothGattDescriptor descriptor = + service.getCharacteristic(MediaControlGattService.UUID_TRACK_POSITION) + .getDescriptor(UUID_CCCD); + Assert.assertNotNull(descriptor); + + prepareConnectedDevice(); + doReturn(BluetoothDevice.ACCESS_UNKNOWN) + .when(mMockMcpService) + .getDeviceAuthorization(any(BluetoothDevice.class)); + + ByteBuffer bb = ByteBuffer.allocate(2).order(ByteOrder.LITTLE_ENDIAN); + bb.put((byte) 0); + bb.put((byte) 1); + + mMcpService.mServerCallback.onDescriptorWriteRequest( + mCurrentDevice, 1, descriptor, false, true, 0, bb.array()); + verify(mMockMcpService, times(0)).onDeviceUnauthorized(eq(mCurrentDevice)); + verify(mMockGattServer, times(0)) + .sendResponse( + eq(mCurrentDevice), + eq(1), + eq(BluetoothGatt.GATT_INSUFFICIENT_AUTHORIZATION), + eq(0), + any()); + } + @Test public void testUpdatePlayerNameFromNull() { BluetoothGattService service = initAllFeaturesGattService(); -- GitLab From ada7d88af8b646cf0cccd226480ea0242a5818c1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Rymanowski?= Date: Thu, 18 May 2023 01:16:21 +0000 Subject: [PATCH 0104/2405] leaudio: Remove CIG when all ASEs are in the Releasing state We should remove CIG only when there is no active ASEs. In this patch we also add a guard which block creating CIS when CIG is not exist. Bug: 282506986 Test: atest bluetooth_le_audio_test bluetooth_le_audio_client_test Test: BluetoothInstrumentationTests Tag: #feature Change-Id: I4943ed9869945f6d63c4f77c8f9c199aaa345a08 --- system/bta/le_audio/state_machine.cc | 47 ++++++++++++++++++++++------ 1 file changed, 37 insertions(+), 10 deletions(-) diff --git a/system/bta/le_audio/state_machine.cc b/system/bta/le_audio/state_machine.cc index 6956e8c99f7..91e346a0dd0 100644 --- a/system/bta/le_audio/state_machine.cc +++ b/system/bta/le_audio/state_machine.cc @@ -1436,10 +1436,18 @@ class LeAudioGroupStateMachineImpl : public LeAudioGroupStateMachine { return true; } - static void CisCreateForDevice(LeAudioDevice* leAudioDevice) { + static bool CisCreateForDevice(LeAudioDeviceGroup* group, + LeAudioDevice* leAudioDevice) { std::vector conn_pairs; struct ase* ase = leAudioDevice->GetFirstActiveAse(); + /* Make sure CIG is there */ + if (group->GetCigState() != CigState::CREATED) { + LOG_ERROR("CIG is not created for group_id %d ", group->group_id_); + group->PrintDebugState(); + return false; + } + std::stringstream extra_stream; do { /* First in ase pair is Sink, second Source */ @@ -1472,9 +1480,11 @@ class LeAudioGroupStateMachineImpl : public LeAudioGroupStateMachine { IsoManager::GetInstance()->EstablishCis( {.conn_pairs = std::move(conn_pairs)}); + + return true; } - static void CisCreate(LeAudioDeviceGroup* group) { + static bool CisCreate(LeAudioDeviceGroup* group) { LeAudioDevice* leAudioDevice = group->GetFirstActiveDevice(); struct ase* ase; std::vector conn_pairs; @@ -1482,6 +1492,13 @@ class LeAudioGroupStateMachineImpl : public LeAudioGroupStateMachine { LOG_ASSERT(leAudioDevice) << __func__ << " Shouldn't be called without an active device."; + /* Make sure CIG is there */ + if (group->GetCigState() != CigState::CREATED) { + LOG_ERROR("CIG is not created for group_id %d ", group->group_id_); + group->PrintDebugState(); + return false; + } + do { ase = leAudioDevice->GetFirstActiveAse(); LOG_ASSERT(ase) << __func__ @@ -1513,6 +1530,8 @@ class LeAudioGroupStateMachineImpl : public LeAudioGroupStateMachine { IsoManager::GetInstance()->EstablishCis( {.conn_pairs = std::move(conn_pairs)}); + + return true; } static void PrepareDataPath(int group_id, const struct ase* ase) { @@ -2510,7 +2529,10 @@ class LeAudioGroupStateMachineImpl : public LeAudioGroupStateMachine { if (group->GetState() == AseState::BTA_LE_AUDIO_ASE_STATE_STREAMING) { if (ase->data_path_state < AudioStreamDataPathState::CIS_PENDING) { /* We are here because of the reconnection of the single device. */ - CisCreateForDevice(leAudioDevice); + if (!CisCreateForDevice(group, leAudioDevice)) { + StopStream(group); + return; + } } if (!leAudioDevice->HaveAllActiveAsesCisEst()) { @@ -2768,15 +2790,17 @@ class LeAudioGroupStateMachineImpl : public LeAudioGroupStateMachine { break; } case AseState::BTA_LE_AUDIO_ASE_STATE_QOS_CONFIGURED: - /* At this point all of the active ASEs within group are released. */ - RemoveCigForGroup(group); - SetAseState(leAudioDevice, ase, AseState::BTA_LE_AUDIO_ASE_STATE_RELEASING); + if (group->HaveAllActiveDevicesAsesTheSameState( - AseState::BTA_LE_AUDIO_ASE_STATE_RELEASING)) + AseState::BTA_LE_AUDIO_ASE_STATE_RELEASING)) { group->SetState(AseState::BTA_LE_AUDIO_ASE_STATE_RELEASING); + /* At this point all of the active ASEs within group are released. */ + RemoveCigForGroup(group); + } + break; case AseState::BTA_LE_AUDIO_ASE_STATE_ENABLING: @@ -2832,13 +2856,16 @@ class LeAudioGroupStateMachineImpl : public LeAudioGroupStateMachine { group->SetState(AseState::BTA_LE_AUDIO_ASE_STATE_STREAMING); } - if (group->GetTargetState() == AseState::BTA_LE_AUDIO_ASE_STATE_STREAMING) { - CisCreate(group); - } else { + if (group->GetTargetState() != AseState::BTA_LE_AUDIO_ASE_STATE_STREAMING) { LOG_ERROR(", invalid state transition, from: %s , to: %s ", ToString(group->GetState()).c_str(), ToString(group->GetTargetState()).c_str()); StopStream(group); + return; + } + + if (!CisCreate(group)) { + StopStream(group); } } -- GitLab From 8c02fa7af535428884f57d88e68e479087bec83d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Rymanowski?= Date: Thu, 18 May 2023 12:20:26 +0000 Subject: [PATCH 0105/2405] LeAudioService: Fix starting scanner Make sure to retry when registration does not happen, and in other case clear the callback which indicates scan is ongoing. Bug: 283228408 Test: manual Tag: #feature Change-Id: I2399058997b20ea3534951b25c4a8169211d7052 --- .../android/bluetooth/le_audio/LeAudioService.java | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/android/app/src/com/android/bluetooth/le_audio/LeAudioService.java b/android/app/src/com/android/bluetooth/le_audio/LeAudioService.java index b8836252de5..53b58fe70b5 100644 --- a/android/app/src/com/android/bluetooth/le_audio/LeAudioService.java +++ b/android/app/src/com/android/bluetooth/le_audio/LeAudioService.java @@ -1182,15 +1182,20 @@ public class LeAudioService extends ProfileService { @Override public void onScanFailed(int errorCode) { - Log.w(TAG, "Scan failed " + errorCode + " scan retries: " + mScanRetries); + Log.w(TAG, "Scan failed err: " + errorCode + " scan retries: " + mScanRetries); switch(errorCode) { - case SCAN_FAILED_INTERNAL_ERROR: { + case SCAN_FAILED_INTERNAL_ERROR: + case SCAN_FAILED_APPLICATION_REGISTRATION_FAILED: if (mScanRetries < mMaxScanRetires) { mScanRetries++; Log.w(TAG, "Failed to start. Let's retry"); mHandler.post(() -> startAudioServersBackgroundScan(/* retry = */ true)); } - } + break; + default: + /* Indicate scan is no running */ + mScanCallback = null; + break; } } } -- GitLab From f6a115c6f386de1f40781eb12daeb84b434a947b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Rymanowski?= Date: Thu, 18 May 2023 12:31:29 +0000 Subject: [PATCH 0106/2405] bt: Fix getting device type. With this patch p_dev_rec will have updated device type based on the inquire database. This is needed for dual mode bonding, when first bond over LE and later it triest to bond over BR/EDR. Note: At that time BTM_GetPeerDeviceTypeFromFeatures will not return any type as it is working only when BR/EDR is connected Bug: 282733852 Test: manual Tag: feature Change-Id: I69d708153de45c9c503eb71915ac6ccdddf98c12 --- system/stack/btm/btm_ble.cc | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/system/stack/btm/btm_ble.cc b/system/stack/btm/btm_ble.cc index 0b33044314e..c85d71cfe25 100644 --- a/system/stack/btm/btm_ble.cc +++ b/system/stack/btm/btm_ble.cc @@ -112,9 +112,10 @@ void BTM_SecAddBleDevice(const RawAddress& bd_addr, tBT_DEVICE_TYPE dev_type, tBTM_INQ_INFO* p_info = BTM_InqDbRead(bd_addr); if (p_info) { p_info->results.ble_addr_type = p_dev_rec->ble.AddressType(); + p_dev_rec->device_type |= p_info->results.device_type; + LOG_DEBUG("InqDb device_type =0x%x addr_type=0x%x", p_dev_rec->device_type, + p_info->results.ble_addr_type); p_info->results.device_type = p_dev_rec->device_type; - LOG_DEBUG("InqDb device_type =0x%x addr_type=0x%x", - p_info->results.device_type, p_info->results.ble_addr_type); } } -- GitLab From 43a42f5a9357e58bbc721f2d50fbcd91e8fcac13 Mon Sep 17 00:00:00 2001 From: Chris Manton Date: Mon, 15 May 2023 09:56:29 -0700 Subject: [PATCH 0107/2405] Break out stack::include::sdp_callback.h Bug: 282936084 Test: Compiles and links Change-Id: Ied37ee7d0e600df47eeab8b9da28ee1ed2f2c655 --- system/stack/include/sdp_api.h | 5 +---- system/stack/include/sdp_callback.h | 27 +++++++++++++++++++++++++++ 2 files changed, 28 insertions(+), 4 deletions(-) create mode 100644 system/stack/include/sdp_callback.h diff --git a/system/stack/include/sdp_api.h b/system/stack/include/sdp_api.h index 7ab3b76df69..2876c363296 100644 --- a/system/stack/include/sdp_api.h +++ b/system/stack/include/sdp_api.h @@ -23,6 +23,7 @@ #include #include "bt_target.h" +#include "stack/include/sdp_callback.h" #include "stack/include/sdp_device_id.h" #include "stack/include/sdp_status.h" #include "stack/include/sdpdefs.h" @@ -38,10 +39,6 @@ * Type Definitions ****************************************************************************/ -/* Define a callback function for when discovery is complete. */ -typedef void(tSDP_DISC_CMPL_CB)(tSDP_RESULT result); -typedef void(tSDP_DISC_CMPL_CB2)(tSDP_RESULT result, const void* user_data); - /* API into the SDP layer for service discovery. */ /******************************************************************************* diff --git a/system/stack/include/sdp_callback.h b/system/stack/include/sdp_callback.h new file mode 100644 index 00000000000..9cf0a1b3e2c --- /dev/null +++ b/system/stack/include/sdp_callback.h @@ -0,0 +1,27 @@ +/****************************************************************************** + * + * Copyright 1999-2012 Broadcom Corporation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + ******************************************************************************/ + +#pragma once + +#include + +#include "stack/include/sdp_status.h" + +/* Define a callback function for when discovery is complete. */ +typedef void(tSDP_DISC_CMPL_CB)(tSDP_RESULT result); +typedef void(tSDP_DISC_CMPL_CB2)(tSDP_RESULT result, const void* user_data); -- GitLab From 5f637ae6b546e3aa154cae2686afee8caa65f8b1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Rymanowski?= Date: Mon, 15 May 2023 15:11:41 +0000 Subject: [PATCH 0108/2405] gatt_attr: Allow more operations in GATT service client With this patch, GATT Service client is prepared to handle more operations at the time. Needed by following patch Bug: 282134244 Test: manual Tag: #feature Change-Id: I0190f54e1f656519c948d23d8a16065282005b85 --- system/stack/gatt/gatt_attr.cc | 51 +++++++++++++++++----------------- 1 file changed, 26 insertions(+), 25 deletions(-) diff --git a/system/stack/gatt/gatt_attr.cc b/system/stack/gatt/gatt_attr.cc index 50b61aeea41..479dedb16ca 100644 --- a/system/stack/gatt/gatt_attr.cc +++ b/system/stack/gatt/gatt_attr.cc @@ -23,6 +23,7 @@ * ******************************************************************************/ +#include #include #include "base/functional/callback.h" @@ -60,7 +61,7 @@ typedef struct { gatt_sr_supported_feat_cb cb; } gatt_op_cb_data; -static std::map OngoingOps; +static std::map> OngoingOps; static void gatt_request_cback(uint16_t conn_id, uint32_t trans_id, uint8_t op_code, tGATTS_DATA* p_data); @@ -382,6 +383,8 @@ void gatt_profile_db_init(void) { std::array tmp; tmp.fill(0x81); + OngoingOps.clear(); + /* Create a GATT profile service */ gatt_cb.gatt_if = GATT_Register(Uuid::From128BitBE(tmp), "GattProfileDb", &gatt_profile_cback, false); @@ -514,8 +517,7 @@ static void gatt_disc_cmpl_cback(uint16_t conn_id, tGATT_DISC_TYPE disc_type, gatt_cl_start_config_ccc(p_clcb); } -static bool gatt_svc_read_cl_supp_feat_req(uint16_t conn_id, - gatt_op_cb_data* cb) { +static bool gatt_svc_read_cl_supp_feat_req(uint16_t conn_id) { tGATT_READ_PARAM param; memset(¶m, 0, sizeof(tGATT_READ_PARAM)); @@ -533,7 +535,13 @@ static bool gatt_svc_read_cl_supp_feat_req(uint16_t conn_id, return false; } - cb->op_uuid = GATT_UUID_CLIENT_SUP_FEAT; + gatt_op_cb_data cb_data; + + cb_data.cb = + base::BindOnce([](const RawAddress& bdaddr, uint8_t support) { return; }); + cb_data.op_uuid = GATT_UUID_CLIENT_SUP_FEAT; + OngoingOps[conn_id].emplace_back(std::move(cb_data)); + return true; } @@ -580,21 +588,19 @@ static void gatt_cl_op_cmpl_cback(uint16_t conn_id, tGATTC_OPTYPE op, return; } - if (iter == OngoingOps.end()) { + if (iter == OngoingOps.end() || (iter->second.size() == 0)) { /* If OngoingOps is empty it means we are not interested in the result here. */ LOG_DEBUG("Unexpected read complete"); return; } - gatt_op_cb_data* operation_callback_data = &iter->second; - uint16_t cl_op_uuid = operation_callback_data->op_uuid; - operation_callback_data->op_uuid = 0; + uint16_t cl_op_uuid = iter->second.front().op_uuid; if (op == GATTC_OPTYPE_WRITE) { if (cl_op_uuid == GATT_UUID_GATT_SRV_CHGD) { LOG_DEBUG("Write response from Service Changed CCC"); - OngoingOps.erase(iter); + iter->second.pop_front(); /* Read server supported features here supported */ read_sr_supported_feat_req( conn_id, base::BindOnce([](const RawAddress& bdaddr, @@ -605,6 +611,7 @@ static void gatt_cl_op_cmpl_cback(uint16_t conn_id, tGATTC_OPTYPE op, return; } + /* Handle Read operations */ uint8_t* pp = p_data->att_value.value; VLOG(1) << __func__ << " cl_op_uuid " << loghex(cl_op_uuid); @@ -614,6 +621,9 @@ static void gatt_cl_op_cmpl_cback(uint16_t conn_id, tGATTC_OPTYPE op, uint8_t tcb_idx = GATT_GET_TCB_IDX(conn_id); tGATT_TCB& tcb = gatt_cb.tcb[tcb_idx]; + auto operation_callback_data = std::move(iter->second.front()); + iter->second.pop_front(); + /* Check if EATT is supported */ if (status == GATT_SUCCESS) { STREAM_TO_UINT8(tcb.sr_supp_feat, pp); @@ -621,28 +631,21 @@ static void gatt_cl_op_cmpl_cback(uint16_t conn_id, tGATTC_OPTYPE op, } /* Notify user about the supported features */ - std::move(operation_callback_data->cb) - .Run(tcb.peer_bda, tcb.sr_supp_feat); + std::move(operation_callback_data.cb).Run(tcb.peer_bda, tcb.sr_supp_feat); /* If server supports EATT lets try to find handle for the * client supported features characteristic, where we could write * our supported features as a client. */ if (tcb.sr_supp_feat & BLE_GATT_SVR_SUP_FEAT_EATT_BITMASK) { - /* If read succeed, return here */ - if (gatt_svc_read_cl_supp_feat_req(conn_id, operation_callback_data)) - return; + gatt_svc_read_cl_supp_feat_req(conn_id); } - /* Could not read client supported charcteristic or eatt is not - * supported. Erase callback data now. - */ - OngoingOps.erase(iter); break; } case GATT_UUID_CLIENT_SUP_FEAT: /*We don't need callback data anymore */ - OngoingOps.erase(iter); + iter->second.pop_front(); if (status != GATT_SUCCESS) { LOG(INFO) << __func__ @@ -698,7 +701,7 @@ static void gatt_cl_start_config_ccc(tGATT_PROFILE_CLCB* p_clcb) { cb_data.cb = base::BindOnce( [](const RawAddress& bdaddr, uint8_t support) { return; }); cb_data.op_uuid = GATT_UUID_GATT_SRV_CHGD; - OngoingOps[p_clcb->conn_id] = std::move(cb_data); + OngoingOps[p_clcb->conn_id].emplace_back(std::move(cb_data)); break; } @@ -777,7 +780,7 @@ static bool read_sr_supported_feat_req( cb_data.cb = std::move(cb); cb_data.op_uuid = GATT_UUID_SERVER_SUP_FEAT; - OngoingOps[conn_id] = std::move(cb_data); + OngoingOps[conn_id].emplace_back(std::move(cb_data)); return true; } @@ -817,10 +820,8 @@ bool gatt_cl_read_sr_supp_feat_req( } auto it = OngoingOps.find(conn_id); - if (it != OngoingOps.end()) { - LOG(ERROR) << __func__ << " There is ongoing operation for conn_id: " - << loghex(conn_id); - return false; + if (it == OngoingOps.end()) { + OngoingOps[conn_id] = std::deque(); } return read_sr_supported_feat_req(conn_id, std::move(cb)); -- GitLab From 387bcb98c516d2650159d49827b9d34dba50d7eb Mon Sep 17 00:00:00 2001 From: Henri Chataing Date: Wed, 17 May 2023 16:52:37 -0700 Subject: [PATCH 0109/2405] gd: Patch HCI pdl definitions for ISO commands and events - invalid op-code index for LE Set Cig Parameters Test - in ISO H4 packets, iso_sdu_length is the total length of the sdu, not the length of the fragment - rename peripheral_clock_accuracy -> worst_case_sca Bug: 283254594 Test: None Change-Id: I637c72276974b341c60e20711e56db5158d85643 --- system/gd/hci/hci_packets.pdl | 10 +++++----- system/gd/iso/internal/iso_manager_impl.cc | 3 ++- 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/system/gd/hci/hci_packets.pdl b/system/gd/hci/hci_packets.pdl index 11d5b86f651..b2495f77ad5 100644 --- a/system/gd/hci/hci_packets.pdl +++ b/system/gd/hci/hci_packets.pdl @@ -716,7 +716,7 @@ enum OpCodeIndex : 16 { LE_READ_BUFFER_SIZE_V2 = 415, LE_READ_ISO_TX_SYNC = 416, LE_SET_CIG_PARAMETERS = 417, - LE_SET_CIG_PARAMETERS_TEST = 418, + LE_SET_CIG_PARAMETERS_TEST = 420, LE_CREATE_CIS = 421, LE_REMOVE_CIG = 422, LE_ACCEPT_CIS_REQUEST = 423, @@ -4483,7 +4483,7 @@ packet LeSetCigParameters : LeIsoCommand (op_code = LE_SET_CIG_PARAMETERS) { cig_id : 8, sdu_interval_m_to_s : 24, sdu_interval_s_to_m : 24, - peripherals_clock_accuracy : ClockAccuracy, + worst_case_sca : ClockAccuracy, packing : Packing, framing : Enable, max_transport_latency_m_to_s : 16, @@ -4519,7 +4519,7 @@ packet LeSetCigParametersTest : LeIsoCommand (op_code = LE_SET_CIG_PARAMETERS_TE ft_m_to_s : 8, ft_s_to_m : 8, iso_interval : 16, - peripherals_clock_accuracy : ClockAccuracy, + worst_case_sca : ClockAccuracy, packing : Packing, framing : Enable, _count_(cis_config) : 8, @@ -6414,7 +6414,7 @@ enum IsoPacketStatusFlag : 2 { packet IsoWithTimestamp : Iso (ts_flag = PRESENT) { time_stamp : 32, packet_sequence_number : 16, - _size_(_payload_) : 12, // iso_sdu_length + iso_sdu_length : 12, _reserved_ : 2, packet_status_flag : IsoPacketStatusFlag, _payload_, @@ -6422,7 +6422,7 @@ packet IsoWithTimestamp : Iso (ts_flag = PRESENT) { packet IsoWithoutTimestamp : Iso (ts_flag = NOT_PRESENT) { packet_sequence_number : 16, - _size_(_payload_) : 12, // iso_sdu_length + iso_sdu_length : 12, _reserved_ : 2, packet_status_flag : IsoPacketStatusFlag, _payload_, diff --git a/system/gd/iso/internal/iso_manager_impl.cc b/system/gd/iso/internal/iso_manager_impl.cc index 1ea38589494..f4eef2df2dc 100644 --- a/system/gd/iso/internal/iso_manager_impl.cc +++ b/system/gd/iso/internal/iso_manager_impl.cc @@ -254,7 +254,8 @@ void IsoManagerImpl::SendIsoPacket(uint16_t cis_handle, std::vector pac auto builder = hci::IsoWithoutTimestampBuilder::Create( cis_handle, hci::IsoPacketBoundaryFlag::COMPLETE_SDU, - 0 /* sequence_number*/, + 0 /* sequence_number */, + packet.size() /* iso_sdu_length */, hci::IsoPacketStatusFlag::VALID, std::make_unique(packet)); LOG_INFO("%c%c", packet[0], packet[1]); -- GitLab From e0734c312f71a6363da5c8f38e9c15c2eb315bda Mon Sep 17 00:00:00 2001 From: Henri Chataing Date: Tue, 16 May 2023 01:35:28 +0000 Subject: [PATCH 0110/2405] pdl: Fix generation of packets with children AND no payload The parser and serialize both have issues in this case with parts of the generated code assuming the presence of the payload and other not. The added test packet_decl_parent_with_no_payload validates the generated code for this condition. Bug: 279494407 Test: atest pdl_generated_files_compile Change-Id: Ibbd97441a51fc499250e2072ec8da7f3b7806970 --- tools/pdl/Android.bp | 2 + tools/pdl/src/backends/rust.rs | 21 +- tools/pdl/src/backends/rust/parser.rs | 11 + tools/pdl/src/backends/rust/types.rs | 2 +- .../packet_decl_custom_field_big_endian.rs | 8 +- .../packet_decl_custom_field_little_endian.rs | 8 +- ..._decl_parent_with_no_payload_big_endian.rs | 374 ++++++++++++++++++ ...cl_parent_with_no_payload_little_endian.rs | 374 ++++++++++++++++++ 8 files changed, 790 insertions(+), 10 deletions(-) create mode 100644 tools/pdl/tests/generated/packet_decl_parent_with_no_payload_big_endian.rs create mode 100644 tools/pdl/tests/generated/packet_decl_parent_with_no_payload_little_endian.rs diff --git a/tools/pdl/Android.bp b/tools/pdl/Android.bp index 5bd51d77a93..14284f055bd 100644 --- a/tools/pdl/Android.bp +++ b/tools/pdl/Android.bp @@ -97,6 +97,8 @@ filegroup { "tests/generated/packet_decl_mask_scalar_value_little_endian.rs", "tests/generated/packet_decl_mixed_scalars_enums_big_endian.rs", "tests/generated/packet_decl_mixed_scalars_enums_little_endian.rs", + "tests/generated/packet_decl_parent_with_no_payload_big_endian.rs", + "tests/generated/packet_decl_parent_with_no_payload_little_endian.rs", "tests/generated/packet_decl_payload_field_unknown_size_big_endian.rs", "tests/generated/packet_decl_payload_field_unknown_size_little_endian.rs", "tests/generated/packet_decl_payload_field_unknown_size_terminal_big_endian.rs", diff --git a/tools/pdl/src/backends/rust.rs b/tools/pdl/src/backends/rust.rs index d7e355b427b..037e3548445 100644 --- a/tools/pdl/src/backends/rust.rs +++ b/tools/pdl/src/backends/rust.rs @@ -477,6 +477,9 @@ fn generate_packet_decl( #parent_data_child::#prev_parent_id(#prev_parent_id_lower) }); } + } else if scope.iter_children(parent_id).next().is_some() { + field.push(format_ident!("child")); + value.push(quote! { #parent_data_child::None }); } quote! { @@ -907,7 +910,7 @@ fn generate_custom_field_decl(id: &str, width: usize) -> proc_macro2::TokenStrea let id = format_ident!("{}", id); let backing_type = types::Integer::new(width); let backing_type_str = proc_macro2::Literal::string(&format!("u{}", backing_type.width)); - let max_value = mask_bits(width, "usize"); + let max_value = mask_bits(width, &format!("u{}", backing_type.width)); let common = quote! { impl From<&#id> for #backing_type { fn from(value: &#id) -> #backing_type { @@ -1479,6 +1482,22 @@ mod tests { " ); + test_pdl!( + packet_decl_parent_with_no_payload, + " + enum Enum8 : 8 { + A = 0, + } + + packet Parent { + v : Enum8, + } + + packet Child : Parent (v = A) { + } + " + ); + // TODO(mgeisler): enable this test when we have an approach to // struct fields with parents. // diff --git a/tools/pdl/src/backends/rust/parser.rs b/tools/pdl/src/backends/rust/parser.rs index b3e7d422b3c..2a955c625be 100644 --- a/tools/pdl/src/backends/rust/parser.rs +++ b/tools/pdl/src/backends/rust/parser.rs @@ -672,6 +672,17 @@ impl<'a> FieldParser<'a> { quote!(#(, #fields)*) }); let packet_data_child = format_ident!("{}DataChild", self.packet_name); + // Parsing of packet children requires having a payload field; + // it is allowed to inherit from a packet with empty payload, in this + // case generate an empty payload value. + if !decl + .fields() + .any(|f| matches!(&f.desc, ast::FieldDesc::Payload { .. } | ast::FieldDesc::Body)) + { + self.code.push(quote! { + let payload: &[u8] = &[]; + }) + } self.code.push(quote! { let child = match (#(#constrained_field_idents),*) { #(#match_values if #child_ids_data::conforms(&payload) => { diff --git a/tools/pdl/src/backends/rust/types.rs b/tools/pdl/src/backends/rust/types.rs index e8f14aa3de2..5b1767ddfbb 100644 --- a/tools/pdl/src/backends/rust/types.rs +++ b/tools/pdl/src/backends/rust/types.rs @@ -90,7 +90,7 @@ pub fn rust_borrow( ast::FieldDesc::Typedef { type_id, .. } => match &scope.typedef[type_id].desc { ast::DeclDesc::Enum { .. } => quote!(), ast::DeclDesc::Struct { .. } => quote!(&), - ast::DeclDesc::CustomField { .. } => quote!(&), + ast::DeclDesc::CustomField { .. } => quote!(), desc => unreachable!("unexpected declaration: {desc:?}"), }, ast::FieldDesc::Array { .. } => quote!(&), diff --git a/tools/pdl/tests/generated/packet_decl_custom_field_big_endian.rs b/tools/pdl/tests/generated/packet_decl_custom_field_big_endian.rs index cfe327f6b74..4e1b7514a3f 100644 --- a/tools/pdl/tests/generated/packet_decl_custom_field_big_endian.rs +++ b/tools/pdl/tests/generated/packet_decl_custom_field_big_endian.rs @@ -168,11 +168,11 @@ impl Foo { fn new(foo: Arc) -> Result { Ok(Self { foo }) } - pub fn get_a(&self) -> &Bar1 { - &self.foo.as_ref().a + pub fn get_a(&self) -> Bar1 { + self.foo.as_ref().a } - pub fn get_b(&self) -> &Bar2 { - &self.foo.as_ref().b + pub fn get_b(&self) -> Bar2 { + self.foo.as_ref().b } fn write_to(&self, buffer: &mut BytesMut) { self.foo.write_to(buffer) diff --git a/tools/pdl/tests/generated/packet_decl_custom_field_little_endian.rs b/tools/pdl/tests/generated/packet_decl_custom_field_little_endian.rs index 4a12f13ed4f..8cafc82d2f7 100644 --- a/tools/pdl/tests/generated/packet_decl_custom_field_little_endian.rs +++ b/tools/pdl/tests/generated/packet_decl_custom_field_little_endian.rs @@ -168,11 +168,11 @@ impl Foo { fn new(foo: Arc) -> Result { Ok(Self { foo }) } - pub fn get_a(&self) -> &Bar1 { - &self.foo.as_ref().a + pub fn get_a(&self) -> Bar1 { + self.foo.as_ref().a } - pub fn get_b(&self) -> &Bar2 { - &self.foo.as_ref().b + pub fn get_b(&self) -> Bar2 { + self.foo.as_ref().b } fn write_to(&self, buffer: &mut BytesMut) { self.foo.write_to(buffer) diff --git a/tools/pdl/tests/generated/packet_decl_parent_with_no_payload_big_endian.rs b/tools/pdl/tests/generated/packet_decl_parent_with_no_payload_big_endian.rs new file mode 100644 index 00000000000..04f50d24108 --- /dev/null +++ b/tools/pdl/tests/generated/packet_decl_parent_with_no_payload_big_endian.rs @@ -0,0 +1,374 @@ +// @generated rust packets from test + +use bytes::{Buf, BufMut, Bytes, BytesMut}; +use std::cell::Cell; +use std::convert::{TryFrom, TryInto}; +use std::fmt; +use std::sync::Arc; +use thiserror::Error; + +type Result = std::result::Result; + +#[doc = r" Private prevents users from creating arbitrary scalar values"] +#[doc = r" in situations where the value needs to be validated."] +#[doc = r" Users can freely deref the value, but only the backend"] +#[doc = r" may create it."] +#[derive(Debug, Clone, Copy, Hash, PartialEq, Eq, PartialOrd, Ord)] +pub struct Private(T); +impl std::ops::Deref for Private { + type Target = T; + fn deref(&self) -> &Self::Target { + &self.0 + } +} + +#[derive(Debug, Error)] +pub enum Error { + #[error("Packet parsing failed")] + InvalidPacketError, + #[error("{field} was {value:x}, which is not known")] + ConstraintOutOfBounds { field: String, value: u64 }, + #[error("Got {actual:x}, expected {expected:x}")] + InvalidFixedValue { expected: u64, actual: u64 }, + #[error("when parsing {obj} needed length of {wanted} but got {got}")] + InvalidLengthError { obj: String, wanted: usize, got: usize }, + #[error("array size ({array} bytes) is not a multiple of the element size ({element} bytes)")] + InvalidArraySize { array: usize, element: usize }, + #[error("Due to size restrictions a struct could not be parsed.")] + ImpossibleStructError, + #[error("when parsing field {obj}.{field}, {value} is not a valid {type_} value")] + InvalidEnumValueError { obj: String, field: String, value: u64, type_: String }, + #[error("expected child {expected}, got {actual}")] + InvalidChildError { expected: &'static str, actual: String }, +} + +pub trait Packet { + fn to_bytes(self) -> Bytes; + fn to_vec(self) -> Vec; +} + +#[repr(u64)] +#[derive(Debug, Clone, Copy, Hash, Eq, PartialEq)] +#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] +#[cfg_attr(feature = "serde", serde(try_from = "u8", into = "u8"))] +pub enum Enum8 { + A = 0x0, +} +impl TryFrom for Enum8 { + type Error = u8; + fn try_from(value: u8) -> std::result::Result { + match value { + 0x0 => Ok(Enum8::A), + _ => Err(value), + } + } +} +impl From<&Enum8> for u8 { + fn from(value: &Enum8) -> Self { + match value { + Enum8::A => 0x0, + } + } +} +impl From for u8 { + fn from(value: Enum8) -> Self { + (&value).into() + } +} +impl From for i16 { + fn from(value: Enum8) -> Self { + u8::from(value) as Self + } +} +impl From for i32 { + fn from(value: Enum8) -> Self { + u8::from(value) as Self + } +} +impl From for i64 { + fn from(value: Enum8) -> Self { + u8::from(value) as Self + } +} +impl From for u16 { + fn from(value: Enum8) -> Self { + u8::from(value) as Self + } +} +impl From for u32 { + fn from(value: Enum8) -> Self { + u8::from(value) as Self + } +} +impl From for u64 { + fn from(value: Enum8) -> Self { + u8::from(value) as Self + } +} + +#[derive(Debug, Clone, PartialEq, Eq)] +#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] +pub enum ParentDataChild { + Child(Arc), + Payload(Bytes), + None, +} +impl ParentDataChild { + fn get_total_size(&self) -> usize { + match self { + ParentDataChild::Child(value) => value.get_total_size(), + ParentDataChild::Payload(bytes) => bytes.len(), + ParentDataChild::None => 0, + } + } +} +#[derive(Debug, Clone, PartialEq, Eq)] +#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] +pub enum ParentChild { + Child(Child), + Payload(Bytes), + None, +} +#[derive(Debug, Clone, PartialEq, Eq)] +#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] +pub struct ParentData { + v: Enum8, + child: ParentDataChild, +} +#[derive(Debug, Clone, PartialEq, Eq)] +#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] +pub struct Parent { + #[cfg_attr(feature = "serde", serde(flatten))] + parent: Arc, +} +#[derive(Debug)] +#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] +pub struct ParentBuilder { + pub v: Enum8, + pub payload: Option, +} +impl ParentData { + fn conforms(bytes: &[u8]) -> bool { + bytes.len() >= 1 + } + fn parse(bytes: &[u8]) -> Result { + let mut cell = Cell::new(bytes); + let packet = Self::parse_inner(&mut cell)?; + Ok(packet) + } + fn parse_inner(mut bytes: &mut Cell<&[u8]>) -> Result { + if bytes.get().remaining() < 1 { + return Err(Error::InvalidLengthError { + obj: "Parent".to_string(), + wanted: 1, + got: bytes.get().remaining(), + }); + } + let v = Enum8::try_from(bytes.get_mut().get_u8()).map_err(|_| { + Error::InvalidEnumValueError { + obj: "Parent".to_string(), + field: "v".to_string(), + value: bytes.get_mut().get_u8() as u64, + type_: "Enum8".to_string(), + } + })?; + let payload: &[u8] = &[]; + let child = match (v) { + (Enum8::A) if ChildData::conforms(&payload) => { + let mut cell = Cell::new(payload); + let child_data = ChildData::parse_inner(&mut cell)?; + ParentDataChild::Child(Arc::new(child_data)) + } + _ if !payload.is_empty() => ParentDataChild::Payload(Bytes::copy_from_slice(payload)), + _ => ParentDataChild::None, + }; + Ok(Self { v, child }) + } + fn write_to(&self, buffer: &mut BytesMut) { + buffer.put_u8(u8::from(self.v)); + } + fn get_total_size(&self) -> usize { + self.get_size() + } + fn get_size(&self) -> usize { + 1 + } +} +impl Packet for Parent { + fn to_bytes(self) -> Bytes { + let mut buffer = BytesMut::with_capacity(self.parent.get_size()); + self.parent.write_to(&mut buffer); + buffer.freeze() + } + fn to_vec(self) -> Vec { + self.to_bytes().to_vec() + } +} +impl From for Bytes { + fn from(packet: Parent) -> Self { + packet.to_bytes() + } +} +impl From for Vec { + fn from(packet: Parent) -> Self { + packet.to_vec() + } +} +impl Parent { + pub fn parse(bytes: &[u8]) -> Result { + let mut cell = Cell::new(bytes); + let packet = Self::parse_inner(&mut cell)?; + Ok(packet) + } + fn parse_inner(mut bytes: &mut Cell<&[u8]>) -> Result { + let data = ParentData::parse_inner(&mut bytes)?; + Self::new(Arc::new(data)) + } + pub fn specialize(&self) -> ParentChild { + match &self.parent.child { + ParentDataChild::Child(_) => { + ParentChild::Child(Child::new(self.parent.clone()).unwrap()) + } + ParentDataChild::Payload(payload) => ParentChild::Payload(payload.clone()), + ParentDataChild::None => ParentChild::None, + } + } + fn new(parent: Arc) -> Result { + Ok(Self { parent }) + } + pub fn get_v(&self) -> Enum8 { + self.parent.as_ref().v + } + fn write_to(&self, buffer: &mut BytesMut) { + self.parent.write_to(buffer) + } + pub fn get_size(&self) -> usize { + self.parent.get_size() + } +} +impl ParentBuilder { + pub fn build(self) -> Parent { + let parent = Arc::new(ParentData { v: self.v, child: ParentDataChild::None }); + Parent::new(parent).unwrap() + } +} +impl From for Parent { + fn from(builder: ParentBuilder) -> Parent { + builder.build().into() + } +} + +#[derive(Debug, Clone, PartialEq, Eq)] +#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] +pub struct ChildData {} +#[derive(Debug, Clone, PartialEq, Eq)] +#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] +pub struct Child { + #[cfg_attr(feature = "serde", serde(flatten))] + parent: Arc, + #[cfg_attr(feature = "serde", serde(flatten))] + child: Arc, +} +#[derive(Debug)] +#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] +pub struct ChildBuilder {} +impl ChildData { + fn conforms(bytes: &[u8]) -> bool { + true + } + fn parse(bytes: &[u8]) -> Result { + let mut cell = Cell::new(bytes); + let packet = Self::parse_inner(&mut cell)?; + Ok(packet) + } + fn parse_inner(mut bytes: &mut Cell<&[u8]>) -> Result { + Ok(Self {}) + } + fn write_to(&self, buffer: &mut BytesMut) {} + fn get_total_size(&self) -> usize { + self.get_size() + } + fn get_size(&self) -> usize { + 0 + } +} +impl Packet for Child { + fn to_bytes(self) -> Bytes { + let mut buffer = BytesMut::with_capacity(self.parent.get_size()); + self.parent.write_to(&mut buffer); + buffer.freeze() + } + fn to_vec(self) -> Vec { + self.to_bytes().to_vec() + } +} +impl From for Bytes { + fn from(packet: Child) -> Self { + packet.to_bytes() + } +} +impl From for Vec { + fn from(packet: Child) -> Self { + packet.to_vec() + } +} +impl From for Parent { + fn from(packet: Child) -> Parent { + Parent::new(packet.parent).unwrap() + } +} +impl TryFrom for Child { + type Error = Error; + fn try_from(packet: Parent) -> Result { + Child::new(packet.parent) + } +} +impl Child { + pub fn parse(bytes: &[u8]) -> Result { + let mut cell = Cell::new(bytes); + let packet = Self::parse_inner(&mut cell)?; + Ok(packet) + } + fn parse_inner(mut bytes: &mut Cell<&[u8]>) -> Result { + let data = ParentData::parse_inner(&mut bytes)?; + Self::new(Arc::new(data)) + } + fn new(parent: Arc) -> Result { + let child = match &parent.child { + ParentDataChild::Child(value) => value.clone(), + _ => { + return Err(Error::InvalidChildError { + expected: stringify!(ParentDataChild::Child), + actual: format!("{:?}", &parent.child), + }) + } + }; + Ok(Self { parent, child }) + } + pub fn get_v(&self) -> Enum8 { + self.parent.as_ref().v + } + fn write_to(&self, buffer: &mut BytesMut) { + self.child.write_to(buffer) + } + pub fn get_size(&self) -> usize { + self.parent.get_size() + } +} +impl ChildBuilder { + pub fn build(self) -> Child { + let child = Arc::new(ChildData {}); + let parent = Arc::new(ParentData { v: Enum8::A, child: ParentDataChild::None }); + Child::new(parent).unwrap() + } +} +impl From for Parent { + fn from(builder: ChildBuilder) -> Parent { + builder.build().into() + } +} +impl From for Child { + fn from(builder: ChildBuilder) -> Child { + builder.build().into() + } +} diff --git a/tools/pdl/tests/generated/packet_decl_parent_with_no_payload_little_endian.rs b/tools/pdl/tests/generated/packet_decl_parent_with_no_payload_little_endian.rs new file mode 100644 index 00000000000..04f50d24108 --- /dev/null +++ b/tools/pdl/tests/generated/packet_decl_parent_with_no_payload_little_endian.rs @@ -0,0 +1,374 @@ +// @generated rust packets from test + +use bytes::{Buf, BufMut, Bytes, BytesMut}; +use std::cell::Cell; +use std::convert::{TryFrom, TryInto}; +use std::fmt; +use std::sync::Arc; +use thiserror::Error; + +type Result = std::result::Result; + +#[doc = r" Private prevents users from creating arbitrary scalar values"] +#[doc = r" in situations where the value needs to be validated."] +#[doc = r" Users can freely deref the value, but only the backend"] +#[doc = r" may create it."] +#[derive(Debug, Clone, Copy, Hash, PartialEq, Eq, PartialOrd, Ord)] +pub struct Private(T); +impl std::ops::Deref for Private { + type Target = T; + fn deref(&self) -> &Self::Target { + &self.0 + } +} + +#[derive(Debug, Error)] +pub enum Error { + #[error("Packet parsing failed")] + InvalidPacketError, + #[error("{field} was {value:x}, which is not known")] + ConstraintOutOfBounds { field: String, value: u64 }, + #[error("Got {actual:x}, expected {expected:x}")] + InvalidFixedValue { expected: u64, actual: u64 }, + #[error("when parsing {obj} needed length of {wanted} but got {got}")] + InvalidLengthError { obj: String, wanted: usize, got: usize }, + #[error("array size ({array} bytes) is not a multiple of the element size ({element} bytes)")] + InvalidArraySize { array: usize, element: usize }, + #[error("Due to size restrictions a struct could not be parsed.")] + ImpossibleStructError, + #[error("when parsing field {obj}.{field}, {value} is not a valid {type_} value")] + InvalidEnumValueError { obj: String, field: String, value: u64, type_: String }, + #[error("expected child {expected}, got {actual}")] + InvalidChildError { expected: &'static str, actual: String }, +} + +pub trait Packet { + fn to_bytes(self) -> Bytes; + fn to_vec(self) -> Vec; +} + +#[repr(u64)] +#[derive(Debug, Clone, Copy, Hash, Eq, PartialEq)] +#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] +#[cfg_attr(feature = "serde", serde(try_from = "u8", into = "u8"))] +pub enum Enum8 { + A = 0x0, +} +impl TryFrom for Enum8 { + type Error = u8; + fn try_from(value: u8) -> std::result::Result { + match value { + 0x0 => Ok(Enum8::A), + _ => Err(value), + } + } +} +impl From<&Enum8> for u8 { + fn from(value: &Enum8) -> Self { + match value { + Enum8::A => 0x0, + } + } +} +impl From for u8 { + fn from(value: Enum8) -> Self { + (&value).into() + } +} +impl From for i16 { + fn from(value: Enum8) -> Self { + u8::from(value) as Self + } +} +impl From for i32 { + fn from(value: Enum8) -> Self { + u8::from(value) as Self + } +} +impl From for i64 { + fn from(value: Enum8) -> Self { + u8::from(value) as Self + } +} +impl From for u16 { + fn from(value: Enum8) -> Self { + u8::from(value) as Self + } +} +impl From for u32 { + fn from(value: Enum8) -> Self { + u8::from(value) as Self + } +} +impl From for u64 { + fn from(value: Enum8) -> Self { + u8::from(value) as Self + } +} + +#[derive(Debug, Clone, PartialEq, Eq)] +#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] +pub enum ParentDataChild { + Child(Arc), + Payload(Bytes), + None, +} +impl ParentDataChild { + fn get_total_size(&self) -> usize { + match self { + ParentDataChild::Child(value) => value.get_total_size(), + ParentDataChild::Payload(bytes) => bytes.len(), + ParentDataChild::None => 0, + } + } +} +#[derive(Debug, Clone, PartialEq, Eq)] +#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] +pub enum ParentChild { + Child(Child), + Payload(Bytes), + None, +} +#[derive(Debug, Clone, PartialEq, Eq)] +#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] +pub struct ParentData { + v: Enum8, + child: ParentDataChild, +} +#[derive(Debug, Clone, PartialEq, Eq)] +#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] +pub struct Parent { + #[cfg_attr(feature = "serde", serde(flatten))] + parent: Arc, +} +#[derive(Debug)] +#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] +pub struct ParentBuilder { + pub v: Enum8, + pub payload: Option, +} +impl ParentData { + fn conforms(bytes: &[u8]) -> bool { + bytes.len() >= 1 + } + fn parse(bytes: &[u8]) -> Result { + let mut cell = Cell::new(bytes); + let packet = Self::parse_inner(&mut cell)?; + Ok(packet) + } + fn parse_inner(mut bytes: &mut Cell<&[u8]>) -> Result { + if bytes.get().remaining() < 1 { + return Err(Error::InvalidLengthError { + obj: "Parent".to_string(), + wanted: 1, + got: bytes.get().remaining(), + }); + } + let v = Enum8::try_from(bytes.get_mut().get_u8()).map_err(|_| { + Error::InvalidEnumValueError { + obj: "Parent".to_string(), + field: "v".to_string(), + value: bytes.get_mut().get_u8() as u64, + type_: "Enum8".to_string(), + } + })?; + let payload: &[u8] = &[]; + let child = match (v) { + (Enum8::A) if ChildData::conforms(&payload) => { + let mut cell = Cell::new(payload); + let child_data = ChildData::parse_inner(&mut cell)?; + ParentDataChild::Child(Arc::new(child_data)) + } + _ if !payload.is_empty() => ParentDataChild::Payload(Bytes::copy_from_slice(payload)), + _ => ParentDataChild::None, + }; + Ok(Self { v, child }) + } + fn write_to(&self, buffer: &mut BytesMut) { + buffer.put_u8(u8::from(self.v)); + } + fn get_total_size(&self) -> usize { + self.get_size() + } + fn get_size(&self) -> usize { + 1 + } +} +impl Packet for Parent { + fn to_bytes(self) -> Bytes { + let mut buffer = BytesMut::with_capacity(self.parent.get_size()); + self.parent.write_to(&mut buffer); + buffer.freeze() + } + fn to_vec(self) -> Vec { + self.to_bytes().to_vec() + } +} +impl From for Bytes { + fn from(packet: Parent) -> Self { + packet.to_bytes() + } +} +impl From for Vec { + fn from(packet: Parent) -> Self { + packet.to_vec() + } +} +impl Parent { + pub fn parse(bytes: &[u8]) -> Result { + let mut cell = Cell::new(bytes); + let packet = Self::parse_inner(&mut cell)?; + Ok(packet) + } + fn parse_inner(mut bytes: &mut Cell<&[u8]>) -> Result { + let data = ParentData::parse_inner(&mut bytes)?; + Self::new(Arc::new(data)) + } + pub fn specialize(&self) -> ParentChild { + match &self.parent.child { + ParentDataChild::Child(_) => { + ParentChild::Child(Child::new(self.parent.clone()).unwrap()) + } + ParentDataChild::Payload(payload) => ParentChild::Payload(payload.clone()), + ParentDataChild::None => ParentChild::None, + } + } + fn new(parent: Arc) -> Result { + Ok(Self { parent }) + } + pub fn get_v(&self) -> Enum8 { + self.parent.as_ref().v + } + fn write_to(&self, buffer: &mut BytesMut) { + self.parent.write_to(buffer) + } + pub fn get_size(&self) -> usize { + self.parent.get_size() + } +} +impl ParentBuilder { + pub fn build(self) -> Parent { + let parent = Arc::new(ParentData { v: self.v, child: ParentDataChild::None }); + Parent::new(parent).unwrap() + } +} +impl From for Parent { + fn from(builder: ParentBuilder) -> Parent { + builder.build().into() + } +} + +#[derive(Debug, Clone, PartialEq, Eq)] +#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] +pub struct ChildData {} +#[derive(Debug, Clone, PartialEq, Eq)] +#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] +pub struct Child { + #[cfg_attr(feature = "serde", serde(flatten))] + parent: Arc, + #[cfg_attr(feature = "serde", serde(flatten))] + child: Arc, +} +#[derive(Debug)] +#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] +pub struct ChildBuilder {} +impl ChildData { + fn conforms(bytes: &[u8]) -> bool { + true + } + fn parse(bytes: &[u8]) -> Result { + let mut cell = Cell::new(bytes); + let packet = Self::parse_inner(&mut cell)?; + Ok(packet) + } + fn parse_inner(mut bytes: &mut Cell<&[u8]>) -> Result { + Ok(Self {}) + } + fn write_to(&self, buffer: &mut BytesMut) {} + fn get_total_size(&self) -> usize { + self.get_size() + } + fn get_size(&self) -> usize { + 0 + } +} +impl Packet for Child { + fn to_bytes(self) -> Bytes { + let mut buffer = BytesMut::with_capacity(self.parent.get_size()); + self.parent.write_to(&mut buffer); + buffer.freeze() + } + fn to_vec(self) -> Vec { + self.to_bytes().to_vec() + } +} +impl From for Bytes { + fn from(packet: Child) -> Self { + packet.to_bytes() + } +} +impl From for Vec { + fn from(packet: Child) -> Self { + packet.to_vec() + } +} +impl From for Parent { + fn from(packet: Child) -> Parent { + Parent::new(packet.parent).unwrap() + } +} +impl TryFrom for Child { + type Error = Error; + fn try_from(packet: Parent) -> Result { + Child::new(packet.parent) + } +} +impl Child { + pub fn parse(bytes: &[u8]) -> Result { + let mut cell = Cell::new(bytes); + let packet = Self::parse_inner(&mut cell)?; + Ok(packet) + } + fn parse_inner(mut bytes: &mut Cell<&[u8]>) -> Result { + let data = ParentData::parse_inner(&mut bytes)?; + Self::new(Arc::new(data)) + } + fn new(parent: Arc) -> Result { + let child = match &parent.child { + ParentDataChild::Child(value) => value.clone(), + _ => { + return Err(Error::InvalidChildError { + expected: stringify!(ParentDataChild::Child), + actual: format!("{:?}", &parent.child), + }) + } + }; + Ok(Self { parent, child }) + } + pub fn get_v(&self) -> Enum8 { + self.parent.as_ref().v + } + fn write_to(&self, buffer: &mut BytesMut) { + self.child.write_to(buffer) + } + pub fn get_size(&self) -> usize { + self.parent.get_size() + } +} +impl ChildBuilder { + pub fn build(self) -> Child { + let child = Arc::new(ChildData {}); + let parent = Arc::new(ParentData { v: Enum8::A, child: ParentDataChild::None }); + Child::new(parent).unwrap() + } +} +impl From for Parent { + fn from(builder: ChildBuilder) -> Parent { + builder.build().into() + } +} +impl From for Child { + fn from(builder: ChildBuilder) -> Child { + builder.build().into() + } +} -- GitLab From 96d7b10203d72b27a1bef5c4391dd69bef894b91 Mon Sep 17 00:00:00 2001 From: Henri Chataing Date: Wed, 17 May 2023 04:31:22 +0000 Subject: [PATCH 0111/2405] pdl: Fix generation of aliased child packet parsing The generator did not handle well packets with child aliases, as it was generating a wildcard with no constraint for the child specialization. Extend the generator to handle such cases, within a limit - fields must have constraints in immediate children (i.e. cannot generate matcher for fields if they are constrained by granchildren only) - double aliased packets are not allowed (i.e. packets with no constraints for two generations) Bug: 279465240 Test: atest pdl_generated_files_compile Change-Id: If4c3a82e8a06edeab4ef54a8c109b994f6a2dc25 --- tools/pdl/Android.bp | 2 + tools/pdl/src/backends/rust.rs | 30 + tools/pdl/src/backends/rust/parser.rs | 87 +- tools/pdl/src/lint.rs | 2 +- ...decl_parent_with_alias_child_big_endian.rs | 930 ++++++++++++++++++ ...l_parent_with_alias_child_little_endian.rs | 930 ++++++++++++++++++ 6 files changed, 1943 insertions(+), 38 deletions(-) create mode 100644 tools/pdl/tests/generated/packet_decl_parent_with_alias_child_big_endian.rs create mode 100644 tools/pdl/tests/generated/packet_decl_parent_with_alias_child_little_endian.rs diff --git a/tools/pdl/Android.bp b/tools/pdl/Android.bp index 14284f055bd..f066f4d54d7 100644 --- a/tools/pdl/Android.bp +++ b/tools/pdl/Android.bp @@ -97,6 +97,8 @@ filegroup { "tests/generated/packet_decl_mask_scalar_value_little_endian.rs", "tests/generated/packet_decl_mixed_scalars_enums_big_endian.rs", "tests/generated/packet_decl_mixed_scalars_enums_little_endian.rs", + "tests/generated/packet_decl_parent_with_alias_child_big_endian.rs", + "tests/generated/packet_decl_parent_with_alias_child_little_endian.rs", "tests/generated/packet_decl_parent_with_no_payload_big_endian.rs", "tests/generated/packet_decl_parent_with_no_payload_little_endian.rs", "tests/generated/packet_decl_payload_field_unknown_size_big_endian.rs", diff --git a/tools/pdl/src/backends/rust.rs b/tools/pdl/src/backends/rust.rs index 037e3548445..506427c74cb 100644 --- a/tools/pdl/src/backends/rust.rs +++ b/tools/pdl/src/backends/rust.rs @@ -1498,6 +1498,36 @@ mod tests { " ); + test_pdl!( + packet_decl_parent_with_alias_child, + " + enum Enum8 : 8 { + A = 0, + B = 1, + C = 2, + } + + packet Parent { + v : Enum8, + _payload_, + } + + packet AliasChild : Parent { + _payload_ + } + + packet NormalChild : Parent (v = A) { + } + + packet NormalGrandChild1 : AliasChild (v = B) { + } + + packet NormalGrandChild2 : AliasChild (v = C) { + _payload_ + } + " + ); + // TODO(mgeisler): enable this test when we have an approach to // struct fields with parents. // diff --git a/tools/pdl/src/backends/rust/parser.rs b/tools/pdl/src/backends/rust/parser.rs index 2a955c625be..196ae0059c9 100644 --- a/tools/pdl/src/backends/rust/parser.rs +++ b/tools/pdl/src/backends/rust/parser.rs @@ -18,7 +18,7 @@ use crate::backends::rust::{ }; use crate::{ast, lint}; use quote::{format_ident, quote}; -use std::collections::{BTreeSet, HashMap}; +use std::collections::BTreeSet; fn size_field_ident(id: &str) -> proc_macro2::Ident { format_ident!("{}_size", id.trim_matches('_')) @@ -627,51 +627,64 @@ impl<'a> FieldParser<'a> { return; } - let child_ids = children + // Gather fields that are constrained in immediate child declarations. + // Keep the fields sorted by name. + // TODO: fields that are only matched in grand children will not be included. + let constrained_fields = children .iter() - .map(|child| format_ident!("{}", child.id().unwrap())) - .collect::>(); - let child_ids_data = child_ids.iter().map(|ident| format_ident!("{ident}Data")); - - // Set of field names (sorted by name). - let mut constrained_fields = BTreeSet::new(); - // Maps (child name, field name) -> value. - let mut constraint_values = HashMap::new(); + .flat_map(|child| child.constraints().map(|c| &c.id)) + .collect::>(); + + let mut match_values = Vec::new(); + let mut child_parse_args = Vec::new(); + let mut child_ids_data = Vec::new(); + let mut child_ids = Vec::new(); + let get_constraint_value = |mut constraints: std::slice::Iter<'_, ast::Constraint>, + id: &str| + -> Option { + constraints.find(|c| c.id == id).map(|c| constraint_to_value(packet_scope, c)) + }; for child in children.iter() { - match &child.desc { - ast::DeclDesc::Packet { id, constraints, .. } - | ast::DeclDesc::Struct { id, constraints, .. } => { - for constraint in constraints.iter() { - constrained_fields.insert(&constraint.id); - constraint_values.insert( - (id.as_str(), &constraint.id), - constraint_to_value(packet_scope, constraint), - ); - } - } - _ => unreachable!("Invalid child: {child:?}"), + let tuple_values = constrained_fields + .iter() + .map(|id| { + get_constraint_value(child.constraints(), id).map(|v| vec![v]).unwrap_or_else( + || { + self.scope + .file + .iter_children(child) + .filter_map(|d| get_constraint_value(d.constraints(), id)) + .collect() + }, + ) + }) + .collect::>(); + + // If no constraint values are found for the tuple just skip the child + // packet as it would capture unwanted input packets. + if tuple_values.iter().all(|v| v.is_empty()) { + continue; } + + let tuple_values = tuple_values + .iter() + .map(|v| v.is_empty().then_some(quote!(_)).unwrap_or_else(|| quote!( #(#v)|* ))) + .collect::>(); + + let fields = find_constrained_parent_fields(self.scope, child.id().unwrap()) + .map(|field| format_ident!("{}", field.id().unwrap())); + + match_values.push(quote!( (#(#tuple_values),*) )); + child_parse_args.push(quote!( #(, #fields)*)); + child_ids_data.push(format_ident!("{}Data", child.id().unwrap())); + child_ids.push(format_ident!("{}", child.id().unwrap())); } - let wildcard = quote!(_); - let match_values = children.iter().map(|child| { - let child_id = child.id().unwrap(); - let values = constrained_fields.iter().map(|field_name| { - constraint_values.get(&(child_id, field_name)).unwrap_or(&wildcard) - }); - quote! { - (#(#values),*) - } - }); let constrained_field_idents = constrained_fields.iter().map(|field| format_ident!("{field}")); - let child_parse_args = children.iter().map(|child| { - let fields = find_constrained_parent_fields(self.scope, child.id().unwrap()) - .map(|field| format_ident!("{}", field.id().unwrap())); - quote!(#(, #fields)*) - }); let packet_data_child = format_ident!("{}DataChild", self.packet_name); + // Parsing of packet children requires having a payload field; // it is allowed to inherit from a packet with empty payload, in this // case generate an empty payload value. diff --git a/tools/pdl/src/lint.rs b/tools/pdl/src/lint.rs index 7a389fd1fcb..874596eada0 100644 --- a/tools/pdl/src/lint.rs +++ b/tools/pdl/src/lint.rs @@ -21,7 +21,7 @@ use crate::ast::*; #[derive(Debug)] pub struct Scope<'d> { // Original file. - file: &'d analyzer_ast::File, + pub file: &'d analyzer_ast::File, // Collection of Group, Packet, Enum, Struct, Checksum, and CustomField declarations. pub typedef: HashMap, diff --git a/tools/pdl/tests/generated/packet_decl_parent_with_alias_child_big_endian.rs b/tools/pdl/tests/generated/packet_decl_parent_with_alias_child_big_endian.rs new file mode 100644 index 00000000000..2488871665f --- /dev/null +++ b/tools/pdl/tests/generated/packet_decl_parent_with_alias_child_big_endian.rs @@ -0,0 +1,930 @@ +// @generated rust packets from test + +use bytes::{Buf, BufMut, Bytes, BytesMut}; +use std::cell::Cell; +use std::convert::{TryFrom, TryInto}; +use std::fmt; +use std::sync::Arc; +use thiserror::Error; + +type Result = std::result::Result; + +#[doc = r" Private prevents users from creating arbitrary scalar values"] +#[doc = r" in situations where the value needs to be validated."] +#[doc = r" Users can freely deref the value, but only the backend"] +#[doc = r" may create it."] +#[derive(Debug, Clone, Copy, Hash, PartialEq, Eq, PartialOrd, Ord)] +pub struct Private(T); +impl std::ops::Deref for Private { + type Target = T; + fn deref(&self) -> &Self::Target { + &self.0 + } +} + +#[derive(Debug, Error)] +pub enum Error { + #[error("Packet parsing failed")] + InvalidPacketError, + #[error("{field} was {value:x}, which is not known")] + ConstraintOutOfBounds { field: String, value: u64 }, + #[error("Got {actual:x}, expected {expected:x}")] + InvalidFixedValue { expected: u64, actual: u64 }, + #[error("when parsing {obj} needed length of {wanted} but got {got}")] + InvalidLengthError { obj: String, wanted: usize, got: usize }, + #[error("array size ({array} bytes) is not a multiple of the element size ({element} bytes)")] + InvalidArraySize { array: usize, element: usize }, + #[error("Due to size restrictions a struct could not be parsed.")] + ImpossibleStructError, + #[error("when parsing field {obj}.{field}, {value} is not a valid {type_} value")] + InvalidEnumValueError { obj: String, field: String, value: u64, type_: String }, + #[error("expected child {expected}, got {actual}")] + InvalidChildError { expected: &'static str, actual: String }, +} + +pub trait Packet { + fn to_bytes(self) -> Bytes; + fn to_vec(self) -> Vec; +} + +#[repr(u64)] +#[derive(Debug, Clone, Copy, Hash, Eq, PartialEq)] +#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] +#[cfg_attr(feature = "serde", serde(try_from = "u8", into = "u8"))] +pub enum Enum8 { + A = 0x0, + B = 0x1, + C = 0x2, +} +impl TryFrom for Enum8 { + type Error = u8; + fn try_from(value: u8) -> std::result::Result { + match value { + 0x0 => Ok(Enum8::A), + 0x1 => Ok(Enum8::B), + 0x2 => Ok(Enum8::C), + _ => Err(value), + } + } +} +impl From<&Enum8> for u8 { + fn from(value: &Enum8) -> Self { + match value { + Enum8::A => 0x0, + Enum8::B => 0x1, + Enum8::C => 0x2, + } + } +} +impl From for u8 { + fn from(value: Enum8) -> Self { + (&value).into() + } +} +impl From for i16 { + fn from(value: Enum8) -> Self { + u8::from(value) as Self + } +} +impl From for i32 { + fn from(value: Enum8) -> Self { + u8::from(value) as Self + } +} +impl From for i64 { + fn from(value: Enum8) -> Self { + u8::from(value) as Self + } +} +impl From for u16 { + fn from(value: Enum8) -> Self { + u8::from(value) as Self + } +} +impl From for u32 { + fn from(value: Enum8) -> Self { + u8::from(value) as Self + } +} +impl From for u64 { + fn from(value: Enum8) -> Self { + u8::from(value) as Self + } +} + +#[derive(Debug, Clone, PartialEq, Eq)] +#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] +pub enum ParentDataChild { + AliasChild(Arc), + NormalChild(Arc), + Payload(Bytes), + None, +} +impl ParentDataChild { + fn get_total_size(&self) -> usize { + match self { + ParentDataChild::AliasChild(value) => value.get_total_size(), + ParentDataChild::NormalChild(value) => value.get_total_size(), + ParentDataChild::Payload(bytes) => bytes.len(), + ParentDataChild::None => 0, + } + } +} +#[derive(Debug, Clone, PartialEq, Eq)] +#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] +pub enum ParentChild { + AliasChild(AliasChild), + NormalChild(NormalChild), + Payload(Bytes), + None, +} +#[derive(Debug, Clone, PartialEq, Eq)] +#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] +pub struct ParentData { + v: Enum8, + child: ParentDataChild, +} +#[derive(Debug, Clone, PartialEq, Eq)] +#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] +pub struct Parent { + #[cfg_attr(feature = "serde", serde(flatten))] + parent: Arc, +} +#[derive(Debug)] +#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] +pub struct ParentBuilder { + pub v: Enum8, + pub payload: Option, +} +impl ParentData { + fn conforms(bytes: &[u8]) -> bool { + bytes.len() >= 1 + } + fn parse(bytes: &[u8]) -> Result { + let mut cell = Cell::new(bytes); + let packet = Self::parse_inner(&mut cell)?; + Ok(packet) + } + fn parse_inner(mut bytes: &mut Cell<&[u8]>) -> Result { + if bytes.get().remaining() < 1 { + return Err(Error::InvalidLengthError { + obj: "Parent".to_string(), + wanted: 1, + got: bytes.get().remaining(), + }); + } + let v = Enum8::try_from(bytes.get_mut().get_u8()).map_err(|_| { + Error::InvalidEnumValueError { + obj: "Parent".to_string(), + field: "v".to_string(), + value: bytes.get_mut().get_u8() as u64, + type_: "Enum8".to_string(), + } + })?; + let payload = bytes.get(); + bytes.get_mut().advance(payload.len()); + let child = match (v) { + (Enum8::B | Enum8::C) if AliasChildData::conforms(&payload) => { + let mut cell = Cell::new(payload); + let child_data = AliasChildData::parse_inner(&mut cell, v)?; + ParentDataChild::AliasChild(Arc::new(child_data)) + } + (Enum8::A) if NormalChildData::conforms(&payload) => { + let mut cell = Cell::new(payload); + let child_data = NormalChildData::parse_inner(&mut cell)?; + ParentDataChild::NormalChild(Arc::new(child_data)) + } + _ if !payload.is_empty() => ParentDataChild::Payload(Bytes::copy_from_slice(payload)), + _ => ParentDataChild::None, + }; + Ok(Self { v, child }) + } + fn write_to(&self, buffer: &mut BytesMut) { + buffer.put_u8(u8::from(self.v)); + match &self.child { + ParentDataChild::AliasChild(child) => child.write_to(buffer), + ParentDataChild::NormalChild(child) => child.write_to(buffer), + ParentDataChild::Payload(payload) => buffer.put_slice(payload), + ParentDataChild::None => {} + } + } + fn get_total_size(&self) -> usize { + self.get_size() + } + fn get_size(&self) -> usize { + 1 + self.child.get_total_size() + } +} +impl Packet for Parent { + fn to_bytes(self) -> Bytes { + let mut buffer = BytesMut::with_capacity(self.parent.get_size()); + self.parent.write_to(&mut buffer); + buffer.freeze() + } + fn to_vec(self) -> Vec { + self.to_bytes().to_vec() + } +} +impl From for Bytes { + fn from(packet: Parent) -> Self { + packet.to_bytes() + } +} +impl From for Vec { + fn from(packet: Parent) -> Self { + packet.to_vec() + } +} +impl Parent { + pub fn parse(bytes: &[u8]) -> Result { + let mut cell = Cell::new(bytes); + let packet = Self::parse_inner(&mut cell)?; + Ok(packet) + } + fn parse_inner(mut bytes: &mut Cell<&[u8]>) -> Result { + let data = ParentData::parse_inner(&mut bytes)?; + Self::new(Arc::new(data)) + } + pub fn specialize(&self) -> ParentChild { + match &self.parent.child { + ParentDataChild::AliasChild(_) => { + ParentChild::AliasChild(AliasChild::new(self.parent.clone()).unwrap()) + } + ParentDataChild::NormalChild(_) => { + ParentChild::NormalChild(NormalChild::new(self.parent.clone()).unwrap()) + } + ParentDataChild::Payload(payload) => ParentChild::Payload(payload.clone()), + ParentDataChild::None => ParentChild::None, + } + } + fn new(parent: Arc) -> Result { + Ok(Self { parent }) + } + pub fn get_v(&self) -> Enum8 { + self.parent.as_ref().v + } + fn write_to(&self, buffer: &mut BytesMut) { + self.parent.write_to(buffer) + } + pub fn get_size(&self) -> usize { + self.parent.get_size() + } +} +impl ParentBuilder { + pub fn build(self) -> Parent { + let parent = Arc::new(ParentData { + v: self.v, + child: match self.payload { + None => ParentDataChild::None, + Some(bytes) => ParentDataChild::Payload(bytes), + }, + }); + Parent::new(parent).unwrap() + } +} +impl From for Parent { + fn from(builder: ParentBuilder) -> Parent { + builder.build().into() + } +} + +#[derive(Debug, Clone, PartialEq, Eq)] +#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] +pub enum AliasChildDataChild { + NormalGrandChild1(Arc), + NormalGrandChild2(Arc), + Payload(Bytes), + None, +} +impl AliasChildDataChild { + fn get_total_size(&self) -> usize { + match self { + AliasChildDataChild::NormalGrandChild1(value) => value.get_total_size(), + AliasChildDataChild::NormalGrandChild2(value) => value.get_total_size(), + AliasChildDataChild::Payload(bytes) => bytes.len(), + AliasChildDataChild::None => 0, + } + } +} +#[derive(Debug, Clone, PartialEq, Eq)] +#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] +pub enum AliasChildChild { + NormalGrandChild1(NormalGrandChild1), + NormalGrandChild2(NormalGrandChild2), + Payload(Bytes), + None, +} +#[derive(Debug, Clone, PartialEq, Eq)] +#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] +pub struct AliasChildData { + child: AliasChildDataChild, +} +#[derive(Debug, Clone, PartialEq, Eq)] +#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] +pub struct AliasChild { + #[cfg_attr(feature = "serde", serde(flatten))] + parent: Arc, + #[cfg_attr(feature = "serde", serde(flatten))] + aliaschild: Arc, +} +#[derive(Debug)] +#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] +pub struct AliasChildBuilder { + pub v: Enum8, + pub payload: Option, +} +impl AliasChildData { + fn conforms(bytes: &[u8]) -> bool { + true + } + fn parse(bytes: &[u8], v: Enum8) -> Result { + let mut cell = Cell::new(bytes); + let packet = Self::parse_inner(&mut cell, v)?; + Ok(packet) + } + fn parse_inner(mut bytes: &mut Cell<&[u8]>, v: Enum8) -> Result { + let payload = bytes.get(); + bytes.get_mut().advance(payload.len()); + let child = match (v) { + (Enum8::B) if NormalGrandChild1Data::conforms(&payload) => { + let mut cell = Cell::new(payload); + let child_data = NormalGrandChild1Data::parse_inner(&mut cell)?; + AliasChildDataChild::NormalGrandChild1(Arc::new(child_data)) + } + (Enum8::C) if NormalGrandChild2Data::conforms(&payload) => { + let mut cell = Cell::new(payload); + let child_data = NormalGrandChild2Data::parse_inner(&mut cell)?; + AliasChildDataChild::NormalGrandChild2(Arc::new(child_data)) + } + _ if !payload.is_empty() => { + AliasChildDataChild::Payload(Bytes::copy_from_slice(payload)) + } + _ => AliasChildDataChild::None, + }; + Ok(Self { child }) + } + fn write_to(&self, buffer: &mut BytesMut) { + match &self.child { + AliasChildDataChild::NormalGrandChild1(child) => child.write_to(buffer), + AliasChildDataChild::NormalGrandChild2(child) => child.write_to(buffer), + AliasChildDataChild::Payload(payload) => buffer.put_slice(payload), + AliasChildDataChild::None => {} + } + } + fn get_total_size(&self) -> usize { + self.get_size() + } + fn get_size(&self) -> usize { + self.child.get_total_size() + } +} +impl Packet for AliasChild { + fn to_bytes(self) -> Bytes { + let mut buffer = BytesMut::with_capacity(self.parent.get_size()); + self.parent.write_to(&mut buffer); + buffer.freeze() + } + fn to_vec(self) -> Vec { + self.to_bytes().to_vec() + } +} +impl From for Bytes { + fn from(packet: AliasChild) -> Self { + packet.to_bytes() + } +} +impl From for Vec { + fn from(packet: AliasChild) -> Self { + packet.to_vec() + } +} +impl From for Parent { + fn from(packet: AliasChild) -> Parent { + Parent::new(packet.parent).unwrap() + } +} +impl TryFrom for AliasChild { + type Error = Error; + fn try_from(packet: Parent) -> Result { + AliasChild::new(packet.parent) + } +} +impl AliasChild { + pub fn parse(bytes: &[u8]) -> Result { + let mut cell = Cell::new(bytes); + let packet = Self::parse_inner(&mut cell)?; + Ok(packet) + } + fn parse_inner(mut bytes: &mut Cell<&[u8]>) -> Result { + let data = ParentData::parse_inner(&mut bytes)?; + Self::new(Arc::new(data)) + } + pub fn specialize(&self) -> AliasChildChild { + match &self.aliaschild.child { + AliasChildDataChild::NormalGrandChild1(_) => AliasChildChild::NormalGrandChild1( + NormalGrandChild1::new(self.parent.clone()).unwrap(), + ), + AliasChildDataChild::NormalGrandChild2(_) => AliasChildChild::NormalGrandChild2( + NormalGrandChild2::new(self.parent.clone()).unwrap(), + ), + AliasChildDataChild::Payload(payload) => AliasChildChild::Payload(payload.clone()), + AliasChildDataChild::None => AliasChildChild::None, + } + } + fn new(parent: Arc) -> Result { + let aliaschild = match &parent.child { + ParentDataChild::AliasChild(value) => value.clone(), + _ => { + return Err(Error::InvalidChildError { + expected: stringify!(ParentDataChild::AliasChild), + actual: format!("{:?}", &parent.child), + }) + } + }; + Ok(Self { parent, aliaschild }) + } + pub fn get_v(&self) -> Enum8 { + self.parent.as_ref().v + } + fn write_to(&self, buffer: &mut BytesMut) { + self.aliaschild.write_to(buffer) + } + pub fn get_size(&self) -> usize { + self.parent.get_size() + } +} +impl AliasChildBuilder { + pub fn build(self) -> AliasChild { + let aliaschild = Arc::new(AliasChildData { + child: match self.payload { + None => AliasChildDataChild::None, + Some(bytes) => AliasChildDataChild::Payload(bytes), + }, + }); + let parent = + Arc::new(ParentData { v: self.v, child: ParentDataChild::AliasChild(aliaschild) }); + AliasChild::new(parent).unwrap() + } +} +impl From for Parent { + fn from(builder: AliasChildBuilder) -> Parent { + builder.build().into() + } +} +impl From for AliasChild { + fn from(builder: AliasChildBuilder) -> AliasChild { + builder.build().into() + } +} + +#[derive(Debug, Clone, PartialEq, Eq)] +#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] +pub struct NormalChildData {} +#[derive(Debug, Clone, PartialEq, Eq)] +#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] +pub struct NormalChild { + #[cfg_attr(feature = "serde", serde(flatten))] + parent: Arc, + #[cfg_attr(feature = "serde", serde(flatten))] + normalchild: Arc, +} +#[derive(Debug)] +#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] +pub struct NormalChildBuilder {} +impl NormalChildData { + fn conforms(bytes: &[u8]) -> bool { + true + } + fn parse(bytes: &[u8]) -> Result { + let mut cell = Cell::new(bytes); + let packet = Self::parse_inner(&mut cell)?; + Ok(packet) + } + fn parse_inner(mut bytes: &mut Cell<&[u8]>) -> Result { + Ok(Self {}) + } + fn write_to(&self, buffer: &mut BytesMut) {} + fn get_total_size(&self) -> usize { + self.get_size() + } + fn get_size(&self) -> usize { + 0 + } +} +impl Packet for NormalChild { + fn to_bytes(self) -> Bytes { + let mut buffer = BytesMut::with_capacity(self.parent.get_size()); + self.parent.write_to(&mut buffer); + buffer.freeze() + } + fn to_vec(self) -> Vec { + self.to_bytes().to_vec() + } +} +impl From for Bytes { + fn from(packet: NormalChild) -> Self { + packet.to_bytes() + } +} +impl From for Vec { + fn from(packet: NormalChild) -> Self { + packet.to_vec() + } +} +impl From for Parent { + fn from(packet: NormalChild) -> Parent { + Parent::new(packet.parent).unwrap() + } +} +impl TryFrom for NormalChild { + type Error = Error; + fn try_from(packet: Parent) -> Result { + NormalChild::new(packet.parent) + } +} +impl NormalChild { + pub fn parse(bytes: &[u8]) -> Result { + let mut cell = Cell::new(bytes); + let packet = Self::parse_inner(&mut cell)?; + Ok(packet) + } + fn parse_inner(mut bytes: &mut Cell<&[u8]>) -> Result { + let data = ParentData::parse_inner(&mut bytes)?; + Self::new(Arc::new(data)) + } + fn new(parent: Arc) -> Result { + let normalchild = match &parent.child { + ParentDataChild::NormalChild(value) => value.clone(), + _ => { + return Err(Error::InvalidChildError { + expected: stringify!(ParentDataChild::NormalChild), + actual: format!("{:?}", &parent.child), + }) + } + }; + Ok(Self { parent, normalchild }) + } + pub fn get_v(&self) -> Enum8 { + self.parent.as_ref().v + } + fn write_to(&self, buffer: &mut BytesMut) { + self.normalchild.write_to(buffer) + } + pub fn get_size(&self) -> usize { + self.parent.get_size() + } +} +impl NormalChildBuilder { + pub fn build(self) -> NormalChild { + let normalchild = Arc::new(NormalChildData {}); + let parent = + Arc::new(ParentData { v: Enum8::A, child: ParentDataChild::NormalChild(normalchild) }); + NormalChild::new(parent).unwrap() + } +} +impl From for Parent { + fn from(builder: NormalChildBuilder) -> Parent { + builder.build().into() + } +} +impl From for NormalChild { + fn from(builder: NormalChildBuilder) -> NormalChild { + builder.build().into() + } +} + +#[derive(Debug, Clone, PartialEq, Eq)] +#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] +pub struct NormalGrandChild1Data {} +#[derive(Debug, Clone, PartialEq, Eq)] +#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] +pub struct NormalGrandChild1 { + #[cfg_attr(feature = "serde", serde(flatten))] + parent: Arc, + #[cfg_attr(feature = "serde", serde(flatten))] + aliaschild: Arc, + #[cfg_attr(feature = "serde", serde(flatten))] + normalgrandchild1: Arc, +} +#[derive(Debug)] +#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] +pub struct NormalGrandChild1Builder {} +impl NormalGrandChild1Data { + fn conforms(bytes: &[u8]) -> bool { + true + } + fn parse(bytes: &[u8]) -> Result { + let mut cell = Cell::new(bytes); + let packet = Self::parse_inner(&mut cell)?; + Ok(packet) + } + fn parse_inner(mut bytes: &mut Cell<&[u8]>) -> Result { + Ok(Self {}) + } + fn write_to(&self, buffer: &mut BytesMut) {} + fn get_total_size(&self) -> usize { + self.get_size() + } + fn get_size(&self) -> usize { + 0 + } +} +impl Packet for NormalGrandChild1 { + fn to_bytes(self) -> Bytes { + let mut buffer = BytesMut::with_capacity(self.parent.get_size()); + self.parent.write_to(&mut buffer); + buffer.freeze() + } + fn to_vec(self) -> Vec { + self.to_bytes().to_vec() + } +} +impl From for Bytes { + fn from(packet: NormalGrandChild1) -> Self { + packet.to_bytes() + } +} +impl From for Vec { + fn from(packet: NormalGrandChild1) -> Self { + packet.to_vec() + } +} +impl From for Parent { + fn from(packet: NormalGrandChild1) -> Parent { + Parent::new(packet.parent).unwrap() + } +} +impl From for AliasChild { + fn from(packet: NormalGrandChild1) -> AliasChild { + AliasChild::new(packet.parent).unwrap() + } +} +impl TryFrom for NormalGrandChild1 { + type Error = Error; + fn try_from(packet: Parent) -> Result { + NormalGrandChild1::new(packet.parent) + } +} +impl NormalGrandChild1 { + pub fn parse(bytes: &[u8]) -> Result { + let mut cell = Cell::new(bytes); + let packet = Self::parse_inner(&mut cell)?; + Ok(packet) + } + fn parse_inner(mut bytes: &mut Cell<&[u8]>) -> Result { + let data = ParentData::parse_inner(&mut bytes)?; + Self::new(Arc::new(data)) + } + fn new(parent: Arc) -> Result { + let aliaschild = match &parent.child { + ParentDataChild::AliasChild(value) => value.clone(), + _ => { + return Err(Error::InvalidChildError { + expected: stringify!(ParentDataChild::AliasChild), + actual: format!("{:?}", &parent.child), + }) + } + }; + let normalgrandchild1 = match &aliaschild.child { + AliasChildDataChild::NormalGrandChild1(value) => value.clone(), + _ => { + return Err(Error::InvalidChildError { + expected: stringify!(AliasChildDataChild::NormalGrandChild1), + actual: format!("{:?}", &aliaschild.child), + }) + } + }; + Ok(Self { parent, aliaschild, normalgrandchild1 }) + } + pub fn get_v(&self) -> Enum8 { + self.parent.as_ref().v + } + fn write_to(&self, buffer: &mut BytesMut) { + self.normalgrandchild1.write_to(buffer) + } + pub fn get_size(&self) -> usize { + self.parent.get_size() + } +} +impl NormalGrandChild1Builder { + pub fn build(self) -> NormalGrandChild1 { + let normalgrandchild1 = Arc::new(NormalGrandChild1Data {}); + let aliaschild = Arc::new(AliasChildData { + child: AliasChildDataChild::NormalGrandChild1(normalgrandchild1), + }); + let parent = + Arc::new(ParentData { v: Enum8::B, child: ParentDataChild::AliasChild(aliaschild) }); + NormalGrandChild1::new(parent).unwrap() + } +} +impl From for Parent { + fn from(builder: NormalGrandChild1Builder) -> Parent { + builder.build().into() + } +} +impl From for AliasChild { + fn from(builder: NormalGrandChild1Builder) -> AliasChild { + builder.build().into() + } +} +impl From for NormalGrandChild1 { + fn from(builder: NormalGrandChild1Builder) -> NormalGrandChild1 { + builder.build().into() + } +} + +#[derive(Debug, Clone, PartialEq, Eq)] +#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] +pub enum NormalGrandChild2DataChild { + Payload(Bytes), + None, +} +impl NormalGrandChild2DataChild { + fn get_total_size(&self) -> usize { + match self { + NormalGrandChild2DataChild::Payload(bytes) => bytes.len(), + NormalGrandChild2DataChild::None => 0, + } + } +} +#[derive(Debug, Clone, PartialEq, Eq)] +#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] +pub enum NormalGrandChild2Child { + Payload(Bytes), + None, +} +#[derive(Debug, Clone, PartialEq, Eq)] +#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] +pub struct NormalGrandChild2Data { + child: NormalGrandChild2DataChild, +} +#[derive(Debug, Clone, PartialEq, Eq)] +#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] +pub struct NormalGrandChild2 { + #[cfg_attr(feature = "serde", serde(flatten))] + parent: Arc, + #[cfg_attr(feature = "serde", serde(flatten))] + aliaschild: Arc, + #[cfg_attr(feature = "serde", serde(flatten))] + normalgrandchild2: Arc, +} +#[derive(Debug)] +#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] +pub struct NormalGrandChild2Builder { + pub payload: Option, +} +impl NormalGrandChild2Data { + fn conforms(bytes: &[u8]) -> bool { + true + } + fn parse(bytes: &[u8]) -> Result { + let mut cell = Cell::new(bytes); + let packet = Self::parse_inner(&mut cell)?; + Ok(packet) + } + fn parse_inner(mut bytes: &mut Cell<&[u8]>) -> Result { + let payload = bytes.get(); + bytes.get_mut().advance(payload.len()); + let child = match () { + _ if !payload.is_empty() => { + NormalGrandChild2DataChild::Payload(Bytes::copy_from_slice(payload)) + } + _ => NormalGrandChild2DataChild::None, + }; + Ok(Self { child }) + } + fn write_to(&self, buffer: &mut BytesMut) { + match &self.child { + NormalGrandChild2DataChild::Payload(payload) => buffer.put_slice(payload), + NormalGrandChild2DataChild::None => {} + } + } + fn get_total_size(&self) -> usize { + self.get_size() + } + fn get_size(&self) -> usize { + self.child.get_total_size() + } +} +impl Packet for NormalGrandChild2 { + fn to_bytes(self) -> Bytes { + let mut buffer = BytesMut::with_capacity(self.parent.get_size()); + self.parent.write_to(&mut buffer); + buffer.freeze() + } + fn to_vec(self) -> Vec { + self.to_bytes().to_vec() + } +} +impl From for Bytes { + fn from(packet: NormalGrandChild2) -> Self { + packet.to_bytes() + } +} +impl From for Vec { + fn from(packet: NormalGrandChild2) -> Self { + packet.to_vec() + } +} +impl From for Parent { + fn from(packet: NormalGrandChild2) -> Parent { + Parent::new(packet.parent).unwrap() + } +} +impl From for AliasChild { + fn from(packet: NormalGrandChild2) -> AliasChild { + AliasChild::new(packet.parent).unwrap() + } +} +impl TryFrom for NormalGrandChild2 { + type Error = Error; + fn try_from(packet: Parent) -> Result { + NormalGrandChild2::new(packet.parent) + } +} +impl NormalGrandChild2 { + pub fn parse(bytes: &[u8]) -> Result { + let mut cell = Cell::new(bytes); + let packet = Self::parse_inner(&mut cell)?; + Ok(packet) + } + fn parse_inner(mut bytes: &mut Cell<&[u8]>) -> Result { + let data = ParentData::parse_inner(&mut bytes)?; + Self::new(Arc::new(data)) + } + pub fn specialize(&self) -> NormalGrandChild2Child { + match &self.normalgrandchild2.child { + NormalGrandChild2DataChild::Payload(payload) => { + NormalGrandChild2Child::Payload(payload.clone()) + } + NormalGrandChild2DataChild::None => NormalGrandChild2Child::None, + } + } + fn new(parent: Arc) -> Result { + let aliaschild = match &parent.child { + ParentDataChild::AliasChild(value) => value.clone(), + _ => { + return Err(Error::InvalidChildError { + expected: stringify!(ParentDataChild::AliasChild), + actual: format!("{:?}", &parent.child), + }) + } + }; + let normalgrandchild2 = match &aliaschild.child { + AliasChildDataChild::NormalGrandChild2(value) => value.clone(), + _ => { + return Err(Error::InvalidChildError { + expected: stringify!(AliasChildDataChild::NormalGrandChild2), + actual: format!("{:?}", &aliaschild.child), + }) + } + }; + Ok(Self { parent, aliaschild, normalgrandchild2 }) + } + pub fn get_v(&self) -> Enum8 { + self.parent.as_ref().v + } + pub fn get_payload(&self) -> &[u8] { + match &self.normalgrandchild2.child { + NormalGrandChild2DataChild::Payload(bytes) => &bytes, + NormalGrandChild2DataChild::None => &[], + } + } + fn write_to(&self, buffer: &mut BytesMut) { + self.normalgrandchild2.write_to(buffer) + } + pub fn get_size(&self) -> usize { + self.parent.get_size() + } +} +impl NormalGrandChild2Builder { + pub fn build(self) -> NormalGrandChild2 { + let normalgrandchild2 = Arc::new(NormalGrandChild2Data { + child: match self.payload { + None => NormalGrandChild2DataChild::None, + Some(bytes) => NormalGrandChild2DataChild::Payload(bytes), + }, + }); + let aliaschild = Arc::new(AliasChildData { + child: AliasChildDataChild::NormalGrandChild2(normalgrandchild2), + }); + let parent = + Arc::new(ParentData { v: Enum8::C, child: ParentDataChild::AliasChild(aliaschild) }); + NormalGrandChild2::new(parent).unwrap() + } +} +impl From for Parent { + fn from(builder: NormalGrandChild2Builder) -> Parent { + builder.build().into() + } +} +impl From for AliasChild { + fn from(builder: NormalGrandChild2Builder) -> AliasChild { + builder.build().into() + } +} +impl From for NormalGrandChild2 { + fn from(builder: NormalGrandChild2Builder) -> NormalGrandChild2 { + builder.build().into() + } +} diff --git a/tools/pdl/tests/generated/packet_decl_parent_with_alias_child_little_endian.rs b/tools/pdl/tests/generated/packet_decl_parent_with_alias_child_little_endian.rs new file mode 100644 index 00000000000..2488871665f --- /dev/null +++ b/tools/pdl/tests/generated/packet_decl_parent_with_alias_child_little_endian.rs @@ -0,0 +1,930 @@ +// @generated rust packets from test + +use bytes::{Buf, BufMut, Bytes, BytesMut}; +use std::cell::Cell; +use std::convert::{TryFrom, TryInto}; +use std::fmt; +use std::sync::Arc; +use thiserror::Error; + +type Result = std::result::Result; + +#[doc = r" Private prevents users from creating arbitrary scalar values"] +#[doc = r" in situations where the value needs to be validated."] +#[doc = r" Users can freely deref the value, but only the backend"] +#[doc = r" may create it."] +#[derive(Debug, Clone, Copy, Hash, PartialEq, Eq, PartialOrd, Ord)] +pub struct Private(T); +impl std::ops::Deref for Private { + type Target = T; + fn deref(&self) -> &Self::Target { + &self.0 + } +} + +#[derive(Debug, Error)] +pub enum Error { + #[error("Packet parsing failed")] + InvalidPacketError, + #[error("{field} was {value:x}, which is not known")] + ConstraintOutOfBounds { field: String, value: u64 }, + #[error("Got {actual:x}, expected {expected:x}")] + InvalidFixedValue { expected: u64, actual: u64 }, + #[error("when parsing {obj} needed length of {wanted} but got {got}")] + InvalidLengthError { obj: String, wanted: usize, got: usize }, + #[error("array size ({array} bytes) is not a multiple of the element size ({element} bytes)")] + InvalidArraySize { array: usize, element: usize }, + #[error("Due to size restrictions a struct could not be parsed.")] + ImpossibleStructError, + #[error("when parsing field {obj}.{field}, {value} is not a valid {type_} value")] + InvalidEnumValueError { obj: String, field: String, value: u64, type_: String }, + #[error("expected child {expected}, got {actual}")] + InvalidChildError { expected: &'static str, actual: String }, +} + +pub trait Packet { + fn to_bytes(self) -> Bytes; + fn to_vec(self) -> Vec; +} + +#[repr(u64)] +#[derive(Debug, Clone, Copy, Hash, Eq, PartialEq)] +#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] +#[cfg_attr(feature = "serde", serde(try_from = "u8", into = "u8"))] +pub enum Enum8 { + A = 0x0, + B = 0x1, + C = 0x2, +} +impl TryFrom for Enum8 { + type Error = u8; + fn try_from(value: u8) -> std::result::Result { + match value { + 0x0 => Ok(Enum8::A), + 0x1 => Ok(Enum8::B), + 0x2 => Ok(Enum8::C), + _ => Err(value), + } + } +} +impl From<&Enum8> for u8 { + fn from(value: &Enum8) -> Self { + match value { + Enum8::A => 0x0, + Enum8::B => 0x1, + Enum8::C => 0x2, + } + } +} +impl From for u8 { + fn from(value: Enum8) -> Self { + (&value).into() + } +} +impl From for i16 { + fn from(value: Enum8) -> Self { + u8::from(value) as Self + } +} +impl From for i32 { + fn from(value: Enum8) -> Self { + u8::from(value) as Self + } +} +impl From for i64 { + fn from(value: Enum8) -> Self { + u8::from(value) as Self + } +} +impl From for u16 { + fn from(value: Enum8) -> Self { + u8::from(value) as Self + } +} +impl From for u32 { + fn from(value: Enum8) -> Self { + u8::from(value) as Self + } +} +impl From for u64 { + fn from(value: Enum8) -> Self { + u8::from(value) as Self + } +} + +#[derive(Debug, Clone, PartialEq, Eq)] +#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] +pub enum ParentDataChild { + AliasChild(Arc), + NormalChild(Arc), + Payload(Bytes), + None, +} +impl ParentDataChild { + fn get_total_size(&self) -> usize { + match self { + ParentDataChild::AliasChild(value) => value.get_total_size(), + ParentDataChild::NormalChild(value) => value.get_total_size(), + ParentDataChild::Payload(bytes) => bytes.len(), + ParentDataChild::None => 0, + } + } +} +#[derive(Debug, Clone, PartialEq, Eq)] +#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] +pub enum ParentChild { + AliasChild(AliasChild), + NormalChild(NormalChild), + Payload(Bytes), + None, +} +#[derive(Debug, Clone, PartialEq, Eq)] +#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] +pub struct ParentData { + v: Enum8, + child: ParentDataChild, +} +#[derive(Debug, Clone, PartialEq, Eq)] +#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] +pub struct Parent { + #[cfg_attr(feature = "serde", serde(flatten))] + parent: Arc, +} +#[derive(Debug)] +#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] +pub struct ParentBuilder { + pub v: Enum8, + pub payload: Option, +} +impl ParentData { + fn conforms(bytes: &[u8]) -> bool { + bytes.len() >= 1 + } + fn parse(bytes: &[u8]) -> Result { + let mut cell = Cell::new(bytes); + let packet = Self::parse_inner(&mut cell)?; + Ok(packet) + } + fn parse_inner(mut bytes: &mut Cell<&[u8]>) -> Result { + if bytes.get().remaining() < 1 { + return Err(Error::InvalidLengthError { + obj: "Parent".to_string(), + wanted: 1, + got: bytes.get().remaining(), + }); + } + let v = Enum8::try_from(bytes.get_mut().get_u8()).map_err(|_| { + Error::InvalidEnumValueError { + obj: "Parent".to_string(), + field: "v".to_string(), + value: bytes.get_mut().get_u8() as u64, + type_: "Enum8".to_string(), + } + })?; + let payload = bytes.get(); + bytes.get_mut().advance(payload.len()); + let child = match (v) { + (Enum8::B | Enum8::C) if AliasChildData::conforms(&payload) => { + let mut cell = Cell::new(payload); + let child_data = AliasChildData::parse_inner(&mut cell, v)?; + ParentDataChild::AliasChild(Arc::new(child_data)) + } + (Enum8::A) if NormalChildData::conforms(&payload) => { + let mut cell = Cell::new(payload); + let child_data = NormalChildData::parse_inner(&mut cell)?; + ParentDataChild::NormalChild(Arc::new(child_data)) + } + _ if !payload.is_empty() => ParentDataChild::Payload(Bytes::copy_from_slice(payload)), + _ => ParentDataChild::None, + }; + Ok(Self { v, child }) + } + fn write_to(&self, buffer: &mut BytesMut) { + buffer.put_u8(u8::from(self.v)); + match &self.child { + ParentDataChild::AliasChild(child) => child.write_to(buffer), + ParentDataChild::NormalChild(child) => child.write_to(buffer), + ParentDataChild::Payload(payload) => buffer.put_slice(payload), + ParentDataChild::None => {} + } + } + fn get_total_size(&self) -> usize { + self.get_size() + } + fn get_size(&self) -> usize { + 1 + self.child.get_total_size() + } +} +impl Packet for Parent { + fn to_bytes(self) -> Bytes { + let mut buffer = BytesMut::with_capacity(self.parent.get_size()); + self.parent.write_to(&mut buffer); + buffer.freeze() + } + fn to_vec(self) -> Vec { + self.to_bytes().to_vec() + } +} +impl From for Bytes { + fn from(packet: Parent) -> Self { + packet.to_bytes() + } +} +impl From for Vec { + fn from(packet: Parent) -> Self { + packet.to_vec() + } +} +impl Parent { + pub fn parse(bytes: &[u8]) -> Result { + let mut cell = Cell::new(bytes); + let packet = Self::parse_inner(&mut cell)?; + Ok(packet) + } + fn parse_inner(mut bytes: &mut Cell<&[u8]>) -> Result { + let data = ParentData::parse_inner(&mut bytes)?; + Self::new(Arc::new(data)) + } + pub fn specialize(&self) -> ParentChild { + match &self.parent.child { + ParentDataChild::AliasChild(_) => { + ParentChild::AliasChild(AliasChild::new(self.parent.clone()).unwrap()) + } + ParentDataChild::NormalChild(_) => { + ParentChild::NormalChild(NormalChild::new(self.parent.clone()).unwrap()) + } + ParentDataChild::Payload(payload) => ParentChild::Payload(payload.clone()), + ParentDataChild::None => ParentChild::None, + } + } + fn new(parent: Arc) -> Result { + Ok(Self { parent }) + } + pub fn get_v(&self) -> Enum8 { + self.parent.as_ref().v + } + fn write_to(&self, buffer: &mut BytesMut) { + self.parent.write_to(buffer) + } + pub fn get_size(&self) -> usize { + self.parent.get_size() + } +} +impl ParentBuilder { + pub fn build(self) -> Parent { + let parent = Arc::new(ParentData { + v: self.v, + child: match self.payload { + None => ParentDataChild::None, + Some(bytes) => ParentDataChild::Payload(bytes), + }, + }); + Parent::new(parent).unwrap() + } +} +impl From for Parent { + fn from(builder: ParentBuilder) -> Parent { + builder.build().into() + } +} + +#[derive(Debug, Clone, PartialEq, Eq)] +#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] +pub enum AliasChildDataChild { + NormalGrandChild1(Arc), + NormalGrandChild2(Arc), + Payload(Bytes), + None, +} +impl AliasChildDataChild { + fn get_total_size(&self) -> usize { + match self { + AliasChildDataChild::NormalGrandChild1(value) => value.get_total_size(), + AliasChildDataChild::NormalGrandChild2(value) => value.get_total_size(), + AliasChildDataChild::Payload(bytes) => bytes.len(), + AliasChildDataChild::None => 0, + } + } +} +#[derive(Debug, Clone, PartialEq, Eq)] +#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] +pub enum AliasChildChild { + NormalGrandChild1(NormalGrandChild1), + NormalGrandChild2(NormalGrandChild2), + Payload(Bytes), + None, +} +#[derive(Debug, Clone, PartialEq, Eq)] +#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] +pub struct AliasChildData { + child: AliasChildDataChild, +} +#[derive(Debug, Clone, PartialEq, Eq)] +#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] +pub struct AliasChild { + #[cfg_attr(feature = "serde", serde(flatten))] + parent: Arc, + #[cfg_attr(feature = "serde", serde(flatten))] + aliaschild: Arc, +} +#[derive(Debug)] +#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] +pub struct AliasChildBuilder { + pub v: Enum8, + pub payload: Option, +} +impl AliasChildData { + fn conforms(bytes: &[u8]) -> bool { + true + } + fn parse(bytes: &[u8], v: Enum8) -> Result { + let mut cell = Cell::new(bytes); + let packet = Self::parse_inner(&mut cell, v)?; + Ok(packet) + } + fn parse_inner(mut bytes: &mut Cell<&[u8]>, v: Enum8) -> Result { + let payload = bytes.get(); + bytes.get_mut().advance(payload.len()); + let child = match (v) { + (Enum8::B) if NormalGrandChild1Data::conforms(&payload) => { + let mut cell = Cell::new(payload); + let child_data = NormalGrandChild1Data::parse_inner(&mut cell)?; + AliasChildDataChild::NormalGrandChild1(Arc::new(child_data)) + } + (Enum8::C) if NormalGrandChild2Data::conforms(&payload) => { + let mut cell = Cell::new(payload); + let child_data = NormalGrandChild2Data::parse_inner(&mut cell)?; + AliasChildDataChild::NormalGrandChild2(Arc::new(child_data)) + } + _ if !payload.is_empty() => { + AliasChildDataChild::Payload(Bytes::copy_from_slice(payload)) + } + _ => AliasChildDataChild::None, + }; + Ok(Self { child }) + } + fn write_to(&self, buffer: &mut BytesMut) { + match &self.child { + AliasChildDataChild::NormalGrandChild1(child) => child.write_to(buffer), + AliasChildDataChild::NormalGrandChild2(child) => child.write_to(buffer), + AliasChildDataChild::Payload(payload) => buffer.put_slice(payload), + AliasChildDataChild::None => {} + } + } + fn get_total_size(&self) -> usize { + self.get_size() + } + fn get_size(&self) -> usize { + self.child.get_total_size() + } +} +impl Packet for AliasChild { + fn to_bytes(self) -> Bytes { + let mut buffer = BytesMut::with_capacity(self.parent.get_size()); + self.parent.write_to(&mut buffer); + buffer.freeze() + } + fn to_vec(self) -> Vec { + self.to_bytes().to_vec() + } +} +impl From for Bytes { + fn from(packet: AliasChild) -> Self { + packet.to_bytes() + } +} +impl From for Vec { + fn from(packet: AliasChild) -> Self { + packet.to_vec() + } +} +impl From for Parent { + fn from(packet: AliasChild) -> Parent { + Parent::new(packet.parent).unwrap() + } +} +impl TryFrom for AliasChild { + type Error = Error; + fn try_from(packet: Parent) -> Result { + AliasChild::new(packet.parent) + } +} +impl AliasChild { + pub fn parse(bytes: &[u8]) -> Result { + let mut cell = Cell::new(bytes); + let packet = Self::parse_inner(&mut cell)?; + Ok(packet) + } + fn parse_inner(mut bytes: &mut Cell<&[u8]>) -> Result { + let data = ParentData::parse_inner(&mut bytes)?; + Self::new(Arc::new(data)) + } + pub fn specialize(&self) -> AliasChildChild { + match &self.aliaschild.child { + AliasChildDataChild::NormalGrandChild1(_) => AliasChildChild::NormalGrandChild1( + NormalGrandChild1::new(self.parent.clone()).unwrap(), + ), + AliasChildDataChild::NormalGrandChild2(_) => AliasChildChild::NormalGrandChild2( + NormalGrandChild2::new(self.parent.clone()).unwrap(), + ), + AliasChildDataChild::Payload(payload) => AliasChildChild::Payload(payload.clone()), + AliasChildDataChild::None => AliasChildChild::None, + } + } + fn new(parent: Arc) -> Result { + let aliaschild = match &parent.child { + ParentDataChild::AliasChild(value) => value.clone(), + _ => { + return Err(Error::InvalidChildError { + expected: stringify!(ParentDataChild::AliasChild), + actual: format!("{:?}", &parent.child), + }) + } + }; + Ok(Self { parent, aliaschild }) + } + pub fn get_v(&self) -> Enum8 { + self.parent.as_ref().v + } + fn write_to(&self, buffer: &mut BytesMut) { + self.aliaschild.write_to(buffer) + } + pub fn get_size(&self) -> usize { + self.parent.get_size() + } +} +impl AliasChildBuilder { + pub fn build(self) -> AliasChild { + let aliaschild = Arc::new(AliasChildData { + child: match self.payload { + None => AliasChildDataChild::None, + Some(bytes) => AliasChildDataChild::Payload(bytes), + }, + }); + let parent = + Arc::new(ParentData { v: self.v, child: ParentDataChild::AliasChild(aliaschild) }); + AliasChild::new(parent).unwrap() + } +} +impl From for Parent { + fn from(builder: AliasChildBuilder) -> Parent { + builder.build().into() + } +} +impl From for AliasChild { + fn from(builder: AliasChildBuilder) -> AliasChild { + builder.build().into() + } +} + +#[derive(Debug, Clone, PartialEq, Eq)] +#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] +pub struct NormalChildData {} +#[derive(Debug, Clone, PartialEq, Eq)] +#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] +pub struct NormalChild { + #[cfg_attr(feature = "serde", serde(flatten))] + parent: Arc, + #[cfg_attr(feature = "serde", serde(flatten))] + normalchild: Arc, +} +#[derive(Debug)] +#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] +pub struct NormalChildBuilder {} +impl NormalChildData { + fn conforms(bytes: &[u8]) -> bool { + true + } + fn parse(bytes: &[u8]) -> Result { + let mut cell = Cell::new(bytes); + let packet = Self::parse_inner(&mut cell)?; + Ok(packet) + } + fn parse_inner(mut bytes: &mut Cell<&[u8]>) -> Result { + Ok(Self {}) + } + fn write_to(&self, buffer: &mut BytesMut) {} + fn get_total_size(&self) -> usize { + self.get_size() + } + fn get_size(&self) -> usize { + 0 + } +} +impl Packet for NormalChild { + fn to_bytes(self) -> Bytes { + let mut buffer = BytesMut::with_capacity(self.parent.get_size()); + self.parent.write_to(&mut buffer); + buffer.freeze() + } + fn to_vec(self) -> Vec { + self.to_bytes().to_vec() + } +} +impl From for Bytes { + fn from(packet: NormalChild) -> Self { + packet.to_bytes() + } +} +impl From for Vec { + fn from(packet: NormalChild) -> Self { + packet.to_vec() + } +} +impl From for Parent { + fn from(packet: NormalChild) -> Parent { + Parent::new(packet.parent).unwrap() + } +} +impl TryFrom for NormalChild { + type Error = Error; + fn try_from(packet: Parent) -> Result { + NormalChild::new(packet.parent) + } +} +impl NormalChild { + pub fn parse(bytes: &[u8]) -> Result { + let mut cell = Cell::new(bytes); + let packet = Self::parse_inner(&mut cell)?; + Ok(packet) + } + fn parse_inner(mut bytes: &mut Cell<&[u8]>) -> Result { + let data = ParentData::parse_inner(&mut bytes)?; + Self::new(Arc::new(data)) + } + fn new(parent: Arc) -> Result { + let normalchild = match &parent.child { + ParentDataChild::NormalChild(value) => value.clone(), + _ => { + return Err(Error::InvalidChildError { + expected: stringify!(ParentDataChild::NormalChild), + actual: format!("{:?}", &parent.child), + }) + } + }; + Ok(Self { parent, normalchild }) + } + pub fn get_v(&self) -> Enum8 { + self.parent.as_ref().v + } + fn write_to(&self, buffer: &mut BytesMut) { + self.normalchild.write_to(buffer) + } + pub fn get_size(&self) -> usize { + self.parent.get_size() + } +} +impl NormalChildBuilder { + pub fn build(self) -> NormalChild { + let normalchild = Arc::new(NormalChildData {}); + let parent = + Arc::new(ParentData { v: Enum8::A, child: ParentDataChild::NormalChild(normalchild) }); + NormalChild::new(parent).unwrap() + } +} +impl From for Parent { + fn from(builder: NormalChildBuilder) -> Parent { + builder.build().into() + } +} +impl From for NormalChild { + fn from(builder: NormalChildBuilder) -> NormalChild { + builder.build().into() + } +} + +#[derive(Debug, Clone, PartialEq, Eq)] +#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] +pub struct NormalGrandChild1Data {} +#[derive(Debug, Clone, PartialEq, Eq)] +#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] +pub struct NormalGrandChild1 { + #[cfg_attr(feature = "serde", serde(flatten))] + parent: Arc, + #[cfg_attr(feature = "serde", serde(flatten))] + aliaschild: Arc, + #[cfg_attr(feature = "serde", serde(flatten))] + normalgrandchild1: Arc, +} +#[derive(Debug)] +#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] +pub struct NormalGrandChild1Builder {} +impl NormalGrandChild1Data { + fn conforms(bytes: &[u8]) -> bool { + true + } + fn parse(bytes: &[u8]) -> Result { + let mut cell = Cell::new(bytes); + let packet = Self::parse_inner(&mut cell)?; + Ok(packet) + } + fn parse_inner(mut bytes: &mut Cell<&[u8]>) -> Result { + Ok(Self {}) + } + fn write_to(&self, buffer: &mut BytesMut) {} + fn get_total_size(&self) -> usize { + self.get_size() + } + fn get_size(&self) -> usize { + 0 + } +} +impl Packet for NormalGrandChild1 { + fn to_bytes(self) -> Bytes { + let mut buffer = BytesMut::with_capacity(self.parent.get_size()); + self.parent.write_to(&mut buffer); + buffer.freeze() + } + fn to_vec(self) -> Vec { + self.to_bytes().to_vec() + } +} +impl From for Bytes { + fn from(packet: NormalGrandChild1) -> Self { + packet.to_bytes() + } +} +impl From for Vec { + fn from(packet: NormalGrandChild1) -> Self { + packet.to_vec() + } +} +impl From for Parent { + fn from(packet: NormalGrandChild1) -> Parent { + Parent::new(packet.parent).unwrap() + } +} +impl From for AliasChild { + fn from(packet: NormalGrandChild1) -> AliasChild { + AliasChild::new(packet.parent).unwrap() + } +} +impl TryFrom for NormalGrandChild1 { + type Error = Error; + fn try_from(packet: Parent) -> Result { + NormalGrandChild1::new(packet.parent) + } +} +impl NormalGrandChild1 { + pub fn parse(bytes: &[u8]) -> Result { + let mut cell = Cell::new(bytes); + let packet = Self::parse_inner(&mut cell)?; + Ok(packet) + } + fn parse_inner(mut bytes: &mut Cell<&[u8]>) -> Result { + let data = ParentData::parse_inner(&mut bytes)?; + Self::new(Arc::new(data)) + } + fn new(parent: Arc) -> Result { + let aliaschild = match &parent.child { + ParentDataChild::AliasChild(value) => value.clone(), + _ => { + return Err(Error::InvalidChildError { + expected: stringify!(ParentDataChild::AliasChild), + actual: format!("{:?}", &parent.child), + }) + } + }; + let normalgrandchild1 = match &aliaschild.child { + AliasChildDataChild::NormalGrandChild1(value) => value.clone(), + _ => { + return Err(Error::InvalidChildError { + expected: stringify!(AliasChildDataChild::NormalGrandChild1), + actual: format!("{:?}", &aliaschild.child), + }) + } + }; + Ok(Self { parent, aliaschild, normalgrandchild1 }) + } + pub fn get_v(&self) -> Enum8 { + self.parent.as_ref().v + } + fn write_to(&self, buffer: &mut BytesMut) { + self.normalgrandchild1.write_to(buffer) + } + pub fn get_size(&self) -> usize { + self.parent.get_size() + } +} +impl NormalGrandChild1Builder { + pub fn build(self) -> NormalGrandChild1 { + let normalgrandchild1 = Arc::new(NormalGrandChild1Data {}); + let aliaschild = Arc::new(AliasChildData { + child: AliasChildDataChild::NormalGrandChild1(normalgrandchild1), + }); + let parent = + Arc::new(ParentData { v: Enum8::B, child: ParentDataChild::AliasChild(aliaschild) }); + NormalGrandChild1::new(parent).unwrap() + } +} +impl From for Parent { + fn from(builder: NormalGrandChild1Builder) -> Parent { + builder.build().into() + } +} +impl From for AliasChild { + fn from(builder: NormalGrandChild1Builder) -> AliasChild { + builder.build().into() + } +} +impl From for NormalGrandChild1 { + fn from(builder: NormalGrandChild1Builder) -> NormalGrandChild1 { + builder.build().into() + } +} + +#[derive(Debug, Clone, PartialEq, Eq)] +#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] +pub enum NormalGrandChild2DataChild { + Payload(Bytes), + None, +} +impl NormalGrandChild2DataChild { + fn get_total_size(&self) -> usize { + match self { + NormalGrandChild2DataChild::Payload(bytes) => bytes.len(), + NormalGrandChild2DataChild::None => 0, + } + } +} +#[derive(Debug, Clone, PartialEq, Eq)] +#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] +pub enum NormalGrandChild2Child { + Payload(Bytes), + None, +} +#[derive(Debug, Clone, PartialEq, Eq)] +#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] +pub struct NormalGrandChild2Data { + child: NormalGrandChild2DataChild, +} +#[derive(Debug, Clone, PartialEq, Eq)] +#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] +pub struct NormalGrandChild2 { + #[cfg_attr(feature = "serde", serde(flatten))] + parent: Arc, + #[cfg_attr(feature = "serde", serde(flatten))] + aliaschild: Arc, + #[cfg_attr(feature = "serde", serde(flatten))] + normalgrandchild2: Arc, +} +#[derive(Debug)] +#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] +pub struct NormalGrandChild2Builder { + pub payload: Option, +} +impl NormalGrandChild2Data { + fn conforms(bytes: &[u8]) -> bool { + true + } + fn parse(bytes: &[u8]) -> Result { + let mut cell = Cell::new(bytes); + let packet = Self::parse_inner(&mut cell)?; + Ok(packet) + } + fn parse_inner(mut bytes: &mut Cell<&[u8]>) -> Result { + let payload = bytes.get(); + bytes.get_mut().advance(payload.len()); + let child = match () { + _ if !payload.is_empty() => { + NormalGrandChild2DataChild::Payload(Bytes::copy_from_slice(payload)) + } + _ => NormalGrandChild2DataChild::None, + }; + Ok(Self { child }) + } + fn write_to(&self, buffer: &mut BytesMut) { + match &self.child { + NormalGrandChild2DataChild::Payload(payload) => buffer.put_slice(payload), + NormalGrandChild2DataChild::None => {} + } + } + fn get_total_size(&self) -> usize { + self.get_size() + } + fn get_size(&self) -> usize { + self.child.get_total_size() + } +} +impl Packet for NormalGrandChild2 { + fn to_bytes(self) -> Bytes { + let mut buffer = BytesMut::with_capacity(self.parent.get_size()); + self.parent.write_to(&mut buffer); + buffer.freeze() + } + fn to_vec(self) -> Vec { + self.to_bytes().to_vec() + } +} +impl From for Bytes { + fn from(packet: NormalGrandChild2) -> Self { + packet.to_bytes() + } +} +impl From for Vec { + fn from(packet: NormalGrandChild2) -> Self { + packet.to_vec() + } +} +impl From for Parent { + fn from(packet: NormalGrandChild2) -> Parent { + Parent::new(packet.parent).unwrap() + } +} +impl From for AliasChild { + fn from(packet: NormalGrandChild2) -> AliasChild { + AliasChild::new(packet.parent).unwrap() + } +} +impl TryFrom for NormalGrandChild2 { + type Error = Error; + fn try_from(packet: Parent) -> Result { + NormalGrandChild2::new(packet.parent) + } +} +impl NormalGrandChild2 { + pub fn parse(bytes: &[u8]) -> Result { + let mut cell = Cell::new(bytes); + let packet = Self::parse_inner(&mut cell)?; + Ok(packet) + } + fn parse_inner(mut bytes: &mut Cell<&[u8]>) -> Result { + let data = ParentData::parse_inner(&mut bytes)?; + Self::new(Arc::new(data)) + } + pub fn specialize(&self) -> NormalGrandChild2Child { + match &self.normalgrandchild2.child { + NormalGrandChild2DataChild::Payload(payload) => { + NormalGrandChild2Child::Payload(payload.clone()) + } + NormalGrandChild2DataChild::None => NormalGrandChild2Child::None, + } + } + fn new(parent: Arc) -> Result { + let aliaschild = match &parent.child { + ParentDataChild::AliasChild(value) => value.clone(), + _ => { + return Err(Error::InvalidChildError { + expected: stringify!(ParentDataChild::AliasChild), + actual: format!("{:?}", &parent.child), + }) + } + }; + let normalgrandchild2 = match &aliaschild.child { + AliasChildDataChild::NormalGrandChild2(value) => value.clone(), + _ => { + return Err(Error::InvalidChildError { + expected: stringify!(AliasChildDataChild::NormalGrandChild2), + actual: format!("{:?}", &aliaschild.child), + }) + } + }; + Ok(Self { parent, aliaschild, normalgrandchild2 }) + } + pub fn get_v(&self) -> Enum8 { + self.parent.as_ref().v + } + pub fn get_payload(&self) -> &[u8] { + match &self.normalgrandchild2.child { + NormalGrandChild2DataChild::Payload(bytes) => &bytes, + NormalGrandChild2DataChild::None => &[], + } + } + fn write_to(&self, buffer: &mut BytesMut) { + self.normalgrandchild2.write_to(buffer) + } + pub fn get_size(&self) -> usize { + self.parent.get_size() + } +} +impl NormalGrandChild2Builder { + pub fn build(self) -> NormalGrandChild2 { + let normalgrandchild2 = Arc::new(NormalGrandChild2Data { + child: match self.payload { + None => NormalGrandChild2DataChild::None, + Some(bytes) => NormalGrandChild2DataChild::Payload(bytes), + }, + }); + let aliaschild = Arc::new(AliasChildData { + child: AliasChildDataChild::NormalGrandChild2(normalgrandchild2), + }); + let parent = + Arc::new(ParentData { v: Enum8::C, child: ParentDataChild::AliasChild(aliaschild) }); + NormalGrandChild2::new(parent).unwrap() + } +} +impl From for Parent { + fn from(builder: NormalGrandChild2Builder) -> Parent { + builder.build().into() + } +} +impl From for AliasChild { + fn from(builder: NormalGrandChild2Builder) -> AliasChild { + builder.build().into() + } +} +impl From for NormalGrandChild2 { + fn from(builder: NormalGrandChild2Builder) -> NormalGrandChild2 { + builder.build().into() + } +} -- GitLab From f18476d5fd4fccec2a0330780870f4ca13d632f2 Mon Sep 17 00:00:00 2001 From: Henri Chataing Date: Tue, 16 May 2023 01:31:25 +0000 Subject: [PATCH 0112/2405] RootCanal: Migrate packets::hci to the new PDL generator Bug: 279494407 Test: None Change-Id: I44c205373ae3372e50a697f3223ce28dd32096ae --- tools/rootcanal/Android.bp | 13 +-- tools/rootcanal/rust/CMakeLists.txt | 9 +- tools/rootcanal/rust/build.rs | 37 ++++---- tools/rootcanal/rust/src/either.rs | 2 +- tools/rootcanal/rust/src/ffi.rs | 25 +++--- tools/rootcanal/rust/src/lmp/manager.rs | 16 ++-- .../rust/src/lmp/procedure/authentication.rs | 21 +++-- .../rust/src/lmp/procedure/encryption.rs | 2 +- .../rust/src/lmp/procedure/features.rs | 6 +- .../rust/src/lmp/procedure/legacy_pairing.rs | 4 +- tools/rootcanal/rust/src/lmp/procedure/mod.rs | 6 +- .../lmp/procedure/secure_simple_pairing.rs | 59 ++++++------- tools/rootcanal/rust/src/lmp/test/context.rs | 20 ++--- tools/rootcanal/rust/src/lmp/test/sequence.rs | 2 +- tools/rootcanal/rust/src/packets.rs | 84 +++++-------------- tools/rootcanal/rust/test/SP/BV-16-C.in | 2 +- tools/rootcanal/rust/test/SP/BV-17-C.in | 2 +- tools/rootcanal/rust/test/SP/BV-30-C.in | 2 +- tools/rootcanal/rust/test/SP/BV-32-C.in | 2 +- tools/rootcanal/rust/test/SP/BV-35-C.in | 2 +- tools/rootcanal/rust/test/SP/BV-36-C.in | 2 +- 21 files changed, 131 insertions(+), 187 deletions(-) diff --git a/tools/rootcanal/Android.bp b/tools/rootcanal/Android.bp index b9a012726ff..59ff7991751 100644 --- a/tools/rootcanal/Android.bp +++ b/tools/rootcanal/Android.bp @@ -436,16 +436,9 @@ genrule { genrule { name: "rootcanal_hci_packets_rust_gen", - tools: [ - "bluetooth_packetgen", - ], - cmd: "$(location bluetooth_packetgen) --include=packages/modules/Bluetooth/tools/rootcanal/packets --out=$(genDir) $(in) --rust", - srcs: [ - "packets/hci/hci_packets.pdl", - ], - out: [ - "hci/hci_packets.rs", - ], + defaults: ["pdl_rust_generator_defaults"], + srcs: ["packets/hci/hci_packets.pdl"], + out: ["hci_packets.rs"], } // bt_vhci_forwarder in cuttlefish depends on this H4Packetizer implementation. diff --git a/tools/rootcanal/rust/CMakeLists.txt b/tools/rootcanal/rust/CMakeLists.txt index e3b478194bc..55273a98907 100644 --- a/tools/rootcanal/rust/CMakeLists.txt +++ b/tools/rootcanal/rust/CMakeLists.txt @@ -1,9 +1,10 @@ message(STATUS "Enabling bluetooth LMP module.") -# TODO(b/279494407): migrate hci packets to new generator -android_bluetooth_packet_gen( - GENERATED hci_packets_rs INCLUDES packets SRC hci/hci_packets.pdl - SOURCE_DIR ${ROOTCANAL_ROOT} LANG rust) +pdl_gen( + NAME hci_packets_rs + INPUT ${ROOTCANAL_ROOT}/packets/hci/hci_packets.pdl + OUTPUT hci_packets.rs + LANG rust) pdl_gen( NAME lmp_packets_rs diff --git a/tools/rootcanal/rust/build.rs b/tools/rootcanal/rust/build.rs index 086639681a6..04ef70626a6 100644 --- a/tools/rootcanal/rust/build.rs +++ b/tools/rootcanal/rust/build.rs @@ -14,8 +14,9 @@ // limitations under the License. use std::env; +use std::fs::File; use std::path::{Path, PathBuf}; -use std::process::Command; +use std::process::{Command, Stdio}; fn main() { install_generated_module( @@ -48,35 +49,33 @@ fn install_generated_module(module_name: &str, prebuilt_var: &str, pdl_name: &Pa } } -fn generate_module(pdl_name: &PathBuf) { +fn generate_module(in_file: &PathBuf) { let out_dir = PathBuf::from(env::var("OUT_DIR").unwrap()); + let out_file = + File::create(out_dir.join(in_file.file_name().unwrap()).with_extension("rs")).unwrap(); - // Find the packetgen tool. Expecting it at CARGO_HOME/bin - let packetgen = match env::var("CARGO_HOME") { - Ok(dir) => PathBuf::from(dir).join("bin").join("bluetooth_packetgen"), - Err(_) => PathBuf::from("bluetooth_packetgen"), + // Find the pdl tool. Expecting it at CARGO_HOME/bin + let pdl = match env::var("CARGO_HOME") { + Ok(dir) => PathBuf::from(dir).join("bin").join("pdl"), + Err(_) => PathBuf::from("pdl"), }; - if !Path::new(packetgen.as_os_str()).exists() { - panic!( - "bluetooth_packetgen not found in the current environment: {:?}", - packetgen.as_os_str().to_str().unwrap() - ); + if !Path::new(pdl.as_os_str()).exists() { + panic!("pdl not found in the current environment: {:?}", pdl.as_os_str().to_str().unwrap()); } - println!("cargo:rerun-if-changed={}", pdl_name.display()); - let output = Command::new(packetgen.as_os_str().to_str().unwrap()) - .arg("--out=".to_owned() + out_dir.as_os_str().to_str().unwrap()) - .arg("--include=".to_owned() + pdl_name.parent().unwrap().as_os_str().to_str().unwrap()) - .arg("--rust") - .arg(pdl_name) + println!("cargo:rerun-if-changed={}", in_file.display()); + let output = Command::new(pdl.as_os_str().to_str().unwrap()) + .arg("--output-format") + .arg("rust") + .arg(in_file) + .stdout(Stdio::from(out_file)) .output() .unwrap(); println!( - "Status: {}, stdout: {}, stderr: {}", + "Status: {}, stderr: {}", output.status, - String::from_utf8_lossy(output.stdout.as_slice()), String::from_utf8_lossy(output.stderr.as_slice()) ); diff --git a/tools/rootcanal/rust/src/either.rs b/tools/rootcanal/rust/src/either.rs index af18e93da89..4812e9f13e8 100644 --- a/tools/rootcanal/rust/src/either.rs +++ b/tools/rootcanal/rust/src/either.rs @@ -32,4 +32,4 @@ macro_rules! impl_try_from { } impl_try_from!(lmp::LmpPacket); -impl_try_from!(hci::CommandPacket); +impl_try_from!(hci::Command); diff --git a/tools/rootcanal/rust/src/ffi.rs b/tools/rootcanal/rust/src/ffi.rs index 96fa9b5c662..672fc13e80f 100644 --- a/tools/rootcanal/rust/src/ffi.rs +++ b/tools/rootcanal/rust/src/ffi.rs @@ -20,17 +20,15 @@ pub struct LinkManagerOps { impl LinkManagerOps { pub(crate) fn get_address(&self, handle: u16) -> Option { - let mut result = hci::EMPTY_ADDRESS; - unsafe { (self.get_address)(self.user_pointer, handle, &mut result.bytes as *mut _) }; - if result == hci::EMPTY_ADDRESS { - None - } else { - Some(result) - } + let mut result = [0; 6]; + unsafe { (self.get_address)(self.user_pointer, handle, &mut result as *mut _) }; + let addr = hci::Address::from(&result); + (addr != hci::EMPTY_ADDRESS).then_some(addr) } pub(crate) fn get_handle(&self, addr: hci::Address) -> u16 { - unsafe { (self.get_handle)(self.user_pointer, &addr.bytes as *const _) } + let addr_bytes: [u8; 6] = addr.into(); + unsafe { (self.get_handle)(self.user_pointer, &addr_bytes as *const _) } } pub(crate) fn extended_features(&self, features_page: u8) -> u64 { @@ -42,10 +40,11 @@ impl LinkManagerOps { } pub(crate) fn send_lmp_packet(&self, to: hci::Address, packet: &[u8]) { + let to_bytes: [u8; 6] = to.into(); unsafe { (self.send_lmp_packet)( self.user_pointer, - &to.bytes as *const _, + &to_bytes as *const _, packet.as_ptr(), packet.len(), ) @@ -75,7 +74,7 @@ pub unsafe extern "C" fn link_manager_add_link( peer: *const [u8; 6], ) -> bool { let lm = ManuallyDrop::new(Rc::from_raw(lm)); - lm.add_link(hci::Address { bytes: *peer }).is_ok() + lm.add_link(hci::Address::from(&*peer)).is_ok() } /// Unregister a link with a peer inside the link manager @@ -93,7 +92,7 @@ pub unsafe extern "C" fn link_manager_remove_link( peer: *const [u8; 6], ) -> bool { let lm = ManuallyDrop::new(Rc::from_raw(lm)); - lm.remove_link(hci::Address { bytes: *peer }).is_ok() + lm.remove_link(hci::Address::from(&*peer)).is_ok() } /// Run the Link Manager procedures @@ -127,7 +126,7 @@ pub unsafe extern "C" fn link_manager_ingest_hci( let lm = ManuallyDrop::new(Rc::from_raw(lm)); let data = slice::from_raw_parts(data, len); - if let Ok(packet) = hci::CommandPacket::parse(data) { + if let Ok(packet) = hci::Command::parse(data) { lm.ingest_hci(packet).is_ok() } else { false @@ -157,7 +156,7 @@ pub unsafe extern "C" fn link_manager_ingest_lmp( let data = slice::from_raw_parts(data, len); if let Ok(packet) = lmp::LmpPacket::parse(data) { - lm.ingest_lmp(hci::Address { bytes: *from }, packet).is_ok() + lm.ingest_lmp(hci::Address::from(&*from), packet).is_ok() } else { false } diff --git a/tools/rootcanal/rust/src/lmp/manager.rs b/tools/rootcanal/rust/src/lmp/manager.rs index 4280f46c64f..40031bdbb76 100644 --- a/tools/rootcanal/rust/src/lmp/manager.rs +++ b/tools/rootcanal/rust/src/lmp/manager.rs @@ -21,7 +21,7 @@ struct Link { peer: Cell, // Only store one HCI packet as our Num_HCI_Command_Packets // is always 1 - hci: Cell>, + hci: Cell>, lmp: RefCell>, } @@ -40,11 +40,11 @@ impl Link { self.lmp.borrow_mut().push_back(packet); } - fn ingest_hci(&self, command: hci::CommandPacket) { + fn ingest_hci(&self, command: hci::Command) { assert!(self.hci.replace(Some(command)).is_none(), "HCI flow control violation"); } - fn poll_hci_command>(&self) -> Poll { + fn poll_hci_command>(&self) -> Poll { let command = self.hci.take(); if let Some(command) = command.clone().and_then(|c| c.try_into().ok()) { @@ -117,14 +117,14 @@ impl LinkManager { /// with the specified error code. fn send_command_complete_event( &self, - command: &hci::CommandPacket, + command: &hci::Command, status: hci::ErrorCode, ) -> Result<(), LinkManagerError> { use hci::CommandChild::*; #[allow(unused_imports)] use Option::None; // Overwrite `None` variant of `Child` enum - let event: hci::EventPacket = match command.specialize() { + let event: hci::Event = match command.specialize() { LinkKeyRequestReply(packet) => hci::LinkKeyRequestReplyCompleteBuilder { status, bd_addr: packet.get_bd_addr(), @@ -229,7 +229,7 @@ impl LinkManager { Ok(()) } - pub fn ingest_hci(&self, command: hci::CommandPacket) -> Result<(), LinkManagerError> { + pub fn ingest_hci(&self, command: hci::Command) -> Result<(), LinkManagerError> { // Try to find the matching link from the command arguments let link = hci::command_connection_handle(&command) .and_then(|handle| self.ops.get_address(handle)) @@ -288,7 +288,7 @@ struct LinkContext { } impl procedure::Context for LinkContext { - fn poll_hci_command>(&self) -> Poll { + fn poll_hci_command>(&self) -> Poll { if let Some(manager) = self.manager.upgrade() { manager.link(self.index).poll_hci_command() } else { @@ -304,7 +304,7 @@ impl procedure::Context for LinkContext { } } - fn send_hci_event>(&self, event: E) { + fn send_hci_event>(&self, event: E) { if let Some(manager) = self.manager.upgrade() { manager.ops.send_hci_event(&event.into().to_vec()) } diff --git a/tools/rootcanal/rust/src/lmp/procedure/authentication.rs b/tools/rootcanal/rust/src/lmp/procedure/authentication.rs index 83fa0cb66ef..efc69743ee5 100644 --- a/tools/rootcanal/rust/src/lmp/procedure/authentication.rs +++ b/tools/rootcanal/rust/src/lmp/procedure/authentication.rs @@ -28,7 +28,7 @@ pub async fn receive_challenge(ctx: &impl Context, _link_key: [u8; 16]) { } pub async fn initiate(ctx: &impl Context) { - let _ = ctx.receive_hci_command::().await; + let _ = ctx.receive_hci_command::().await; ctx.send_hci_event( hci::AuthenticationRequestedStatusBuilder { num_hci_command_packets, @@ -39,10 +39,10 @@ pub async fn initiate(ctx: &impl Context) { ctx.send_hci_event(hci::LinkKeyRequestBuilder { bd_addr: ctx.peer_address() }.build()); - let status = match ctx.receive_hci_command::>().await { + let status = match ctx + .receive_hci_command::>() + .await + { Either::Left(_reply) => { ctx.send_hci_event( hci::LinkKeyRequestReplyCompleteBuilder { @@ -53,7 +53,7 @@ pub async fn initiate(ctx: &impl Context) { .build(), ); hci::ErrorCode::Success - }, + } Either::Right(_) => { ctx.send_hci_event( hci::LinkKeyRequestNegativeReplyCompleteBuilder { @@ -64,7 +64,12 @@ pub async fn initiate(ctx: &impl Context) { .build(), ); - let result = if features::supported_on_both_page1(ctx, hci::LMPFeaturesPage1Bits::SecureSimplePairingHostSupport).await { + let result = if features::supported_on_both_page1( + ctx, + hci::LMPFeaturesPage1Bits::SecureSimplePairingHostSupport, + ) + .await + { secure_simple_pairing::initiate(ctx).await } else { legacy_pairing::initiate(ctx).await @@ -72,7 +77,7 @@ pub async fn initiate(ctx: &impl Context) { match result { Ok(_) => hci::ErrorCode::Success, - Err(_) => hci::ErrorCode::AuthenticationFailure + Err(_) => hci::ErrorCode::AuthenticationFailure, } } }; diff --git a/tools/rootcanal/rust/src/lmp/procedure/encryption.rs b/tools/rootcanal/rust/src/lmp/procedure/encryption.rs index 6b7d85d73d6..1e6098660eb 100644 --- a/tools/rootcanal/rust/src/lmp/procedure/encryption.rs +++ b/tools/rootcanal/rust/src/lmp/procedure/encryption.rs @@ -10,7 +10,7 @@ use hci::LMPFeaturesPage2Bits::SecureConnectionsControllerSupport; pub async fn initiate(ctx: &impl Context) { // TODO: handle turn off - let _ = ctx.receive_hci_command::().await; + let _ = ctx.receive_hci_command::().await; ctx.send_hci_event( hci::SetConnectionEncryptionStatusBuilder { num_hci_command_packets, diff --git a/tools/rootcanal/rust/src/lmp/procedure/features.rs b/tools/rootcanal/rust/src/lmp/procedure/features.rs index 2e0f7cbd032..2bf580b38a2 100644 --- a/tools/rootcanal/rust/src/lmp/procedure/features.rs +++ b/tools/rootcanal/rust/src/lmp/procedure/features.rs @@ -1,7 +1,5 @@ // Bluetooth Core, Vol 2, Part C, 4.3.4 -use num_traits::ToPrimitive; - use crate::lmp::procedure::Context; use crate::packets::lmp; @@ -54,12 +52,12 @@ pub async fn supported_on_both_page1( ctx: &impl Context, feature: crate::packets::hci::LMPFeaturesPage1Bits, ) -> bool { - supported_on_both_page(ctx, 1, feature.to_u64().unwrap()).await + supported_on_both_page(ctx, 1, feature.into()).await } pub async fn supported_on_both_page2( ctx: &impl Context, feature: crate::packets::hci::LMPFeaturesPage2Bits, ) -> bool { - supported_on_both_page(ctx, 2, feature.to_u64().unwrap()).await + supported_on_both_page(ctx, 2, feature.into()).await } diff --git a/tools/rootcanal/rust/src/lmp/procedure/legacy_pairing.rs b/tools/rootcanal/rust/src/lmp/procedure/legacy_pairing.rs index f6367f692dd..6f03d8b9f1a 100644 --- a/tools/rootcanal/rust/src/lmp/procedure/legacy_pairing.rs +++ b/tools/rootcanal/rust/src/lmp/procedure/legacy_pairing.rs @@ -8,7 +8,7 @@ use crate::num_hci_command_packets; pub async fn initiate(ctx: &impl Context) -> Result<(), ()> { ctx.send_hci_event(hci::PinCodeRequestBuilder { bd_addr: ctx.peer_address() }.build()); - let _pin_code = ctx.receive_hci_command::().await; + let _pin_code = ctx.receive_hci_command::().await; ctx.send_hci_event( hci::PinCodeRequestReplyCompleteBuilder { @@ -53,7 +53,7 @@ pub async fn initiate(ctx: &impl Context) -> Result<(), ()> { pub async fn respond(ctx: &impl Context, _request: lmp::InRand) -> Result<(), ()> { ctx.send_hci_event(hci::PinCodeRequestBuilder { bd_addr: ctx.peer_address() }.build()); - let _pin_code = ctx.receive_hci_command::().await; + let _pin_code = ctx.receive_hci_command::().await; ctx.send_hci_event( hci::PinCodeRequestReplyCompleteBuilder { diff --git a/tools/rootcanal/rust/src/lmp/procedure/mod.rs b/tools/rootcanal/rust/src/lmp/procedure/mod.rs index ea702fd87bb..8f0598d25b4 100644 --- a/tools/rootcanal/rust/src/lmp/procedure/mod.rs +++ b/tools/rootcanal/rust/src/lmp/procedure/mod.rs @@ -7,10 +7,10 @@ use crate::lmp::ec::PrivateKey; use crate::packets::{hci, lmp}; pub trait Context { - fn poll_hci_command>(&self) -> Poll; + fn poll_hci_command>(&self) -> Poll; fn poll_lmp_packet>(&self) -> Poll

; - fn send_hci_event>(&self, event: E); + fn send_hci_event>(&self, event: E); fn send_lmp_packet>(&self, packet: P); fn peer_address(&self) -> hci::Address; @@ -22,7 +22,7 @@ pub trait Context { fn extended_features(&self, features_page: u8) -> u64; - fn receive_hci_command>(&self) -> ReceiveFuture<'_, Self, C> { + fn receive_hci_command>(&self) -> ReceiveFuture<'_, Self, C> { ReceiveFuture(Self::poll_hci_command, self) } diff --git a/tools/rootcanal/rust/src/lmp/procedure/secure_simple_pairing.rs b/tools/rootcanal/rust/src/lmp/procedure/secure_simple_pairing.rs index ccdfa9fad5f..e7dc6bb6d87 100644 --- a/tools/rootcanal/rust/src/lmp/procedure/secure_simple_pairing.rs +++ b/tools/rootcanal/rust/src/lmp/procedure/secure_simple_pairing.rs @@ -1,8 +1,6 @@ // Bluetooth Core, Vol 2, Part C, 4.2.7 -use std::convert::TryInto; - -use num_traits::{FromPrimitive, ToPrimitive}; +use std::convert::{TryFrom, TryInto}; use crate::either::Either; use crate::lmp::ec::{DhKey, PrivateKey, PublicKey}; @@ -207,8 +205,8 @@ async fn user_confirmation_request(ctx: &impl Context) -> Result<(), ()> { match ctx .receive_hci_command::>() .await { @@ -243,11 +241,8 @@ async fn user_passkey_request(ctx: &impl Context) -> Result<(), ()> { loop { match ctx .receive_hci_command::, - hci::SendKeypressNotificationPacket, + Either, + hci::SendKeypressNotification, >>() .await { @@ -293,8 +288,8 @@ async fn remote_oob_data_request(ctx: &impl Context) -> Result<(), ()> { match ctx .receive_hci_command::>() .await { @@ -331,8 +326,8 @@ pub async fn initiate(ctx: &impl Context) -> Result<(), ()> { ctx.send_hci_event(hci::IoCapabilityRequestBuilder { bd_addr: ctx.peer_address() }.build()); match ctx .receive_hci_command::>() .await { @@ -348,12 +343,11 @@ pub async fn initiate(ctx: &impl Context) -> Result<(), ()> { ctx.send_lmp_packet( lmp::IoCapabilityReqBuilder { transaction_id: 0, - io_capabilities: reply.get_io_capability().to_u8().unwrap(), - oob_authentication_data: reply.get_oob_present().to_u8().unwrap(), + io_capabilities: reply.get_io_capability().into(), + oob_authentication_data: reply.get_oob_present().into(), authentication_requirement: reply .get_authentication_requirements() - .to_u8() - .unwrap(), + .into(), } .build(), ); @@ -386,11 +380,11 @@ pub async fn initiate(ctx: &impl Context) -> Result<(), ()> { let responder = { let response = ctx.receive_lmp_packet::().await; - let io_capability = hci::IoCapability::from_u8(response.get_io_capabilities()).unwrap(); + let io_capability = hci::IoCapability::try_from(response.get_io_capabilities()).unwrap(); let oob_data_present = - hci::OobDataPresent::from_u8(response.get_oob_authentication_data()).unwrap(); + hci::OobDataPresent::try_from(response.get_oob_authentication_data()).unwrap(); let authentication_requirements = - hci::AuthenticationRequirements::from_u8(response.get_authentication_requirement()) + hci::AuthenticationRequirements::try_from(response.get_authentication_requirement()) .unwrap(); ctx.send_hci_event( @@ -537,11 +531,11 @@ pub async fn initiate(ctx: &impl Context) -> Result<(), ()> { pub async fn respond(ctx: &impl Context, request: lmp::IoCapabilityReq) -> Result<(), ()> { let initiator = { - let io_capability = hci::IoCapability::from_u8(request.get_io_capabilities()).unwrap(); + let io_capability = hci::IoCapability::try_from(request.get_io_capabilities()).unwrap(); let oob_data_present = - hci::OobDataPresent::from_u8(request.get_oob_authentication_data()).unwrap(); + hci::OobDataPresent::try_from(request.get_oob_authentication_data()).unwrap(); let authentication_requirements = - hci::AuthenticationRequirements::from_u8(request.get_authentication_requirement()) + hci::AuthenticationRequirements::try_from(request.get_authentication_requirement()) .unwrap(); ctx.send_hci_event( @@ -561,8 +555,8 @@ pub async fn respond(ctx: &impl Context, request: lmp::IoCapabilityReq) -> Resul ctx.send_hci_event(hci::IoCapabilityRequestBuilder { bd_addr: ctx.peer_address() }.build()); match ctx .receive_hci_command::>() .await { @@ -578,12 +572,11 @@ pub async fn respond(ctx: &impl Context, request: lmp::IoCapabilityReq) -> Resul ctx.send_lmp_packet( lmp::IoCapabilityResBuilder { transaction_id: 0, - io_capabilities: reply.get_io_capability().to_u8().unwrap(), - oob_authentication_data: reply.get_oob_present().to_u8().unwrap(), + io_capabilities: reply.get_io_capability().into(), + oob_authentication_data: reply.get_oob_present().into(), authentication_requirement: reply .get_authentication_requirements() - .to_u8() - .unwrap(), + .into(), } .build(), ); @@ -605,7 +598,7 @@ pub async fn respond(ctx: &impl Context, request: lmp::IoCapabilityReq) -> Resul ctx.send_lmp_packet( lmp::NotAcceptedExtBuilder { transaction_id: 0, - error_code: reply.get_reason().to_u8().unwrap(), + error_code: reply.get_reason().into(), not_accepted_opcode: lmp::ExtendedOpcode::IoCapabilityReq, } .build(), @@ -694,7 +687,7 @@ pub async fn respond(ctx: &impl Context, request: lmp::IoCapabilityReq) -> Resul lmp::NotAcceptedBuilder { transaction_id: 0, not_accepted_opcode: lmp::Opcode::DhkeyCheck, - error_code: hci::ErrorCode::AuthenticationFailure.to_u8().unwrap(), + error_code: hci::ErrorCode::AuthenticationFailure.into(), } .build(), ); @@ -754,8 +747,6 @@ pub async fn respond(ctx: &impl Context, request: lmp::IoCapabilityReq) -> Resul #[cfg(test)] mod tests { - use num_traits::ToPrimitive; - use crate::lmp::ec::PrivateKey; use crate::lmp::procedure::Context; use crate::lmp::test::{sequence, TestContext}; diff --git a/tools/rootcanal/rust/src/lmp/test/context.rs b/tools/rootcanal/rust/src/lmp/test/context.rs index 5ab6e9b9899..f5f505d408e 100644 --- a/tools/rootcanal/rust/src/lmp/test/context.rs +++ b/tools/rootcanal/rust/src/lmp/test/context.rs @@ -5,8 +5,6 @@ use std::future::Future; use std::pin::Pin; use std::task::{self, Poll}; -use num_traits::ToPrimitive; - use crate::lmp::ec::PrivateKey; use crate::packets::{hci, lmp}; @@ -16,8 +14,8 @@ use crate::lmp::procedure::Context; pub struct TestContext { pub in_lmp_packets: RefCell>, pub out_lmp_packets: RefCell>, - pub hci_events: RefCell>, - pub hci_commands: RefCell>, + pub hci_events: RefCell>, + pub hci_commands: RefCell>, private_key: RefCell>, features_pages: [u64; 3], peer_features_pages: [u64; 3], @@ -31,28 +29,28 @@ impl TestContext { } pub fn with_page_1_feature(mut self, feature: hci::LMPFeaturesPage1Bits) -> Self { - self.features_pages[1] |= feature.to_u64().unwrap(); + self.features_pages[1] |= u64::from(feature); self } pub fn with_page_2_feature(mut self, feature: hci::LMPFeaturesPage2Bits) -> Self { - self.features_pages[2] |= feature.to_u64().unwrap(); + self.features_pages[2] |= u64::from(feature); self } pub fn with_peer_page_1_feature(mut self, feature: hci::LMPFeaturesPage1Bits) -> Self { - self.peer_features_pages[1] |= feature.to_u64().unwrap(); + self.peer_features_pages[1] |= u64::from(feature); self } pub fn with_peer_page_2_feature(mut self, feature: hci::LMPFeaturesPage2Bits) -> Self { - self.peer_features_pages[2] |= feature.to_u64().unwrap(); + self.peer_features_pages[2] |= u64::from(feature); self } } impl Context for TestContext { - fn poll_hci_command>(&self) -> Poll { + fn poll_hci_command>(&self) -> Poll { let command = self.hci_commands.borrow().front().and_then(|command| command.clone().try_into().ok()); @@ -76,7 +74,7 @@ impl Context for TestContext { } } - fn send_hci_event>(&self, event: E) { + fn send_hci_event>(&self, event: E) { self.hci_events.borrow_mut().push_back(event.into()); } @@ -85,7 +83,7 @@ impl Context for TestContext { } fn peer_address(&self) -> hci::Address { - hci::Address { bytes: [0; 6] } + hci::Address::try_from(0).unwrap() } fn peer_handle(&self) -> u16 { diff --git a/tools/rootcanal/rust/src/lmp/test/sequence.rs b/tools/rootcanal/rust/src/lmp/test/sequence.rs index 42460090713..47bf87314c5 100644 --- a/tools/rootcanal/rust/src/lmp/test/sequence.rs +++ b/tools/rootcanal/rust/src/lmp/test/sequence.rs @@ -46,7 +46,7 @@ macro_rules! sequence_body { use crate::packets::hci::*; paste! { - let packet: [<$packet Packet>] = $ctx.0.hci_events.borrow_mut().pop_front().expect("No hci packet").try_into().unwrap(); + let packet: $packet = $ctx.0.hci_events.borrow_mut().pop_front().expect("No hci packet").try_into().unwrap(); } $( diff --git a/tools/rootcanal/rust/src/packets.rs b/tools/rootcanal/rust/src/packets.rs index 4b88a3df0ff..87f47206803 100644 --- a/tools/rootcanal/rust/src/packets.rs +++ b/tools/rootcanal/rust/src/packets.rs @@ -3,59 +3,41 @@ pub mod hci { #![allow(unused)] #![allow(missing_docs)] - pub const EMPTY_ADDRESS: Address = Address { bytes: [0x00, 0x00, 0x00, 0x00, 0x00, 0x00] }; - pub const ANY_ADDRESS: Address = Address { bytes: [0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF] }; - - /// A Bluetooth address - #[derive(Clone, Copy, Eq, PartialEq, Hash, Ord, PartialOrd, Debug)] - pub struct Address { - pub bytes: [u8; 6], - } + include!(concat!(env!("OUT_DIR"), "/hci_packets.rs")); - impl Address { - pub fn is_empty(&self) -> bool { - *self == EMPTY_ADDRESS - } - } + pub const EMPTY_ADDRESS: Address = Address(0x000000000000); + pub const ANY_ADDRESS: Address = Address(0xffffffffffff); impl fmt::Display for Address { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + let bytes = u64::to_le_bytes(self.0); write!( f, "{:02X}:{:02X}:{:02X}:{:02X}:{:02X}:{:02X}", - self.bytes[5], - self.bytes[4], - self.bytes[3], - self.bytes[2], - self.bytes[1], - self.bytes[0] + bytes[5], bytes[4], bytes[3], bytes[2], bytes[1], bytes[0], ) } } - #[derive(Debug, Clone)] - pub struct InvalidAddressError; - - impl TryFrom<&[u8]> for Address { - type Error = InvalidAddressError; - - fn try_from(slice: &[u8]) -> std::result::Result { - match <[u8; 6]>::try_from(slice) { - Ok(bytes) => Ok(Self { bytes }), - Err(_) => Err(InvalidAddressError), - } + impl From<&[u8; 6]> for Address { + fn from(bytes: &[u8; 6]) -> Self { + Self(u64::from_le_bytes([ + bytes[0], bytes[1], bytes[2], bytes[3], bytes[4], bytes[5], 0, 0, + ])) } } impl From

for [u8; 6] { - fn from(addr: Address) -> [u8; 6] { - addr.bytes + fn from(Address(addr): Address) -> Self { + let bytes = u64::to_le_bytes(addr); + bytes[0..6].try_into().unwrap() } } - #[derive(Clone, Eq, Copy, PartialEq, Hash, Ord, PartialOrd, Debug)] - pub struct ClassOfDevice { - pub bytes: [u8; 3], + impl Address { + pub fn is_empty(&self) -> bool { + *self == EMPTY_ADDRESS + } } impl fmt::Display for ClassOfDevice { @@ -63,36 +45,14 @@ pub mod hci { write!( f, "{:03X}-{:01X}-{:02X}", - ((self.bytes[2] as u16) << 4) | ((self.bytes[1] as u16) >> 4), - self.bytes[1] & 0x0F, - self.bytes[0] + (self.0 >> 12) & 0xfff, + (self.0 >> 8) & 0xf, + self.0 & 0xff, ) } } - #[derive(Debug, Clone)] - pub struct InvalidClassOfDeviceError; - - impl TryFrom<&[u8]> for ClassOfDevice { - type Error = InvalidClassOfDeviceError; - - fn try_from(slice: &[u8]) -> std::result::Result { - match <[u8; 3]>::try_from(slice) { - Ok(bytes) => Ok(Self { bytes }), - Err(_) => Err(InvalidClassOfDeviceError), - } - } - } - - impl From for [u8; 3] { - fn from(cod: ClassOfDevice) -> [u8; 3] { - cod.bytes - } - } - - include!(concat!(env!("OUT_DIR"), "/hci_packets.rs")); - - pub fn command_remote_device_address(command: &CommandPacket) -> Option
{ + pub fn command_remote_device_address(command: &Command) -> Option
{ use CommandChild::*; #[allow(unused_imports)] use Option::None; // Overwrite `None` variant of `Child` enum @@ -115,7 +75,7 @@ pub mod hci { } } - pub fn command_connection_handle(command: &CommandPacket) -> Option { + pub fn command_connection_handle(command: &Command) -> Option { use CommandChild::*; #[allow(unused_imports)] use Option::None; // Overwrite `None` variant of `Child` enum diff --git a/tools/rootcanal/rust/test/SP/BV-16-C.in b/tools/rootcanal/rust/test/SP/BV-16-C.in index fc3f014f3b1..dc0b6ba9fc0 100644 --- a/tools/rootcanal/rust/test/SP/BV-16-C.in +++ b/tools/rootcanal/rust/test/SP/BV-16-C.in @@ -119,7 +119,7 @@ sequence! { procedure, context, Lower Tester -> IUT: NotAccepted { transaction_id: 0, not_accepted_opcode: Opcode::SimplePairingNumber, - error_code: ErrorCode::AuthenticationFailure.to_u8().unwrap(), + error_code: ErrorCode::AuthenticationFailure.into(), } IUT -> Upper Tester: SimplePairingComplete { status: ErrorCode::AuthenticationFailure, diff --git a/tools/rootcanal/rust/test/SP/BV-17-C.in b/tools/rootcanal/rust/test/SP/BV-17-C.in index 33ea83983dc..fd8d50e8aac 100644 --- a/tools/rootcanal/rust/test/SP/BV-17-C.in +++ b/tools/rootcanal/rust/test/SP/BV-17-C.in @@ -90,7 +90,7 @@ sequence! { procedure, context, IUT -> Lower Tester: NotAccepted { transaction_id: 0, not_accepted_opcode: Opcode::SimplePairingNumber, - error_code: ErrorCode::AuthenticationFailure.to_u8().unwrap(), + error_code: ErrorCode::AuthenticationFailure.into(), } IUT -> Upper Tester: SimplePairingComplete { status: ErrorCode::AuthenticationFailure, diff --git a/tools/rootcanal/rust/test/SP/BV-30-C.in b/tools/rootcanal/rust/test/SP/BV-30-C.in index 29784f0b16f..8c19aecf60e 100644 --- a/tools/rootcanal/rust/test/SP/BV-30-C.in +++ b/tools/rootcanal/rust/test/SP/BV-30-C.in @@ -27,7 +27,7 @@ sequence! { procedure, context, IUT -> Lower Tester: NotAcceptedExt { transaction_id: 0, not_accepted_opcode: ExtendedOpcode::IoCapabilityReq, - error_code: ErrorCode::PairingNotAllowed.to_u8().unwrap(), + error_code: ErrorCode::PairingNotAllowed.into(), } IUT -> Upper Tester: SimplePairingComplete { status: ErrorCode::AuthenticationFailure, diff --git a/tools/rootcanal/rust/test/SP/BV-32-C.in b/tools/rootcanal/rust/test/SP/BV-32-C.in index bd3017e53b8..c1fd0068626 100644 --- a/tools/rootcanal/rust/test/SP/BV-32-C.in +++ b/tools/rootcanal/rust/test/SP/BV-32-C.in @@ -27,7 +27,7 @@ sequence! { procedure, context, IUT -> Lower Tester: NotAcceptedExt { transaction_id: 0, not_accepted_opcode: ExtendedOpcode::IoCapabilityReq, - error_code: ErrorCode::HostBusy.to_u8().unwrap(), + error_code: ErrorCode::HostBusy.into(), } IUT -> Upper Tester: SimplePairingComplete { status: ErrorCode::AuthenticationFailure, diff --git a/tools/rootcanal/rust/test/SP/BV-35-C.in b/tools/rootcanal/rust/test/SP/BV-35-C.in index 999a4baf162..b14a593f58a 100644 --- a/tools/rootcanal/rust/test/SP/BV-35-C.in +++ b/tools/rootcanal/rust/test/SP/BV-35-C.in @@ -145,7 +145,7 @@ sequence! { procedure, context, Lower Tester -> IUT: NotAccepted { transaction_id: 0, not_accepted_opcode: Opcode::SimplePairingNumber, - error_code: ErrorCode::AuthenticationFailure.to_u8().unwrap(), + error_code: ErrorCode::AuthenticationFailure.into(), } IUT -> Upper Tester: SimplePairingComplete { status: ErrorCode::AuthenticationFailure, diff --git a/tools/rootcanal/rust/test/SP/BV-36-C.in b/tools/rootcanal/rust/test/SP/BV-36-C.in index f9948d6c7e6..03d276915be 100644 --- a/tools/rootcanal/rust/test/SP/BV-36-C.in +++ b/tools/rootcanal/rust/test/SP/BV-36-C.in @@ -106,7 +106,7 @@ sequence! { procedure, context, IUT -> Lower Tester: NotAccepted { transaction_id: 0, not_accepted_opcode: Opcode::SimplePairingNumber, - error_code: ErrorCode::AuthenticationFailure.to_u8().unwrap(), + error_code: ErrorCode::AuthenticationFailure.into(), } IUT -> Upper Tester: SimplePairingComplete { status: ErrorCode::AuthenticationFailure, -- GitLab From de135fd4c6a1ed974314a48f5346bfb7750b81c4 Mon Sep 17 00:00:00 2001 From: Yuyang Huang Date: Tue, 16 May 2023 14:46:15 -0700 Subject: [PATCH 0113/2405] Enhance CLCC inference sort CLCC response by index add null check clear inference when conference call children arrive clear inference when parent call ends Bug: 262199042 Test: atest com.android.bluetooth.telephony.BluetoothInCallServiceTest Change-Id: I35d2f8569af1deb13b830a1f23ec540679435233 --- .../telephony/BluetoothInCallService.java | 112 ++++++++++---- .../telephony/BluetoothInCallServiceTest.java | 140 ++++++++++++++++++ 2 files changed, 224 insertions(+), 28 deletions(-) diff --git a/android/app/src/com/android/bluetooth/telephony/BluetoothInCallService.java b/android/app/src/com/android/bluetooth/telephony/BluetoothInCallService.java index a7fa694fd43..4ebc38dccb6 100644 --- a/android/app/src/com/android/bluetooth/telephony/BluetoothInCallService.java +++ b/android/app/src/com/android/bluetooth/telephony/BluetoothInCallService.java @@ -62,6 +62,8 @@ import java.util.List; import java.util.Map; import java.util.Objects; import java.util.Queue; +import java.util.SortedMap; +import java.util.TreeMap; import java.util.UUID; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; @@ -75,7 +77,7 @@ import java.util.concurrent.Executors; public class BluetoothInCallService extends InCallService { private static final String TAG = "BluetoothInCallService"; - private static final String CLCC_INFERENCE = "ConferenceCallInference"; + @VisibleForTesting static final String CLCC_INFERENCE = "ConferenceCallInference"; // match up with bthf_call_state_t of bt_hf.h private static final int CALL_STATE_ACTIVE = 0; @@ -154,7 +156,7 @@ public class BluetoothInCallService extends InCallService { private int mMaxNumberOfCalls = 0; /** - * Listens to connections and disconnections of bluetooth headsets. We need to save the current + * Listens to connections and disconnections of bluetooth headsets. We need to save the current * bluetooth headset so that we know where to send BluetoothCall updates. */ @VisibleForTesting @@ -164,11 +166,13 @@ public class BluetoothInCallService extends InCallService { public void onServiceConnected(int profile, BluetoothProfile proxy) { synchronized (LOCK) { if (profile == BluetoothProfile.HEADSET) { - setBluetoothHeadset(new BluetoothHeadsetProxy((BluetoothHeadset) proxy)); + setBluetoothHeadset( + new BluetoothHeadsetProxy((BluetoothHeadset) proxy)); updateHeadsetWithCallState(true /* force */); } else { - setBluetoothLeCallControl(new BluetoothLeCallControlProxy(( - BluetoothLeCallControl) proxy)); + setBluetoothLeCallControl( + new BluetoothLeCallControlProxy( + (BluetoothLeCallControl) proxy)); sendTbsCurrentCallsList(); } } @@ -639,15 +643,30 @@ public class BluetoothInCallService extends InCallService { if (mBluetoothCallHashMap.containsKey(call.getId())) { mBluetoothCallHashMap.remove(call.getId()); - mBluetoothCallQueue.add(call.getId()); - mBluetoothConferenceCallInference.put(call.getId(), call); - mClccInferenceIndexMap.put(getClccMapKey(call), mClccIndexMap.get(getClccMapKey(call))); - // queue size limited to 2 because merge operation only happens on 2 calls - // we are only interested in last 2 calls merged - if (mBluetoothCallQueue.size() > 2) { - Integer callId = mBluetoothCallQueue.peek(); - mBluetoothCallQueue.remove(); - mBluetoothConferenceCallInference.remove(callId); + DisconnectCause cause = call.getDisconnectCause(); + if (cause != null && cause.getCode() == DisconnectCause.OTHER) { + Log.d(TAG, "add inference call with reason: " + cause.getReason()); + mBluetoothCallQueue.add(call.getId()); + mBluetoothConferenceCallInference.put(call.getId(), call); + Integer indexValue = mClccIndexMap.get(getClccMapKey(call)); + mClccInferenceIndexMap.put(getClccMapKey(call), indexValue); + if (indexValue == null) { + Log.w(TAG, "CLCC index value is null"); + } + // queue size limited to 2 because merge operation only happens on 2 calls + // we are only interested in last 2 calls merged + if (mBluetoothCallQueue.size() > 2) { + Integer callId = mBluetoothCallQueue.peek(); + mBluetoothCallQueue.remove(); + mBluetoothConferenceCallInference.remove(callId); + } + } + // As there is at most 1 conference call, so clear inference when parent call ends + if (call.isConference()) { + Log.d(TAG, "conference call ends, clear inference"); + mBluetoothConferenceCallInference.clear(); + mClccInferenceIndexMap.clear(); + mBluetoothCallQueue.clear(); } } @@ -745,18 +764,34 @@ public class BluetoothInCallService extends InCallService { Log.d(TAG, "is conference call inference enabled: " + isInferenceEnabled); for (BluetoothCall call : calls) { if (isInferenceEnabled && call.isConference() - && call.getChildrenIds().size() < 2 && !mBluetoothConferenceCallInference.isEmpty()) { - Log.d(TAG, "conference call inferred size: " - + mBluetoothConferenceCallInference.size() - + "current size: " + mBluetoothCallHashMap.size()); + SortedMap clccResponseMap = new TreeMap<>(); + Log.d( + TAG, + "conference call inferred size: " + + mBluetoothConferenceCallInference.size() + + " current size: " + + mBluetoothCallHashMap.size()); // Do conference call inference until at least 2 children arrive // If carrier does send children info, then inference will end when info arrives. // If carrier does not send children info, then inference won't impact actual value. + if (call.getChildrenIds().size() >= 2) { + mBluetoothConferenceCallInference.clear(); + break; + } for (BluetoothCall inferredCall : mBluetoothConferenceCallInference.values()) { - int index = mClccInferenceIndexMap.get(getClccMapKey(inferredCall)); + String clccMapKey = getClccMapKey(inferredCall); + if (!mClccInferenceIndexMap.containsKey(clccMapKey)) { + Log.w(TAG, "Inference Index Map does not have: " + clccMapKey); + continue; + } + if (mClccInferenceIndexMap.get(clccMapKey) == null) { + Log.w(TAG, "inferred index is null"); + continue; + } + int index = mClccInferenceIndexMap.get(clccMapKey); // save the index so later on when real children arrive, index is the same - mClccIndexMap.put(getClccMapKey(inferredCall), index); + mClccIndexMap.put(clccMapKey, index); int direction = inferredCall.isIncoming() ? 1 : 0; int state = CALL_STATE_ACTIVE; boolean isPartOfConference = true; @@ -770,17 +805,38 @@ public class BluetoothInCallService extends InCallService { if (address != null) { address = PhoneNumberUtils.stripSeparators(address); } - int addressType = address == null ? -1 : PhoneNumberUtils.toaFromString(address); - Log.i(TAG, "sending inferred clcc for BluetoothCall " - + index + ", " - + direction + ", " - + state + ", " - + isPartOfConference + ", " - + addressType); + clccResponseMap.put( + index, + new Object[] { + index, direction, state, 0, isPartOfConference, address, addressType + }); + } + // ensure response is sorted by index + for (Object[] response : clccResponseMap.values()) { + if (response.length < 7) { + Log.e(TAG, "clccResponseMap entry too short"); + continue; + } + Log.i( + TAG, + String.format( + "sending inferred clcc for BluetoothCall: index %d, direction" + + " %d, state %d, isPartOfConference %b, addressType %d", + (int) response[0], + (int) response[1], + (int) response[2], + (boolean) response[4], + (int) response[6])); mBluetoothHeadset.clccResponse( - index, direction, state, 0, isPartOfConference, address, addressType); + (int) response[0], + (int) response[1], + (int) response[2], + (int) response[3], + (boolean) response[4], + (String) response[5], + (int) response[6]); } sendClccEndMarker(); return; diff --git a/android/app/tests/unit/src/com/android/bluetooth/telephony/BluetoothInCallServiceTest.java b/android/app/tests/unit/src/com/android/bluetooth/telephony/BluetoothInCallServiceTest.java index 0b503f1659b..ea787aa7330 100644 --- a/android/app/tests/unit/src/com/android/bluetooth/telephony/BluetoothInCallServiceTest.java +++ b/android/app/tests/unit/src/com/android/bluetooth/telephony/BluetoothInCallServiceTest.java @@ -16,6 +16,7 @@ package com.android.bluetooth.telephony; +import static com.android.bluetooth.telephony.BluetoothInCallService.CLCC_INFERENCE; import static org.mockito.ArgumentMatchers.any; import static org.mockito.Mockito.*; @@ -31,6 +32,7 @@ import android.os.Binder; import android.os.Build; import android.os.Bundle; import android.os.IBinder; +import android.provider.DeviceConfig; import android.telecom.BluetoothCallQualityReport; import android.telecom.Call; import android.telecom.Connection; @@ -766,6 +768,144 @@ public class BluetoothInCallServiceTest { eq(1), eq(1), eq(0), eq(0), eq(true), eq("5551234"), eq(129)); } + @Test + public void testListCurrentCallsConferenceEmptyChildrenInference() throws Exception { + DeviceConfig.setProperty(DeviceConfig.NAMESPACE_BLUETOOTH, CLCC_INFERENCE, "true", false); + + ArrayList calls = new ArrayList<>(); + when(mMockCallInfo.getBluetoothCalls()).thenReturn(calls); + + // active call is added + BluetoothCall activeCall = createActiveCall(UUID.randomUUID()); + calls.add(activeCall); + mBluetoothInCallService.onCallAdded(activeCall); + + when(activeCall.getState()).thenReturn(Call.STATE_ACTIVE); + when(activeCall.isIncoming()).thenReturn(false); + when(activeCall.isConference()).thenReturn(false); + when(activeCall.getHandle()).thenReturn(Uri.parse("tel:555-0001")); + when(activeCall.getGatewayInfo()) + .thenReturn(new GatewayInfo(null, null, Uri.parse("tel:555-0001"))); + + // holding call is added + BluetoothCall holdingCall = createHeldCall(UUID.randomUUID()); + calls.add(holdingCall); + mBluetoothInCallService.onCallAdded(holdingCall); + + when(holdingCall.getState()).thenReturn(Call.STATE_HOLDING); + when(holdingCall.isIncoming()).thenReturn(true); + when(holdingCall.isConference()).thenReturn(false); + when(holdingCall.getHandle()).thenReturn(Uri.parse("tel:555-0002")); + when(holdingCall.getGatewayInfo()) + .thenReturn(new GatewayInfo(null, null, Uri.parse("tel:555-0002"))); + + // needs to have at least one CLCC response before merge to enable call inference + clearInvocations(mMockBluetoothHeadset); + mBluetoothInCallService.listCurrentCalls(); + verify(mMockBluetoothHeadset) + .clccResponse( + 1, 0, CALL_STATE_ACTIVE, 0, false, "5550001", PhoneNumberUtils.TOA_Unknown); + verify(mMockBluetoothHeadset) + .clccResponse( + 2, 1, CALL_STATE_HELD, 0, false, "5550002", PhoneNumberUtils.TOA_Unknown); + calls.clear(); + + // calls merged for conference call + DisconnectCause cause = new DisconnectCause(DisconnectCause.OTHER); + when(activeCall.getDisconnectCause()).thenReturn(cause); + when(holdingCall.getDisconnectCause()).thenReturn(cause); + mBluetoothInCallService.onCallRemoved(activeCall, true); + mBluetoothInCallService.onCallRemoved(holdingCall, true); + + BluetoothCall conferenceCall = createActiveCall(UUID.randomUUID()); + addCallCapability(conferenceCall, Connection.CAPABILITY_MANAGE_CONFERENCE); + + when(conferenceCall.getHandle()).thenReturn(Uri.parse("tel:555-1234")); + when(conferenceCall.isConference()).thenReturn(true); + when(conferenceCall.getState()).thenReturn(Call.STATE_ACTIVE); + when(conferenceCall.hasProperty(Call.Details.PROPERTY_GENERIC_CONFERENCE)).thenReturn(true); + when(conferenceCall.can(Connection.CAPABILITY_CONFERENCE_HAS_NO_CHILDREN)) + .thenReturn(false); + when(conferenceCall.isIncoming()).thenReturn(true); + when(mMockCallInfo.getBluetoothCalls()).thenReturn(calls); + + // parent call arrived, but children have not, then do inference on children + calls.add(conferenceCall); + Assert.assertEquals(calls.size(), 1); + mBluetoothInCallService.onCallAdded(conferenceCall); + + clearInvocations(mMockBluetoothHeadset); + mBluetoothInCallService.listCurrentCalls(); + verify(mMockBluetoothHeadset) + .clccResponse( + 1, 0, CALL_STATE_ACTIVE, 0, true, "5550001", PhoneNumberUtils.TOA_Unknown); + verify(mMockBluetoothHeadset) + .clccResponse( + 2, 1, CALL_STATE_ACTIVE, 0, true, "5550002", PhoneNumberUtils.TOA_Unknown); + + // real children arrive, no change on CLCC response + calls.add(activeCall); + mBluetoothInCallService.onCallAdded(activeCall); + when(activeCall.isConference()).thenReturn(true); + calls.add(holdingCall); + mBluetoothInCallService.onCallAdded(holdingCall); + when(holdingCall.getState()).thenReturn(Call.STATE_ACTIVE); + when(holdingCall.isConference()).thenReturn(true); + when(conferenceCall.getChildrenIds()).thenReturn(new ArrayList<>(Arrays.asList(1, 2))); + + clearInvocations(mMockBluetoothHeadset); + mBluetoothInCallService.listCurrentCalls(); + verify(mMockBluetoothHeadset) + .clccResponse( + 1, 0, CALL_STATE_ACTIVE, 0, true, "5550001", PhoneNumberUtils.TOA_Unknown); + verify(mMockBluetoothHeadset) + .clccResponse( + 2, 1, CALL_STATE_ACTIVE, 0, true, "5550002", PhoneNumberUtils.TOA_Unknown); + + // when call is terminated, children first removed, then parent + cause = new DisconnectCause(DisconnectCause.LOCAL); + when(activeCall.getDisconnectCause()).thenReturn(cause); + when(holdingCall.getDisconnectCause()).thenReturn(cause); + mBluetoothInCallService.onCallRemoved(activeCall, true); + mBluetoothInCallService.onCallRemoved(holdingCall, true); + calls.remove(activeCall); + calls.remove(holdingCall); + Assert.assertEquals(calls.size(), 1); + + clearInvocations(mMockBluetoothHeadset); + mBluetoothInCallService.listCurrentCalls(); + verify(mMockBluetoothHeadset).clccResponse(0, 0, 0, 0, false, null, 0); + verify(mMockBluetoothHeadset, times(1)) + .clccResponse( + anyInt(), + anyInt(), + anyInt(), + anyInt(), + anyBoolean(), + nullable(String.class), + anyInt()); + + // when parent is removed + when(conferenceCall.getDisconnectCause()).thenReturn(cause); + calls.remove(conferenceCall); + mBluetoothInCallService.onCallRemoved(conferenceCall, true); + + clearInvocations(mMockBluetoothHeadset); + mBluetoothInCallService.listCurrentCalls(); + verify(mMockBluetoothHeadset).clccResponse(0, 0, 0, 0, false, null, 0); + verify(mMockBluetoothHeadset, times(1)) + .clccResponse( + anyInt(), + anyInt(), + anyInt(), + anyInt(), + anyBoolean(), + nullable(String.class), + anyInt()); + + DeviceConfig.setProperty(DeviceConfig.NAMESPACE_BLUETOOTH, CLCC_INFERENCE, "false", false); + } + @Test public void testQueryPhoneState() throws Exception { BluetoothCall ringingCall = createRingingCall(UUID.randomUUID()); -- GitLab From 81587000062abf42d58f9870120d81008b52aab0 Mon Sep 17 00:00:00 2001 From: Charlie Boutier Date: Tue, 18 Apr 2023 16:49:35 +0000 Subject: [PATCH 0114/2405] Pandora avatar: adb forward rootcanal vsock server port Bug: 265144446 Bug: 261847616 Test: avatar run --mobly-std-log --include-filter 'ExampleTest#test_classic_connect' on a TV target Change-Id: Iada26e4e001838f44173923806a48e21a1b79123 --- android/pandora/test/AndroidTest.xml | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/android/pandora/test/AndroidTest.xml b/android/pandora/test/AndroidTest.xml index 8e893d3c15f..b76fe083fbe 100644 --- a/android/pandora/test/AndroidTest.xml +++ b/android/pandora/test/AndroidTest.xml @@ -24,8 +24,7 @@