1
0
mirror of https://codeberg.org/Freeyourgadget/Gadgetbridge synced 2024-11-03 17:02:13 +01:00

Fossil/Skagen Hybrids: Pair watch to phone, fixes repeating confirmation request

This commit is contained in:
Arjan Schrijver 2023-05-08 22:44:43 +02:00
parent e0d481bb36
commit f727f2fdcb
5 changed files with 91 additions and 5 deletions

View File

@ -10,6 +10,7 @@
* Amazfit GTR 4: Whitelist fw 3.18.1.1 diff from 3.17.0.2 * Amazfit GTR 4: Whitelist fw 3.18.1.1 diff from 3.17.0.2
* Amazfit GTS 2 Mini: Add missing alexa menu item * Amazfit GTS 2 Mini: Add missing alexa menu item
* Bangle.js: Fix updating timezone in settings.json if the timezone is zero * Bangle.js: Fix updating timezone in settings.json if the timezone is zero
* Fossil/Skagen Hybrids: Pair watch to phone, fixes repeating confirmation request
* Huami: Implement repeated activity fetching * Huami: Implement repeated activity fetching
* Sony WH-1000XM4: Add speak-to-chat * Sony WH-1000XM4: Add speak-to-chat
* Sony Headphones: Add button modes help * Sony Headphones: Add button modes help

View File

