diff --git a/lib/connector/meshcore_connector.dart b/lib/connector/meshcore_connector.dart index 7868162..8932c8e 100644 --- a/lib/connector/meshcore_connector.dart +++ b/lib/connector/meshcore_connector.dart @@ -2520,18 +2520,42 @@ class MeshCoreConnector extends ChangeNotifier { } } } else { - try { - await device.connect( - timeout: connectTimeout, - mtu: null, - license: License.free, - ); - } catch (error) { - _appDebugLogService?.error( - 'device.connect() failure: $error', - tag: 'BLE Connect', - ); - rethrow; + var attempt = 0; + while (true) { + attempt++; + try { + await device.connect( + timeout: connectTimeout, + mtu: null, + license: License.free, + ); + break; + } catch (error) { + // Android GATT status 133 (ANDROID_SPECIFIC_ERROR) is the + // notorious, frequently transient connect failure. Standard + // mitigation (#522/#698): clean close, short delay, one bounded + // retry before surfacing anything to the user. + final isTransient133 = + error is FlutterBluePlusException && error.code == 133; + _appDebugLogService?.error( + 'device.connect() failure (attempt $attempt): $error', + tag: 'BLE Connect', + ); + if (!isTransient133 || attempt >= 2) rethrow; + try { + await device.disconnect(queue: false, timeout: 5); + } catch (cleanupError) { + _appDebugLogService?.warn( + 'cleanup disconnect before 133 retry failed: $cleanupError', + tag: 'BLE Connect', + ); + } + await Future.delayed(const Duration(milliseconds: 800)); + _appDebugLogService?.info( + 'retrying connect after GATT 133', + tag: 'BLE Connect', + ); + } } } diff --git a/lib/l10n/app_en.arb b/lib/l10n/app_en.arb index d12e873..24495d2 100644 --- a/lib/l10n/app_en.arb +++ b/lib/l10n/app_en.arb @@ -134,6 +134,18 @@ "scanner_scan": "Scan", "scanner_bluetoothOff": "Bluetooth is off", "scanner_bluetoothOffMessage": "Please turn on Bluetooth to scan for devices", + "scanner_connectFailedTransient": "The radio refused the connection (a common transient Bluetooth error). It was already retried; wait a few seconds and try again.", + "@scanner_connectFailedTransient": { + "description": "Human-readable text for an Android GATT 133 connect failure after the bounded retry also failed (#698)." + }, + "scanner_connectFailedTimeout": "The connection timed out. Check that the radio is powered, in range, and not already connected to another device.", + "@scanner_connectFailedTimeout": { + "description": "Human-readable text for a connect timeout (#698)." + }, + "scanner_connectFailedGeneric": "Could not connect to the radio. Details are in the App Debug Log.", + "@scanner_connectFailedGeneric": { + "description": "Human-readable fallback for any other connect failure; the raw exception goes to the log only (#522/#698)." + }, "scanner_bleReleaseWarning": "Radio may still be held by this device", "@scanner_bleReleaseWarning": { "description": "Persistent banner title when a BLE disconnect was never confirmed by the OS, so the radio may stay latched and stop advertising (#697)." diff --git a/lib/l10n/app_localizations.dart b/lib/l10n/app_localizations.dart index 730d182..a0c9059 100644 --- a/lib/l10n/app_localizations.dart +++ b/lib/l10n/app_localizations.dart @@ -640,6 +640,24 @@ abstract class AppLocalizations { /// **'Please turn on Bluetooth to scan for devices'** String get scanner_bluetoothOffMessage; + /// Human-readable text for an Android GATT 133 connect failure after the bounded retry also failed (#698). + /// + /// In en, this message translates to: + /// **'The radio refused the connection (a common transient Bluetooth error). It was already retried; wait a few seconds and try again.'** + String get scanner_connectFailedTransient; + + /// Human-readable text for a connect timeout (#698). + /// + /// In en, this message translates to: + /// **'The connection timed out. Check that the radio is powered, in range, and not already connected to another device.'** + String get scanner_connectFailedTimeout; + + /// Human-readable fallback for any other connect failure; the raw exception goes to the log only (#522/#698). + /// + /// In en, this message translates to: + /// **'Could not connect to the radio. Details are in the App Debug Log.'** + String get scanner_connectFailedGeneric; + /// Persistent banner title when a BLE disconnect was never confirmed by the OS, so the radio may stay latched and stop advertising (#697). /// /// In en, this message translates to: diff --git a/lib/l10n/app_localizations_bg.dart b/lib/l10n/app_localizations_bg.dart index a891bec..dc0a1c0 100644 --- a/lib/l10n/app_localizations_bg.dart +++ b/lib/l10n/app_localizations_bg.dart @@ -290,6 +290,18 @@ class AppLocalizationsBg extends AppLocalizations { String get scanner_bluetoothOffMessage => 'Моля, активирайте Bluetooth, за да сканирате за устройства.'; + @override + String get scanner_connectFailedTransient => + 'The radio refused the connection (a common transient Bluetooth error). It was already retried; wait a few seconds and try again.'; + + @override + String get scanner_connectFailedTimeout => + 'The connection timed out. Check that the radio is powered, in range, and not already connected to another device.'; + + @override + String get scanner_connectFailedGeneric => + 'Could not connect to the radio. Details are in the App Debug Log.'; + @override String get scanner_bleReleaseWarning => 'Radio may still be held by this device'; diff --git a/lib/l10n/app_localizations_de.dart b/lib/l10n/app_localizations_de.dart index 597e4fc..0726908 100644 --- a/lib/l10n/app_localizations_de.dart +++ b/lib/l10n/app_localizations_de.dart @@ -293,6 +293,18 @@ class AppLocalizationsDe extends AppLocalizations { String get scanner_bluetoothOffMessage => 'Bitte aktivieren Sie Bluetooth, um nach Geräten zu suchen.'; + @override + String get scanner_connectFailedTransient => + 'The radio refused the connection (a common transient Bluetooth error). It was already retried; wait a few seconds and try again.'; + + @override + String get scanner_connectFailedTimeout => + 'The connection timed out. Check that the radio is powered, in range, and not already connected to another device.'; + + @override + String get scanner_connectFailedGeneric => + 'Could not connect to the radio. Details are in the App Debug Log.'; + @override String get scanner_bleReleaseWarning => 'Radio may still be held by this device'; diff --git a/lib/l10n/app_localizations_en.dart b/lib/l10n/app_localizations_en.dart index a048fec..29b507b 100644 --- a/lib/l10n/app_localizations_en.dart +++ b/lib/l10n/app_localizations_en.dart @@ -287,6 +287,18 @@ class AppLocalizationsEn extends AppLocalizations { String get scanner_bluetoothOffMessage => 'Please turn on Bluetooth to scan for devices'; + @override + String get scanner_connectFailedTransient => + 'The radio refused the connection (a common transient Bluetooth error). It was already retried; wait a few seconds and try again.'; + + @override + String get scanner_connectFailedTimeout => + 'The connection timed out. Check that the radio is powered, in range, and not already connected to another device.'; + + @override + String get scanner_connectFailedGeneric => + 'Could not connect to the radio. Details are in the App Debug Log.'; + @override String get scanner_bleReleaseWarning => 'Radio may still be held by this device'; diff --git a/lib/l10n/app_localizations_es.dart b/lib/l10n/app_localizations_es.dart index 3e89c4d..bbd42cc 100644 --- a/lib/l10n/app_localizations_es.dart +++ b/lib/l10n/app_localizations_es.dart @@ -291,6 +291,18 @@ class AppLocalizationsEs extends AppLocalizations { String get scanner_bluetoothOffMessage => 'Por favor, active el Bluetooth para escanear dispositivos.'; + @override + String get scanner_connectFailedTransient => + 'The radio refused the connection (a common transient Bluetooth error). It was already retried; wait a few seconds and try again.'; + + @override + String get scanner_connectFailedTimeout => + 'The connection timed out. Check that the radio is powered, in range, and not already connected to another device.'; + + @override + String get scanner_connectFailedGeneric => + 'Could not connect to the radio. Details are in the App Debug Log.'; + @override String get scanner_bleReleaseWarning => 'Radio may still be held by this device'; diff --git a/lib/l10n/app_localizations_fr.dart b/lib/l10n/app_localizations_fr.dart index 6fe1270..a7e24f4 100644 --- a/lib/l10n/app_localizations_fr.dart +++ b/lib/l10n/app_localizations_fr.dart @@ -293,6 +293,18 @@ class AppLocalizationsFr extends AppLocalizations { String get scanner_bluetoothOffMessage => 'Veuillez activer le Bluetooth pour rechercher des appareils.'; + @override + String get scanner_connectFailedTransient => + 'The radio refused the connection (a common transient Bluetooth error). It was already retried; wait a few seconds and try again.'; + + @override + String get scanner_connectFailedTimeout => + 'The connection timed out. Check that the radio is powered, in range, and not already connected to another device.'; + + @override + String get scanner_connectFailedGeneric => + 'Could not connect to the radio. Details are in the App Debug Log.'; + @override String get scanner_bleReleaseWarning => 'Radio may still be held by this device'; diff --git a/lib/l10n/app_localizations_hu.dart b/lib/l10n/app_localizations_hu.dart index 910e832..800ab40 100644 --- a/lib/l10n/app_localizations_hu.dart +++ b/lib/l10n/app_localizations_hu.dart @@ -290,6 +290,18 @@ class AppLocalizationsHu extends AppLocalizations { String get scanner_bluetoothOffMessage => 'Kérjük, kapcsolja be a Bluetooth-ot, hogy eszközök keresése lehessen.'; + @override + String get scanner_connectFailedTransient => + 'The radio refused the connection (a common transient Bluetooth error). It was already retried; wait a few seconds and try again.'; + + @override + String get scanner_connectFailedTimeout => + 'The connection timed out. Check that the radio is powered, in range, and not already connected to another device.'; + + @override + String get scanner_connectFailedGeneric => + 'Could not connect to the radio. Details are in the App Debug Log.'; + @override String get scanner_bleReleaseWarning => 'Radio may still be held by this device'; diff --git a/lib/l10n/app_localizations_it.dart b/lib/l10n/app_localizations_it.dart index fc49cd6..ded7e8a 100644 --- a/lib/l10n/app_localizations_it.dart +++ b/lib/l10n/app_localizations_it.dart @@ -293,6 +293,18 @@ class AppLocalizationsIt extends AppLocalizations { String get scanner_bluetoothOffMessage => 'Si prega di attivare il Bluetooth per effettuare la scansione dei dispositivi.'; + @override + String get scanner_connectFailedTransient => + 'The radio refused the connection (a common transient Bluetooth error). It was already retried; wait a few seconds and try again.'; + + @override + String get scanner_connectFailedTimeout => + 'The connection timed out. Check that the radio is powered, in range, and not already connected to another device.'; + + @override + String get scanner_connectFailedGeneric => + 'Could not connect to the radio. Details are in the App Debug Log.'; + @override String get scanner_bleReleaseWarning => 'Radio may still be held by this device'; diff --git a/lib/l10n/app_localizations_ja.dart b/lib/l10n/app_localizations_ja.dart index dff3789..c99d396 100644 --- a/lib/l10n/app_localizations_ja.dart +++ b/lib/l10n/app_localizations_ja.dart @@ -280,6 +280,18 @@ class AppLocalizationsJa extends AppLocalizations { @override String get scanner_bluetoothOffMessage => 'Bluetoothを有効にして、デバイスを検索してください。'; + @override + String get scanner_connectFailedTransient => + 'The radio refused the connection (a common transient Bluetooth error). It was already retried; wait a few seconds and try again.'; + + @override + String get scanner_connectFailedTimeout => + 'The connection timed out. Check that the radio is powered, in range, and not already connected to another device.'; + + @override + String get scanner_connectFailedGeneric => + 'Could not connect to the radio. Details are in the App Debug Log.'; + @override String get scanner_bleReleaseWarning => 'Radio may still be held by this device'; diff --git a/lib/l10n/app_localizations_ko.dart b/lib/l10n/app_localizations_ko.dart index 0cc0a70..e553a75 100644 --- a/lib/l10n/app_localizations_ko.dart +++ b/lib/l10n/app_localizations_ko.dart @@ -279,6 +279,18 @@ class AppLocalizationsKo extends AppLocalizations { @override String get scanner_bluetoothOffMessage => '블루투스를 켜서 장치를 검색해주세요.'; + @override + String get scanner_connectFailedTransient => + 'The radio refused the connection (a common transient Bluetooth error). It was already retried; wait a few seconds and try again.'; + + @override + String get scanner_connectFailedTimeout => + 'The connection timed out. Check that the radio is powered, in range, and not already connected to another device.'; + + @override + String get scanner_connectFailedGeneric => + 'Could not connect to the radio. Details are in the App Debug Log.'; + @override String get scanner_bleReleaseWarning => 'Radio may still be held by this device'; diff --git a/lib/l10n/app_localizations_nl.dart b/lib/l10n/app_localizations_nl.dart index 1aa66db..4c5ce45 100644 --- a/lib/l10n/app_localizations_nl.dart +++ b/lib/l10n/app_localizations_nl.dart @@ -289,6 +289,18 @@ class AppLocalizationsNl extends AppLocalizations { String get scanner_bluetoothOffMessage => 'Zorg ervoor dat Bluetooth is ingeschakeld om naar apparaten te zoeken.'; + @override + String get scanner_connectFailedTransient => + 'The radio refused the connection (a common transient Bluetooth error). It was already retried; wait a few seconds and try again.'; + + @override + String get scanner_connectFailedTimeout => + 'The connection timed out. Check that the radio is powered, in range, and not already connected to another device.'; + + @override + String get scanner_connectFailedGeneric => + 'Could not connect to the radio. Details are in the App Debug Log.'; + @override String get scanner_bleReleaseWarning => 'Radio may still be held by this device'; diff --git a/lib/l10n/app_localizations_pl.dart b/lib/l10n/app_localizations_pl.dart index d6db094..e4b7d67 100644 --- a/lib/l10n/app_localizations_pl.dart +++ b/lib/l10n/app_localizations_pl.dart @@ -294,6 +294,18 @@ class AppLocalizationsPl extends AppLocalizations { String get scanner_bluetoothOffMessage => 'Prosimy włączyć Bluetooth, aby przeskanować urządzenia.'; + @override + String get scanner_connectFailedTransient => + 'The radio refused the connection (a common transient Bluetooth error). It was already retried; wait a few seconds and try again.'; + + @override + String get scanner_connectFailedTimeout => + 'The connection timed out. Check that the radio is powered, in range, and not already connected to another device.'; + + @override + String get scanner_connectFailedGeneric => + 'Could not connect to the radio. Details are in the App Debug Log.'; + @override String get scanner_bleReleaseWarning => 'Radio may still be held by this device'; diff --git a/lib/l10n/app_localizations_pt.dart b/lib/l10n/app_localizations_pt.dart index b885e11..2dbc209 100644 --- a/lib/l10n/app_localizations_pt.dart +++ b/lib/l10n/app_localizations_pt.dart @@ -292,6 +292,18 @@ class AppLocalizationsPt extends AppLocalizations { String get scanner_bluetoothOffMessage => 'Por favor, ative o Bluetooth para escanear por dispositivos.'; + @override + String get scanner_connectFailedTransient => + 'The radio refused the connection (a common transient Bluetooth error). It was already retried; wait a few seconds and try again.'; + + @override + String get scanner_connectFailedTimeout => + 'The connection timed out. Check that the radio is powered, in range, and not already connected to another device.'; + + @override + String get scanner_connectFailedGeneric => + 'Could not connect to the radio. Details are in the App Debug Log.'; + @override String get scanner_bleReleaseWarning => 'Radio may still be held by this device'; diff --git a/lib/l10n/app_localizations_ru.dart b/lib/l10n/app_localizations_ru.dart index 61e266b..4da6d97 100644 --- a/lib/l10n/app_localizations_ru.dart +++ b/lib/l10n/app_localizations_ru.dart @@ -292,6 +292,18 @@ class AppLocalizationsRu extends AppLocalizations { String get scanner_bluetoothOffMessage => 'Пожалуйста, включите Bluetooth, чтобы найти устройства.'; + @override + String get scanner_connectFailedTransient => + 'The radio refused the connection (a common transient Bluetooth error). It was already retried; wait a few seconds and try again.'; + + @override + String get scanner_connectFailedTimeout => + 'The connection timed out. Check that the radio is powered, in range, and not already connected to another device.'; + + @override + String get scanner_connectFailedGeneric => + 'Could not connect to the radio. Details are in the App Debug Log.'; + @override String get scanner_bleReleaseWarning => 'Radio may still be held by this device'; diff --git a/lib/l10n/app_localizations_sk.dart b/lib/l10n/app_localizations_sk.dart index fcbc28c..8c287cd 100644 --- a/lib/l10n/app_localizations_sk.dart +++ b/lib/l10n/app_localizations_sk.dart @@ -291,6 +291,18 @@ class AppLocalizationsSk extends AppLocalizations { String get scanner_bluetoothOffMessage => 'Prosím, zapnite Bluetooth, aby ste mohli skenovať pre zariadenia.'; + @override + String get scanner_connectFailedTransient => + 'The radio refused the connection (a common transient Bluetooth error). It was already retried; wait a few seconds and try again.'; + + @override + String get scanner_connectFailedTimeout => + 'The connection timed out. Check that the radio is powered, in range, and not already connected to another device.'; + + @override + String get scanner_connectFailedGeneric => + 'Could not connect to the radio. Details are in the App Debug Log.'; + @override String get scanner_bleReleaseWarning => 'Radio may still be held by this device'; diff --git a/lib/l10n/app_localizations_sl.dart b/lib/l10n/app_localizations_sl.dart index 8193aa4..ac29adf 100644 --- a/lib/l10n/app_localizations_sl.dart +++ b/lib/l10n/app_localizations_sl.dart @@ -289,6 +289,18 @@ class AppLocalizationsSl extends AppLocalizations { String get scanner_bluetoothOffMessage => 'Prosimo, vklopite Bluetooth, da lahko poiščete naprave.'; + @override + String get scanner_connectFailedTransient => + 'The radio refused the connection (a common transient Bluetooth error). It was already retried; wait a few seconds and try again.'; + + @override + String get scanner_connectFailedTimeout => + 'The connection timed out. Check that the radio is powered, in range, and not already connected to another device.'; + + @override + String get scanner_connectFailedGeneric => + 'Could not connect to the radio. Details are in the App Debug Log.'; + @override String get scanner_bleReleaseWarning => 'Radio may still be held by this device'; diff --git a/lib/l10n/app_localizations_sv.dart b/lib/l10n/app_localizations_sv.dart index 8f344a2..08d73d0 100644 --- a/lib/l10n/app_localizations_sv.dart +++ b/lib/l10n/app_localizations_sv.dart @@ -288,6 +288,18 @@ class AppLocalizationsSv extends AppLocalizations { String get scanner_bluetoothOffMessage => 'Vänligen aktivera Bluetooth för att söka efter enheter.'; + @override + String get scanner_connectFailedTransient => + 'The radio refused the connection (a common transient Bluetooth error). It was already retried; wait a few seconds and try again.'; + + @override + String get scanner_connectFailedTimeout => + 'The connection timed out. Check that the radio is powered, in range, and not already connected to another device.'; + + @override + String get scanner_connectFailedGeneric => + 'Could not connect to the radio. Details are in the App Debug Log.'; + @override String get scanner_bleReleaseWarning => 'Radio may still be held by this device'; diff --git a/lib/l10n/app_localizations_uk.dart b/lib/l10n/app_localizations_uk.dart index 099f2a8..89f4b2b 100644 --- a/lib/l10n/app_localizations_uk.dart +++ b/lib/l10n/app_localizations_uk.dart @@ -291,6 +291,18 @@ class AppLocalizationsUk extends AppLocalizations { String get scanner_bluetoothOffMessage => 'Будь ласка, увімкніть Bluetooth, щоб сканувати пристрої.'; + @override + String get scanner_connectFailedTransient => + 'The radio refused the connection (a common transient Bluetooth error). It was already retried; wait a few seconds and try again.'; + + @override + String get scanner_connectFailedTimeout => + 'The connection timed out. Check that the radio is powered, in range, and not already connected to another device.'; + + @override + String get scanner_connectFailedGeneric => + 'Could not connect to the radio. Details are in the App Debug Log.'; + @override String get scanner_bleReleaseWarning => 'Radio may still be held by this device'; diff --git a/lib/l10n/app_localizations_zh.dart b/lib/l10n/app_localizations_zh.dart index a38da41..0e349d8 100644 --- a/lib/l10n/app_localizations_zh.dart +++ b/lib/l10n/app_localizations_zh.dart @@ -277,6 +277,18 @@ class AppLocalizationsZh extends AppLocalizations { @override String get scanner_bluetoothOffMessage => '请开启蓝牙以搜索设备'; + @override + String get scanner_connectFailedTransient => + 'The radio refused the connection (a common transient Bluetooth error). It was already retried; wait a few seconds and try again.'; + + @override + String get scanner_connectFailedTimeout => + 'The connection timed out. Check that the radio is powered, in range, and not already connected to another device.'; + + @override + String get scanner_connectFailedGeneric => + 'Could not connect to the radio. Details are in the App Debug Log.'; + @override String get scanner_bleReleaseWarning => 'Radio may still be held by this device'; diff --git a/lib/screens/scanner_screen.dart b/lib/screens/scanner_screen.dart index fa38279..359d8ee 100644 --- a/lib/screens/scanner_screen.dart +++ b/lib/screens/scanner_screen.dart @@ -346,16 +346,35 @@ class _ScannerScreenState extends State { ); return; } + // Never show a raw exception to the user (#522/#698): the full detail + // goes to the log, the snackbar gets a plain-language message and + // persists until dismissed. + appLogger.error('Connect failed: $e', tag: 'ScannerScreen'); if (context.mounted) { showDismissibleSnackBar( context, - content: Text(context.l10n.scanner_connectionFailed(e.toString())), + content: Text( + context.l10n.scanner_connectionFailed(_describeConnectError(e)), + ), backgroundColor: Colors.red, + persist: true, ); } } } + String _describeConnectError(Object e) { + final l10n = context.l10n; + if (e is FlutterBluePlusException && e.code == 133) { + return l10n.scanner_connectFailedTransient; + } + if (e is TimeoutException || + (e is FlutterBluePlusException && e.function == 'connect')) { + return l10n.scanner_connectFailedTimeout; + } + return l10n.scanner_connectFailedGeneric; + } + Future _promptLinuxPairingPin( BuildContext context, String deviceName, diff --git a/untranslated.json b/untranslated.json index 4bb1eba..a04e684 100644 --- a/untranslated.json +++ b/untranslated.json @@ -1,5 +1,8 @@ { "bg": [ + "scanner_connectFailedTransient", + "scanner_connectFailedTimeout", + "scanner_connectFailedGeneric", "scanner_bleReleaseWarning", "scanner_bleReleaseWarningMessage", "settings_messageSettings", @@ -203,6 +206,9 @@ ], "de": [ + "scanner_connectFailedTransient", + "scanner_connectFailedTimeout", + "scanner_connectFailedGeneric", "scanner_bleReleaseWarning", "scanner_bleReleaseWarningMessage", "settings_messageSettings", @@ -406,6 +412,9 @@ ], "es": [ + "scanner_connectFailedTransient", + "scanner_connectFailedTimeout", + "scanner_connectFailedGeneric", "scanner_bleReleaseWarning", "scanner_bleReleaseWarningMessage", "settings_messageSettings", @@ -609,6 +618,9 @@ ], "fr": [ + "scanner_connectFailedTransient", + "scanner_connectFailedTimeout", + "scanner_connectFailedGeneric", "scanner_bleReleaseWarning", "scanner_bleReleaseWarningMessage", "settings_messageSettings", @@ -812,6 +824,9 @@ ], "hu": [ + "scanner_connectFailedTransient", + "scanner_connectFailedTimeout", + "scanner_connectFailedGeneric", "scanner_bleReleaseWarning", "scanner_bleReleaseWarningMessage", "settings_messageSettings", @@ -1015,6 +1030,9 @@ ], "it": [ + "scanner_connectFailedTransient", + "scanner_connectFailedTimeout", + "scanner_connectFailedGeneric", "scanner_bleReleaseWarning", "scanner_bleReleaseWarningMessage", "settings_messageSettings", @@ -1218,6 +1236,9 @@ ], "ja": [ + "scanner_connectFailedTransient", + "scanner_connectFailedTimeout", + "scanner_connectFailedGeneric", "scanner_bleReleaseWarning", "scanner_bleReleaseWarningMessage", "settings_messageSettings", @@ -1421,6 +1442,9 @@ ], "ko": [ + "scanner_connectFailedTransient", + "scanner_connectFailedTimeout", + "scanner_connectFailedGeneric", "scanner_bleReleaseWarning", "scanner_bleReleaseWarningMessage", "settings_messageSettings", @@ -1624,6 +1648,9 @@ ], "nl": [ + "scanner_connectFailedTransient", + "scanner_connectFailedTimeout", + "scanner_connectFailedGeneric", "scanner_bleReleaseWarning", "scanner_bleReleaseWarningMessage", "settings_messageSettings", @@ -1827,6 +1854,9 @@ ], "pl": [ + "scanner_connectFailedTransient", + "scanner_connectFailedTimeout", + "scanner_connectFailedGeneric", "scanner_bleReleaseWarning", "scanner_bleReleaseWarningMessage", "settings_messageSettings", @@ -2030,6 +2060,9 @@ ], "pt": [ + "scanner_connectFailedTransient", + "scanner_connectFailedTimeout", + "scanner_connectFailedGeneric", "scanner_bleReleaseWarning", "scanner_bleReleaseWarningMessage", "settings_messageSettings", @@ -2233,6 +2266,9 @@ ], "ru": [ + "scanner_connectFailedTransient", + "scanner_connectFailedTimeout", + "scanner_connectFailedGeneric", "scanner_bleReleaseWarning", "scanner_bleReleaseWarningMessage", "settings_messageSettings", @@ -2436,6 +2472,9 @@ ], "sk": [ + "scanner_connectFailedTransient", + "scanner_connectFailedTimeout", + "scanner_connectFailedGeneric", "scanner_bleReleaseWarning", "scanner_bleReleaseWarningMessage", "settings_messageSettings", @@ -2639,6 +2678,9 @@ ], "sl": [ + "scanner_connectFailedTransient", + "scanner_connectFailedTimeout", + "scanner_connectFailedGeneric", "scanner_bleReleaseWarning", "scanner_bleReleaseWarningMessage", "settings_messageSettings", @@ -2842,6 +2884,9 @@ ], "sv": [ + "scanner_connectFailedTransient", + "scanner_connectFailedTimeout", + "scanner_connectFailedGeneric", "scanner_bleReleaseWarning", "scanner_bleReleaseWarningMessage", "settings_messageSettings", @@ -3045,6 +3090,9 @@ ], "uk": [ + "scanner_connectFailedTransient", + "scanner_connectFailedTimeout", + "scanner_connectFailedGeneric", "scanner_bleReleaseWarning", "scanner_bleReleaseWarningMessage", "settings_messageSettings", @@ -3248,6 +3296,9 @@ ], "zh": [ + "scanner_connectFailedTransient", + "scanner_connectFailedTimeout", + "scanner_connectFailedGeneric", "scanner_bleReleaseWarning", "scanner_bleReleaseWarningMessage", "settings_messageSettings",