@ -122,7 +122,9 @@ import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.fos
import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.fossil_hr.application.ApplicationsListRequest; import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.fossil_hr.application.ApplicationsListRequest;
import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.fossil_hr.async.ConfirmAppStatusRequest; import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.fossil_hr.async.ConfirmAppStatusRequest;
import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.fossil_hr.authentication.CheckDeviceNeedsConfirmationRequest; import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.fossil_hr.authentication.CheckDeviceNeedsConfirmationRequest;
import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.fossil_hr.authentication.CheckDevicePairingRequest;
import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.fossil_hr.authentication.ConfirmOnDeviceRequest; import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.fossil_hr.authentication.ConfirmOnDeviceRequest;
import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.fossil_hr.authentication.PerformDevicePairingRequest;
import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.fossil_hr.authentication.VerifyPrivateKeyRequest; import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.fossil_hr.authentication.VerifyPrivateKeyRequest;
import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.fossil_hr.buttons.ButtonConfiguration; import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.fossil_hr.buttons.ButtonConfiguration;
import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.fossil_hr.buttons.ButtonConfigurationPutRequest; import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.fossil_hr.buttons.ButtonConfigurationPutRequest;
@ -269,7 +271,7 @@ public class FossilHRWatchAdapter extends FossilWatchAdapter {
} }
boolean shouldAuthenticateOnWatch = getDeviceSpecificPreferences().getBoolean("enable_on_device_confirmation", true); boolean shouldAuthenticateOnWatch = getDeviceSpecificPreferences().getBoolean("enable_on_device_confirmation", true);
if (!shouldAuthenticateOnWatch) { if (!shouldAuthenticateOnWatch) {
GB.toast("Skipping on-device confirmation", Toast.LENGTH_SHORT, GB.INFO); GB.toast(getContext().getString(R.string.fossil_hr_confirmation_skipped), Toast.LENGTH_SHORT, GB.INFO);
initializeAfterWatchConfirmation(false); initializeAfterWatchConfirmation(false);
return; return;
} }
@ -282,7 +284,7 @@ public class FossilHRWatchAdapter extends FossilWatchAdapter {
if (!(fossilRequest instanceof ConfirmOnDeviceRequest)) { if (!(fossilRequest instanceof ConfirmOnDeviceRequest)) {
return; return;
} }
GB.toast("Confirmation timeout, continuing", Toast.LENGTH_SHORT, GB.INFO); GB.toast(getContext().getString(R.string.fossil_hr_confirmation_timeout), Toast.LENGTH_SHORT, GB.INFO);
((ConfirmOnDeviceRequest) fossilRequest).onResult(false); ((ConfirmOnDeviceRequest) fossilRequest).onResult(false);
} }
}; };
@ -294,14 +296,16 @@ public class FossilHRWatchAdapter extends FossilWatchAdapter {
GB.log("needs confirmation: " + needsConfirmation, GB.INFO, null); GB.log("needs confirmation: " + needsConfirmation, GB.INFO, null);
if (needsConfirmation) { if (needsConfirmation) {
final Timer timer = new Timer(); final Timer timer = new Timer();
GB.toast("please confirm on device.", Toast.LENGTH_SHORT, GB.INFO); GB.toast(getContext().getString(R.string.fossil_hr_confirm_connection), Toast.LENGTH_SHORT, GB.INFO);
queueWrite(new ConfirmOnDeviceRequest() { queueWrite(new ConfirmOnDeviceRequest() {
@Override @Override
public void onResult(boolean confirmationSuccess) { public void onResult(boolean confirmationSuccess) {
isFinished = true; isFinished = true;
timer.cancel(); timer.cancel();
if (!confirmationSuccess) { if (confirmationSuccess) {
GB.toast("connection unconfirmed on watch, unauthenticated mode", Toast.LENGTH_LONG, GB.ERROR); pairToWatch();
} else {
GB.toast(getContext().getString(R.string.fossil_hr_connection_not_confirmed), Toast.LENGTH_LONG, GB.ERROR);
} }
initializeAfterWatchConfirmation(confirmationSuccess); initializeAfterWatchConfirmation(confirmationSuccess);
} }
@ -314,6 +318,29 @@ public class FossilHRWatchAdapter extends FossilWatchAdapter {
}); });
} }
private void pairToWatch() {
queueWrite(new CheckDevicePairingRequest() {
@Override
public void onResult(boolean pairingStatus) {
GB.log("watch pairing status: " + pairingStatus, GB.INFO, null);
if (!pairingStatus) {
queueWrite(new PerformDevicePairingRequest() {
@Override
public void onResult(boolean pairingSuccess) {
isFinished = true;
GB.log("watch pairing result: " + pairingSuccess, GB.INFO, null);
if (pairingSuccess) {
GB.toast(getContext().getString(R.string.fossil_hr_pairing_successful), Toast.LENGTH_LONG, GB.ERROR);
} else {
GB.toast(getContext().getString(R.string.fossil_hr_pairing_failed), Toast.LENGTH_LONG, GB.ERROR);
}
}
}, true);
}
}
});
}
private void respondToAlexa(String message, boolean isResponse){ private void respondToAlexa(String message, boolean isResponse){
queueWrite(new AlexaMessageSetRequest(message, isResponse, this)); queueWrite(new AlexaMessageSetRequest(message, isResponse, this));
} }

View File

@ -0,0 +1,44 @@
package nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.fossil_hr.authentication;
import android.bluetooth.BluetoothGattCharacteristic;
import java.util.UUID;
import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.fossil.FossilRequest;
public class CheckDevicePairingRequest extends FossilRequest {
protected boolean isFinished = false;
@Override
public byte[] getStartSequence() {
return new byte[]{0x01, 0x16};
}
@Override
public void handleResponse(BluetoothGattCharacteristic characteristic) {
if(!characteristic.getUuid().equals(getRequestUUID())){
throw new RuntimeException("wrong characteristic responded to pairing");
}
byte[] value = characteristic.getValue();
if(value.length != 3){
throw new RuntimeException("wrong pairing response length");
}
if(value[0] != 0x03 || value[1] != 0x16){
throw new RuntimeException("wrong pairing response bytes");
}
this.onResult(value[2] == 0x01);
this.isFinished = true;
}
public void onResult(boolean confirmationSuccess){};
@Override
public boolean isFinished() {
return isFinished;
}
@Override
public UUID getRequestUUID() {
return UUID.fromString("3dda0002-957f-7d4a-34a6-74696673696d");
}
}

View File

@ -0,0 +1,8 @@
package nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.fossil_hr.authentication;
public class PerformDevicePairingRequest extends CheckDevicePairingRequest {
@Override
public byte[] getStartSequence() {
return new byte[]{0x02, 0x16};
}
}

View File

@ -2083,4 +2083,10 @@
<string name="ftp_server_root_dir">Root Directory</string> <string name="ftp_server_root_dir">Root Directory</string>
<string name="address">Address</string> <string name="address">Address</string>
<string name="username">Username</string> <string name="username">Username</string>
<string name="fossil_hr_confirm_connection">Please confirm on your watch</string>
<string name="fossil_hr_connection_not_confirmed">Connection not confirmed on watch, using unauthenticated mode</string>
<string name="fossil_hr_pairing_successful">Pairing with watch successful</string>
<string name="fossil_hr_pairing_failed">Pairing with watch failed</string>
<string name="fossil_hr_confirmation_skipped">Skipping on-device confirmation</string>
<string name="fossil_hr_confirmation_timeout">Confirmation timeout, continuing</string>
</resources> </resources>