mirror of
https://codeberg.org/Freeyourgadget/Gadgetbridge
synced 2024-11-28 21:06:50 +01:00
added abstraction layer
This commit is contained in:
parent
93726f9e37
commit
187600b076
@ -4,10 +4,10 @@ import android.util.Log;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.PlayNotificationRequest;
|
||||
import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.misfit.PlayNotificationRequest;
|
||||
|
||||
public class PackageConfig implements Serializable {
|
||||
private short min, hour;
|
||||
private short min, hour, activity = -1;
|
||||
private String packageName, appName;
|
||||
private PlayNotificationRequest.VibrationType vibration;
|
||||
private boolean respectSilentMode;
|
||||
@ -22,6 +22,13 @@ public class PackageConfig implements Serializable {
|
||||
this.vibration = vibration;
|
||||
}
|
||||
|
||||
public PackageConfig(short min, short hour, short activity, PlayNotificationRequest.VibrationType vibration) {
|
||||
this.min = min;
|
||||
this.hour = hour;
|
||||
this.activity = activity;
|
||||
this.vibration = vibration;
|
||||
}
|
||||
|
||||
PackageConfig(short min, short hour, String packageName, String appName, boolean respectSilentMode, PlayNotificationRequest.VibrationType vibration, long id) {
|
||||
this.min = min;
|
||||
this.hour = hour;
|
||||
@ -90,6 +97,14 @@ public class PackageConfig implements Serializable {
|
||||
return hour;
|
||||
}
|
||||
|
||||
public short getActivity() {
|
||||
return activity;
|
||||
}
|
||||
|
||||
public void setActivity(short activity) {
|
||||
this.activity = activity;
|
||||
}
|
||||
|
||||
public String getPackageName() {
|
||||
return packageName;
|
||||
}
|
||||
|
@ -9,7 +9,7 @@ import android.util.Log;
|
||||
import java.util.ArrayList;
|
||||
|
||||
import nodomain.freeyourgadget.gadgetbridge.database.DBOpenHelper;
|
||||
import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.PlayNotificationRequest;
|
||||
import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.misfit.PlayNotificationRequest;
|
||||
|
||||
public class PackageConfigHelper extends DBOpenHelper {
|
||||
public static final String DB_NAME = "qhybridNotifications.db";
|
||||
|
@ -12,7 +12,7 @@ import com.twofortyfouram.locale.sdk.client.ui.activity.AbstractPluginActivity;
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
import nodomain.freeyourgadget.gadgetbridge.R;
|
||||
import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.PlayNotificationRequest;
|
||||
import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.misfit.PlayNotificationRequest;
|
||||
|
||||
public class TaskerPluginActivity extends AbstractPluginActivity {
|
||||
public static final String key_hours = "qhybrid_hours";
|
||||
|
@ -6,7 +6,7 @@ import android.content.Intent;
|
||||
|
||||
import androidx.localbroadcastmanager.content.LocalBroadcastManager;
|
||||
import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.QHybridSupport;
|
||||
import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.PlayNotificationRequest;
|
||||
import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.misfit.PlayNotificationRequest;
|
||||
|
||||
public class TaskerPluginReceiver extends BroadcastReceiver {
|
||||
|
||||
|
@ -1,7 +1,6 @@
|
||||
package nodomain.freeyourgadget.gadgetbridge.devices.qhybrid;
|
||||
|
||||
import android.app.AlertDialog;
|
||||
import android.content.ContentValues;
|
||||
import android.content.Context;
|
||||
import android.content.DialogInterface;
|
||||
import android.content.pm.PackageInfo;
|
||||
@ -22,7 +21,7 @@ import android.widget.RadioGroup;
|
||||
import android.widget.ScrollView;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.PlayNotificationRequest;
|
||||
import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.misfit.PlayNotificationRequest;
|
||||
|
||||
public class TimePicker extends AlertDialog.Builder {
|
||||
ImageView pickerView;
|
||||
|
@ -44,31 +44,33 @@ import nodomain.freeyourgadget.gadgetbridge.model.NotificationSpec;
|
||||
import nodomain.freeyourgadget.gadgetbridge.model.RecordedDataTypes;
|
||||
import nodomain.freeyourgadget.gadgetbridge.service.btle.TransactionBuilder;
|
||||
import nodomain.freeyourgadget.gadgetbridge.service.btle.actions.SetDeviceStateAction;
|
||||
import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.ActivityPointGetRequest;
|
||||
import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.AnimationRequest;
|
||||
import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.BatteryLevelRequest;
|
||||
import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.DownloadFileRequest;
|
||||
import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.EraseFileRequest;
|
||||
import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.FileRequest;
|
||||
import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.GetCountdownSettingsRequest;
|
||||
import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.GetCurrentStepCountRequest;
|
||||
import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.GetStepGoalRequest;
|
||||
import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.GetVibrationStrengthRequest;
|
||||
import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.GoalTrackingGetRequest;
|
||||
import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.ListFilesRequest;
|
||||
import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.MoveHandsRequest;
|
||||
import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.OTAEnterRequest;
|
||||
import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.OTAEraseRequest;
|
||||
import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.PlayNotificationRequest;
|
||||
import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.ReleaseHandsControlRequest;
|
||||
import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.Request;
|
||||
import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.RequestHandControlRequest;
|
||||
import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.SetCurrentStepCountRequest;
|
||||
import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.SetStepGoalRequest;
|
||||
import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.SetTimeRequest;
|
||||
import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.SetVibrationStrengthRequest;
|
||||
import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.UploadFileRequest;
|
||||
import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.VibrateRequest;
|
||||
import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.adapter.WatchAdapter;
|
||||
import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.adapter.WatchAdapterFactory;
|
||||
import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.misfit.ActivityPointGetRequest;
|
||||
import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.misfit.AnimationRequest;
|
||||
import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.misfit.BatteryLevelRequest;
|
||||
import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.misfit.DownloadFileRequest;
|
||||
import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.misfit.EraseFileRequest;
|
||||
import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.misfit.FileRequest;
|
||||
import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.misfit.GetCountdownSettingsRequest;
|
||||
import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.misfit.GetCurrentStepCountRequest;
|
||||
import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.misfit.GetStepGoalRequest;
|
||||
import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.misfit.GetVibrationStrengthRequest;
|
||||
import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.misfit.GoalTrackingGetRequest;
|
||||
import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.misfit.ListFilesRequest;
|
||||
import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.misfit.MoveHandsRequest;
|
||||
import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.misfit.OTAEnterRequest;
|
||||
import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.misfit.OTAEraseRequest;
|
||||
import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.misfit.PlayNotificationRequest;
|
||||
import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.misfit.ReleaseHandsControlRequest;
|
||||
import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.misfit.Request;
|
||||
import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.misfit.RequestHandControlRequest;
|
||||
import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.misfit.SetCurrentStepCountRequest;
|
||||
import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.misfit.SetStepGoalRequest;
|
||||
import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.misfit.SetTimeRequest;
|
||||
import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.misfit.SetVibrationStrengthRequest;
|
||||
import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.misfit.UploadFileRequest;
|
||||
import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.misfit.VibrateRequest;
|
||||
import nodomain.freeyourgadget.gadgetbridge.util.GB;
|
||||
|
||||
public class QHybridSupport extends QHybridBaseSupport {
|
||||
@ -102,22 +104,14 @@ public class QHybridSupport extends QHybridBaseSupport {
|
||||
|
||||
private volatile boolean searchDevice = false;
|
||||
|
||||
private int lastButtonIndex = -1;
|
||||
|
||||
private final SparseArray<Request> responseFilters = new SparseArray<>();
|
||||
|
||||
private Request fileRequest = null;
|
||||
|
||||
private long timeOffset;
|
||||
|
||||
private UploadFileRequest uploadFileRequest;
|
||||
|
||||
private Queue<Request> requestQueue = new ArrayDeque<>();
|
||||
|
||||
private String modelNumber;
|
||||
|
||||
private boolean useActivityHand;
|
||||
|
||||
WatchAdapter watchAdapter;
|
||||
|
||||
public QHybridSupport() {
|
||||
super(logger);
|
||||
addSupportedService(UUID.fromString("3dda0001-957f-7d4a-34a6-74696673696d"));
|
||||
@ -133,7 +127,6 @@ public class QHybridSupport extends QHybridBaseSupport {
|
||||
commandFilter.addAction(QHYBRID_COMMAND_UPDATE_SETTINGS);
|
||||
commandFilter.addAction(QHYBRID_COMMAND_OVERWRITE_BUTTONS);
|
||||
LocalBroadcastManager.getInstance(getContext()).registerReceiver(commandReceiver, commandFilter);
|
||||
fillResponseList();
|
||||
|
||||
helper = new PackageConfigHelper(GBApplication.getContext());
|
||||
|
||||
@ -162,48 +155,10 @@ public class QHybridSupport extends QHybridBaseSupport {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
private void fillResponseList() {
|
||||
Class<? extends Request>[] classes = new Class[]{
|
||||
BatteryLevelRequest.class,
|
||||
GetStepGoalRequest.class,
|
||||
GetVibrationStrengthRequest.class,
|
||||
GetCurrentStepCountRequest.class,
|
||||
OTAEnterRequest.class,
|
||||
GoalTrackingGetRequest.class,
|
||||
ActivityPointGetRequest.class,
|
||||
GetCountdownSettingsRequest.class
|
||||
};
|
||||
for (Class<? extends Request> c : classes) {
|
||||
try {
|
||||
c.getSuperclass().getDeclaredMethod("handleResponse", BluetoothGattCharacteristic.class);
|
||||
Request object = c.newInstance();
|
||||
byte[] sequence = object.getStartSequence();
|
||||
if (sequence.length > 1) {
|
||||
responseFilters.put((int) object.getStartSequence()[1], object);
|
||||
Log.d("Service", "response filter " + object.getStartSequence()[1] + ": " + c.getSimpleName());
|
||||
}
|
||||
} catch (NoSuchMethodException | IllegalAccessException | InstantiationException e) {
|
||||
Log.d("Service", "skipping class " + c.getName());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void getTimeOffset() {
|
||||
timeOffset = getContext().getSharedPreferences(getContext().getPackageName(), Context.MODE_PRIVATE).getInt("QHYBRID_TIME_OFFSET", 0);
|
||||
}
|
||||
|
||||
private void queueWrite(Request request) {
|
||||
new TransactionBuilder(request.getClass().getSimpleName()).write(getCharacteristic(request.getRequestUUID()), request.getRequestData()).queue(getQueue());
|
||||
if (request instanceof FileRequest) this.fileRequest = request;
|
||||
|
||||
if (!request.expectsResponse()) {
|
||||
try {
|
||||
queueWrite(requestQueue.remove());
|
||||
} catch (NoSuchElementException e) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected TransactionBuilder initializeDevice(TransactionBuilder builder) {
|
||||
builder.add(new SetDeviceStateAction(getDevice(), GBDevice.State.INITIALIZING, getContext()));
|
||||
@ -217,43 +172,34 @@ public class QHybridSupport extends QHybridBaseSupport {
|
||||
for (int i = 2; i <= 7; i++)
|
||||
builder.notify(getCharacteristic(UUID.fromString("3dda000" + i + "-957f-7d4a-34a6-74696673696d")), true);
|
||||
|
||||
requestQueue.add(new GetCurrentStepCountRequest());
|
||||
requestQueue.add(new GetVibrationStrengthRequest());
|
||||
requestQueue.add(new ActivityPointGetRequest());
|
||||
requestQueue.add(prepareSetTimeRequest());
|
||||
requestQueue.add(new AnimationRequest());
|
||||
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
|
||||
requestQueue.add(new SetCurrentStepCountRequest((int) (999999 * calculateNotificationProgress())));
|
||||
} else {
|
||||
requestQueue.add(new SetCurrentStepCountRequest(0));
|
||||
}
|
||||
|
||||
Request initialRequest = new GetStepGoalRequest();
|
||||
|
||||
builder
|
||||
// .read(getCharacteristic(UUID.fromString("00002a00-0000-1000-8000-00805f9b34fb")))
|
||||
.read(getCharacteristic(UUID.fromString("00002a24-0000-1000-8000-00805f9b34fb")))
|
||||
// .read(getCharacteristic(UUID.fromString("00002a24-0000-1000-8000-00805f9b34fb")))
|
||||
.read(getCharacteristic(UUID.fromString("00002a26-0000-1000-8000-00805f9b34fb")))
|
||||
.read(getCharacteristic(UUID.fromString("00002a19-0000-1000-8000-00805f9b34fb")))
|
||||
.notify(getCharacteristic(UUID.fromString("00002a19-0000-1000-8000-00805f9b34fb")), true)
|
||||
.write(getCharacteristic(initialRequest.getRequestUUID()), initialRequest.getRequestData());
|
||||
// .read(getCharacteristic(UUID.fromString("00002a19-0000-1000-8000-00805f9b34fb")))
|
||||
// .notify(getCharacteristic(UUID.fromString("00002a19-0000-1000-8000-00805f9b34fb")), true)
|
||||
// .write(getCharacteristic(initialRequest.getRequestUUID()), initialRequest.getRequestData())
|
||||
;
|
||||
|
||||
getTimeOffset();
|
||||
|
||||
builder.add(new SetDeviceStateAction(getDevice(), GBDevice.State.INITIALIZED, getContext()));
|
||||
// builder.add(new SetDeviceStateAction(getDevice(), GBDevice.State.INITIALIZED, getContext()));
|
||||
|
||||
return builder;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onFetchRecordedData(int dataTypes) {
|
||||
if ((dataTypes & RecordedDataTypes.TYPE_ACTIVITY) != 0) {
|
||||
//TODO
|
||||
/* if ((dataTypes & RecordedDataTypes.TYPE_ACTIVITY) != 0) {
|
||||
requestQueue.add(new BatteryLevelRequest());
|
||||
requestQueue.add(new GetCurrentStepCountRequest());
|
||||
requestQueue.add(new ListFilesRequest());
|
||||
queueWrite(new ActivityPointGetRequest());
|
||||
}
|
||||
} */
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -287,19 +233,18 @@ public class QHybridSupport extends QHybridBaseSupport {
|
||||
}
|
||||
|
||||
private void showNotificationsByAllActive(boolean enforceByNotification) {
|
||||
if(!this.useActivityHand);
|
||||
if (!this.useActivityHand) ;
|
||||
double progress = calculateNotificationProgress();
|
||||
showNotificationCountOnActivityHand(progress);
|
||||
|
||||
if(enforceByNotification){
|
||||
queueWrite(
|
||||
new PlayNotificationRequest(
|
||||
PlayNotificationRequest.VibrationType.NO_VIBE,
|
||||
-1,
|
||||
-1,
|
||||
(int) (progress * 180)
|
||||
)
|
||||
);
|
||||
if (enforceByNotification) {
|
||||
watchAdapter.playNotification(new PackageConfig(
|
||||
(short) -1,
|
||||
(short) -1,
|
||||
//TODO test activity hand
|
||||
(short) (progress * 180),
|
||||
PlayNotificationRequest.VibrationType.NO_VIBE
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
@ -314,7 +259,7 @@ public class QHybridSupport extends QHybridBaseSupport {
|
||||
|
||||
for (String notificationPackage : NotificationListener.notificationStack) {
|
||||
for (PackageConfig packageConfig : configs.keySet()) {
|
||||
if(configs.get(packageConfig)) continue;
|
||||
if (configs.get(packageConfig)) continue;
|
||||
if (packageConfig.getPackageName().equals(notificationPackage)) {
|
||||
notificationProgress += 0.25;
|
||||
configs.put(packageConfig, true);
|
||||
@ -327,27 +272,19 @@ public class QHybridSupport extends QHybridBaseSupport {
|
||||
|
||||
private void showNotificationCountOnActivityHand(double progress) {
|
||||
if (useActivityHand) {
|
||||
setActivityHand(progress);
|
||||
watchAdapter.setActivityHand(progress);
|
||||
}
|
||||
}
|
||||
|
||||
private void playNotification(PackageConfig config) {
|
||||
if(config.getMin() == -1 && config.getHour() == -1 && config.getVibration() == PlayNotificationRequest.VibrationType.NO_VIBE) return;
|
||||
queueWrite(new PlayNotificationRequest(config.getVibration(), config.getHour(), config.getMin()));
|
||||
if (config.getMin() == -1 && config.getHour() == -1 && config.getVibration() == PlayNotificationRequest.VibrationType.NO_VIBE)
|
||||
return;
|
||||
watchAdapter.playNotification(config);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSetTime() {
|
||||
queueWrite(prepareSetTimeRequest());
|
||||
}
|
||||
|
||||
private SetTimeRequest prepareSetTimeRequest() {
|
||||
long millis = System.currentTimeMillis();
|
||||
TimeZone zone = new GregorianCalendar().getTimeZone();
|
||||
return new SetTimeRequest(
|
||||
(int) (millis / 1000 + timeOffset * 60),
|
||||
(short) (millis % 1000),
|
||||
(short) ((zone.getRawOffset() + zone.getDSTSavings()) / 60000));
|
||||
watchAdapter.setTime();
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -387,27 +324,7 @@ public class QHybridSupport extends QHybridBaseSupport {
|
||||
|
||||
@Override
|
||||
public void onTestNewFunction() {
|
||||
float random = (float)Math.random();
|
||||
setActivityHand(random);
|
||||
queueWrite(
|
||||
new PlayNotificationRequest(
|
||||
PlayNotificationRequest.VibrationType.NO_VIBE,
|
||||
-1,
|
||||
-1,
|
||||
(int) (random * 180)
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
private void overwriteButtons() {
|
||||
uploadFileRequest = new UploadFileRequest((short) 0x0800, new byte[]{
|
||||
(byte) 0x01, (byte) 0x00, (byte) 0x00, (byte) 0x03, (byte) 0x10, (byte) 0x01, (byte) 0x01, (byte) 0x01, (byte) 0x0C, (byte) 0x00, (byte) 0x00, (byte) 0x20, (byte) 0x01, (byte) 0x01, (byte) 0x01, (byte) 0x0C, (byte) 0x00, (byte) 0x00,
|
||||
(byte) 0x30, (byte) 0x01, (byte) 0x01, (byte) 0x01, (byte) 0x0C, (byte) 0x00, (byte) 0x00, (byte) 0x01, (byte) 0x01, (byte) 0x00, (byte) 0x01, (byte) 0x01, (byte) 0x0C, (byte) 0x2E, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x01,
|
||||
(byte) 0x00, (byte) 0x06, (byte) 0x00, (byte) 0x01, (byte) 0x01, (byte) 0x01, (byte) 0x03, (byte) 0x00, (byte) 0x02, (byte) 0x01, (byte) 0x0F, (byte) 0x00, (byte) 0x8B, (byte) 0x00, (byte) 0x00, (byte) 0x93, (byte) 0x00, (byte) 0x01,
|
||||
(byte) 0x08, (byte) 0x01, (byte) 0x14, (byte) 0x00, (byte) 0x01, (byte) 0x00, (byte) 0xFE, (byte) 0x08, (byte) 0x00, (byte) 0x93, (byte) 0x00, (byte) 0x02, (byte) 0x01, (byte) 0x00, (byte) 0xBF, (byte) 0xD5, (byte) 0x54, (byte) 0xD1,
|
||||
(byte) 0x00
|
||||
});
|
||||
queueWrite(uploadFileRequest);
|
||||
}
|
||||
|
||||
private void backupFile(DownloadFileRequest request) {
|
||||
@ -430,21 +347,29 @@ public class QHybridSupport extends QHybridBaseSupport {
|
||||
fos2.write(("file " + request.timeStamp + " cut\n\n").getBytes());
|
||||
fos2.close();
|
||||
|
||||
queueWrite(new EraseFileRequest((short) request.fileHandle));
|
||||
//TODO file stuff
|
||||
// queueWrite(new EraseFileRequest((short) request.fileHandle));
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
if (request.fileHandle > 257) {
|
||||
queueWrite(new DownloadFileRequest((short) (request.fileHandle - 1)));
|
||||
// queueWrite(new DownloadFileRequest((short) (request.fileHandle - 1)));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handleGBDeviceEvent(GBDeviceEventBatteryInfo deviceEvent){
|
||||
super.handleGBDeviceEvent(deviceEvent);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onCharacteristicRead(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic, int status) {
|
||||
switch (characteristic.getUuid().toString()) {
|
||||
case "00002a00-0000-1000-8000-00805f9b34fb": {
|
||||
String deviceName = characteristic.getStringValue(0);
|
||||
case "00002a26-0000-1000-8000-00805f9b34fb": {
|
||||
String firmwareVersion = characteristic.getStringValue(0);
|
||||
|
||||
gbDevice.setFirmwareVersion(firmwareVersion);
|
||||
this.watchAdapter = new WatchAdapterFactory().createWatchAdapter(firmwareVersion, this);
|
||||
break;
|
||||
}
|
||||
case "00002a24-0000-1000-8000-00805f9b34fb": {
|
||||
@ -460,14 +385,6 @@ public class QHybridSupport extends QHybridBaseSupport {
|
||||
}
|
||||
break;
|
||||
}
|
||||
case "00002a26-0000-1000-8000-00805f9b34fb": {
|
||||
String firmwareVersion = characteristic.getStringValue(0);
|
||||
gbDevice.setFirmwareVersion(firmwareVersion);
|
||||
|
||||
checkFirmwareVersion(firmwareVersion);
|
||||
|
||||
break;
|
||||
}
|
||||
case "00002a19-0000-1000-8000-00805f9b34fb": {
|
||||
short level = characteristic.getValue()[0];
|
||||
gbDevice.setBatteryLevel(level);
|
||||
@ -479,6 +396,7 @@ public class QHybridSupport extends QHybridBaseSupport {
|
||||
batteryInfo.state = BatteryState.BATTERY_NORMAL;
|
||||
handleGBDeviceEvent(batteryInfo);
|
||||
break;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@ -495,231 +413,10 @@ public class QHybridSupport extends QHybridBaseSupport {
|
||||
return "unknwon Q";
|
||||
}
|
||||
|
||||
private void checkFirmwareVersion(String firmwareVersion) {
|
||||
if (!isFirmwareCompatible(firmwareVersion)) {
|
||||
GB.toast("Firmware " + firmwareVersion + " not compatible", Toast.LENGTH_LONG, GB.ERROR);
|
||||
getDevice().setName("incopatible firmware");
|
||||
}
|
||||
}
|
||||
|
||||
private boolean isFirmwareCompatible(String firmwareVersion) {
|
||||
int major = Integer.parseInt(firmwareVersion.substring(6, 7));
|
||||
|
||||
return major == 1;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onCharacteristicChanged(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic) {
|
||||
switch (characteristic.getUuid().toString()) {
|
||||
case "3dda0004-957f-7d4a-34a6-74696673696d":
|
||||
case "3dda0003-957f-7d4a-34a6-74696673696d": {
|
||||
return handleFileDownloadCharacteristic(characteristic);
|
||||
}
|
||||
case "3dda0007-957f-7d4a-34a6-74696673696d": {
|
||||
return handleFileUploadCharacteristic(characteristic);
|
||||
}
|
||||
case "3dda0002-957f-7d4a-34a6-74696673696d": {
|
||||
return handleBasicCharacteristic(characteristic);
|
||||
}
|
||||
case "3dda0006-957f-7d4a-34a6-74696673696d": {
|
||||
return handleButtonCharacteristic(characteristic);
|
||||
}
|
||||
case "00002a19-0000-1000-8000-00805f9b34fb": {
|
||||
short level = characteristic.getValue()[0];
|
||||
gbDevice.setBatteryLevel(level);
|
||||
|
||||
gbDevice.setBatteryThresholdPercent((short) 2);
|
||||
|
||||
GBDeviceEventBatteryInfo batteryInfo = new GBDeviceEventBatteryInfo();
|
||||
batteryInfo.level = gbDevice.getBatteryLevel();
|
||||
batteryInfo.state = BatteryState.BATTERY_NORMAL;
|
||||
handleGBDeviceEvent(batteryInfo);
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
Log.d("Service", "unknown shit on " + characteristic.getUuid().toString() + ": " + arrayToString(characteristic.getValue()));
|
||||
try {
|
||||
File charLog = new File("/sdcard/qFiles/charLog.txt");
|
||||
if (!charLog.exists()) {
|
||||
charLog.createNewFile();
|
||||
}
|
||||
|
||||
FileOutputStream fos = new FileOutputStream(charLog, true);
|
||||
fos.write((new Date().toString() + ": " + characteristic.getUuid().toString() + ": " + arrayToString(characteristic.getValue())).getBytes());
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
return super.onCharacteristicChanged(gatt, characteristic);
|
||||
}
|
||||
|
||||
private void setActivityHand(double progress) {
|
||||
queueWrite(new SetCurrentStepCountRequest(Math.min((int) (1000000 * progress), 999999)));
|
||||
}
|
||||
|
||||
private boolean handleFileUploadCharacteristic(BluetoothGattCharacteristic characteristic) {
|
||||
if (uploadFileRequest == null) {
|
||||
logger.debug("no uploadFileRequest to handle response");
|
||||
return true;
|
||||
}
|
||||
|
||||
uploadFileRequest.handleResponse(characteristic);
|
||||
|
||||
switch (uploadFileRequest.state) {
|
||||
case ERROR:
|
||||
Intent fileIntent = new Intent(QHYBRID_EVENT_FILE_UPLOADED);
|
||||
fileIntent.putExtra("EXTRA_ERROR", true);
|
||||
LocalBroadcastManager.getInstance(getContext()).sendBroadcast(fileIntent);
|
||||
uploadFileRequest = null;
|
||||
break;
|
||||
case UPLOAD:
|
||||
for (byte[] packet : this.uploadFileRequest.packets) {
|
||||
new TransactionBuilder("File upload").write(characteristic, packet).queue(getQueue());
|
||||
}
|
||||
break;
|
||||
case UPLOADED:
|
||||
fileIntent = new Intent(QHYBRID_EVENT_FILE_UPLOADED);
|
||||
LocalBroadcastManager.getInstance(getContext()).sendBroadcast(fileIntent);
|
||||
uploadFileRequest = null;
|
||||
break;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
private boolean handleButtonCharacteristic(BluetoothGattCharacteristic characteristic) {
|
||||
byte[] value = characteristic.getValue();
|
||||
if (value.length != 11) {
|
||||
logger.debug("wrong button message");
|
||||
return true;
|
||||
}
|
||||
int index = value[6] & 0xFF;
|
||||
int button = value[8] >> 4 & 0xFF;
|
||||
|
||||
if (index != this.lastButtonIndex) {
|
||||
lastButtonIndex = index;
|
||||
logger.debug("Button press on button " + button);
|
||||
|
||||
Intent i = new Intent(QHYBRID_EVENT_BUTTON_PRESS);
|
||||
i.putExtra("BUTTON", button);
|
||||
|
||||
//ByteBuffer buffer = ByteBuffer.allocate(16);
|
||||
//buffer.put(new byte[]{0x01, 0x00, 0x08});
|
||||
//buffer.put(value, 2, 8);
|
||||
//buffer.put(new byte[]{(byte)0xFF, 0x05, 0x00, 0x01, 0x00});
|
||||
|
||||
//UploadFileRequest request = new UploadFileRequest((short)0, buffer.array());
|
||||
//for(byte[] packet : request.packets){
|
||||
// new TransactionBuilder("File upload").write(getCharacteristic(UUID.fromString("3dda0007-957f-7d4a-34a6-74696673696d")), packet).queue(getQueue());
|
||||
//}
|
||||
|
||||
getContext().sendBroadcast(i);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
private boolean handleBasicCharacteristic(BluetoothGattCharacteristic characteristic) {
|
||||
byte[] values = characteristic.getValue();
|
||||
Request request = resolveAnswer(characteristic);
|
||||
|
||||
if (request == null) {
|
||||
StringBuilder valueString = new StringBuilder(String.valueOf(values[0]));
|
||||
for (int i = 1; i < characteristic.getValue().length; i++) {
|
||||
valueString.append(", ").append(values[i]);
|
||||
}
|
||||
Log.d("Service", "unable to resolve " + characteristic.getUuid().toString() + ": " + valueString);
|
||||
return true;
|
||||
}
|
||||
Log.d("Service", "response: " + request.getClass().getSimpleName());
|
||||
request.handleResponse(characteristic);
|
||||
|
||||
if (request instanceof GetStepGoalRequest) {
|
||||
gbDevice.addDeviceInfo(new GenericItem(ITEM_STEP_GOAL, String.valueOf(((GetStepGoalRequest) request).stepGoal)));
|
||||
} else if (request instanceof GetVibrationStrengthRequest) {
|
||||
int strength = ((GetVibrationStrengthRequest) request).strength;
|
||||
gbDevice.addDeviceInfo(new GenericItem(ITEM_VIBRATION_STRENGTH, String.valueOf(strength)));
|
||||
} else if (request instanceof GetCurrentStepCountRequest) {
|
||||
int steps = ((GetCurrentStepCountRequest) request).steps;
|
||||
logger.debug("get current steps: " + steps);
|
||||
try {
|
||||
File f = new File("/sdcard/qFiles/");
|
||||
if (!f.exists()) f.mkdir();
|
||||
|
||||
File file = new File("/sdcard/qFiles/steps");
|
||||
if (!file.exists()) {
|
||||
file.createNewFile();
|
||||
}
|
||||
logger.debug("Writing file " + file.getPath());
|
||||
FileOutputStream fos = new FileOutputStream(file, true);
|
||||
fos.write((System.currentTimeMillis() + ": " + steps + "\n").getBytes());
|
||||
fos.close();
|
||||
logger.debug("file written.");
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
gbDevice.addDeviceInfo(new GenericItem(ITEM_STEP_COUNT, String.valueOf(((GetCurrentStepCountRequest) request).steps)));
|
||||
} else if (request instanceof OTAEnterRequest) {
|
||||
if (((OTAEnterRequest) request).success) {
|
||||
fileRequest = new OTAEraseRequest(1024 << 16);
|
||||
queueWrite(fileRequest);
|
||||
}
|
||||
} else if (request instanceof ActivityPointGetRequest) {
|
||||
gbDevice.addDeviceInfo(new GenericItem(ITEM_ACTIVITY_POINT, String.valueOf(((ActivityPointGetRequest) request).activityPoint)));
|
||||
}
|
||||
try {
|
||||
queueWrite(requestQueue.remove());
|
||||
} catch (NoSuchElementException e) {
|
||||
}
|
||||
LocalBroadcastManager.getInstance(getContext()).sendBroadcast(new Intent(DeviceManager.ACTION_DEVICES_CHANGED));
|
||||
return true;
|
||||
}
|
||||
|
||||
private boolean handleFileDownloadCharacteristic(BluetoothGattCharacteristic characteristic) {
|
||||
Request request;
|
||||
request = fileRequest;
|
||||
request.handleResponse(characteristic);
|
||||
if (request instanceof ListFilesRequest) {
|
||||
if (((ListFilesRequest) request).completed) {
|
||||
logger.debug("File count: " + ((ListFilesRequest) request).fileCount + " size: " + ((ListFilesRequest) request).size);
|
||||
if (((ListFilesRequest) request).fileCount == 0) return true;
|
||||
// queueWrite(new DownloadFileRequest((short) (256 + ((ListFilesRequest) request).fileCount)));
|
||||
}
|
||||
} else if (request instanceof DownloadFileRequest) {
|
||||
if (((FileRequest) request).completed) {
|
||||
logger.debug("file " + ((DownloadFileRequest) request).fileHandle + " completed: " + ((DownloadFileRequest) request).size);
|
||||
backupFile((DownloadFileRequest) request);
|
||||
}
|
||||
} else if (request instanceof EraseFileRequest) {
|
||||
if (((EraseFileRequest) request).fileHandle > 257) {
|
||||
queueWrite(new DownloadFileRequest((short) (((EraseFileRequest) request).fileHandle - 1)));
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
private String arrayToString(byte[] bytes) {
|
||||
if (bytes.length == 0) return "";
|
||||
StringBuilder s = new StringBuilder();
|
||||
final String chars = "0123456789ABCDEF";
|
||||
for (byte b : bytes) {
|
||||
s.append(chars.charAt((b >> 4) & 0xF)).append(chars.charAt(b & 0xF)).append(" ");
|
||||
}
|
||||
return s.substring(0, s.length() - 1) + "\n";
|
||||
}
|
||||
|
||||
private Request resolveAnswer(BluetoothGattCharacteristic characteristic) {
|
||||
byte[] values = characteristic.getValue();
|
||||
if (values[0] != 3) return null;
|
||||
return responseFilters.get(values[1]);
|
||||
}
|
||||
|
||||
private void setHands(short hour, short minute) {
|
||||
queueWrite(new MoveHandsRequest(false, minute, hour, (short) -1));
|
||||
}
|
||||
|
||||
private void vibrate(PlayNotificationRequest.VibrationType vibration) {
|
||||
queueWrite(new PlayNotificationRequest(vibration, -1, -1));
|
||||
public boolean onCharacteristicChanged(BluetoothGatt gatt, BluetoothGattCharacteristic
|
||||
characteristic) {
|
||||
return watchAdapter.onCharacteristicChanged(gatt, characteristic);
|
||||
}
|
||||
|
||||
private final BroadcastReceiver globalCommandReceiver = new BroadcastReceiver() {
|
||||
@ -730,16 +427,14 @@ public class QHybridSupport extends QHybridBaseSupport {
|
||||
try {
|
||||
Object extra = intent.getExtras().get("EXTRA_PROGRESS");
|
||||
float progress = (float) extra;
|
||||
setActivityHand(progress);
|
||||
watchAdapter.setActivityHand(progress);
|
||||
|
||||
queueWrite(
|
||||
new PlayNotificationRequest(
|
||||
PlayNotificationRequest.VibrationType.NO_VIBE,
|
||||
-1,
|
||||
-1,
|
||||
(int) (progress * 180)
|
||||
)
|
||||
);
|
||||
watchAdapter.playNotification(new PackageConfig(
|
||||
(short) -1,
|
||||
(short) -1,
|
||||
(short) (progress * 180),
|
||||
PlayNotificationRequest.VibrationType.NO_VIBE
|
||||
));
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
logger.debug("trash extra should be number 0.0-1.0");
|
||||
@ -759,29 +454,29 @@ public class QHybridSupport extends QHybridBaseSupport {
|
||||
switch (intent.getAction()) {
|
||||
case QHYBRID_COMMAND_CONTROL: {
|
||||
Log.d("Service", "sending control request");
|
||||
queueWrite(new RequestHandControlRequest());
|
||||
watchAdapter.requestHandsControl();
|
||||
if (config != null) {
|
||||
setHands(config.getHour(), config.getMin());
|
||||
watchAdapter.setHands(config.getHour(), config.getMin());
|
||||
} else {
|
||||
setHands((short) 0, (short) 0);
|
||||
watchAdapter.setHands((short) 0, (short) 0);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case QHYBRID_COMMAND_UNCONTROL: {
|
||||
queueWrite(new ReleaseHandsControlRequest());
|
||||
watchAdapter.releaseHandsControl();
|
||||
break;
|
||||
}
|
||||
case QHYBRID_COMMAND_SET: {
|
||||
setHands(config.getHour(), config.getMin());
|
||||
watchAdapter.setHands(config.getHour(), config.getMin());
|
||||
|
||||
break;
|
||||
}
|
||||
case QHYBRID_COMMAND_VIBRATE: {
|
||||
vibrate(config.getVibration());
|
||||
watchAdapter.vibrate(config.getVibration());
|
||||
break;
|
||||
}
|
||||
case QHYBRID_COMMAND_NOTIFICATION: {
|
||||
queueWrite(new PlayNotificationRequest(config.getVibration(), config.getHour(), config.getMin()));
|
||||
watchAdapter.playNotification(config);
|
||||
break;
|
||||
}
|
||||
case QHYBRID_COMMAND_UPDATE: {
|
||||
@ -793,12 +488,12 @@ public class QHybridSupport extends QHybridBaseSupport {
|
||||
String newSetting = intent.getStringExtra("EXTRA_SETTING");
|
||||
switch (newSetting) {
|
||||
case ITEM_VIBRATION_STRENGTH: {
|
||||
queueWrite(new SetVibrationStrengthRequest(Short.parseShort(gbDevice.getDeviceInfo(ITEM_VIBRATION_STRENGTH).getDetails())));
|
||||
watchAdapter.setVibrationStrength(Short.parseShort(gbDevice.getDeviceInfo(ITEM_VIBRATION_STRENGTH).getDetails()));
|
||||
// queueWrite(new VibrateRequest(false, (short)4, (short)1));
|
||||
break;
|
||||
}
|
||||
case ITEM_STEP_GOAL: {
|
||||
queueWrite(new SetStepGoalRequest(Integer.parseInt(gbDevice.getDeviceInfo(ITEM_STEP_GOAL).getDetails())));
|
||||
watchAdapter.setStepGoal(Integer.parseInt(gbDevice.getDeviceInfo(ITEM_STEP_GOAL).getDetails()));
|
||||
break;
|
||||
}
|
||||
case ITEM_USE_ACTIVITY_HAND: {
|
||||
@ -812,7 +507,7 @@ public class QHybridSupport extends QHybridBaseSupport {
|
||||
break;
|
||||
}
|
||||
case QHYBRID_COMMAND_OVERWRITE_BUTTONS: {
|
||||
overwriteButtons();
|
||||
watchAdapter.overwriteButtons();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,46 @@
|
||||
package nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.adapter;
|
||||
|
||||
import android.bluetooth.BluetoothGatt;
|
||||
import android.bluetooth.BluetoothGattCharacteristic;
|
||||
import android.content.Context;
|
||||
|
||||
import nodomain.freeyourgadget.gadgetbridge.devices.qhybrid.PackageConfig;
|
||||
import nodomain.freeyourgadget.gadgetbridge.service.DeviceSupport;
|
||||
import nodomain.freeyourgadget.gadgetbridge.service.btle.AbstractBTLEDeviceSupport;
|
||||
import nodomain.freeyourgadget.gadgetbridge.service.btle.TransactionBuilder;
|
||||
import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.QHybridSupport;
|
||||
import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.adapter.misfit.MisfitWatchAdapter;
|
||||
import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.misfit.PlayNotificationRequest;
|
||||
|
||||
public abstract class WatchAdapter {
|
||||
private QHybridSupport deviceSupport;
|
||||
|
||||
public WatchAdapter(QHybridSupport deviceSupport){
|
||||
this.deviceSupport = deviceSupport;
|
||||
}
|
||||
|
||||
protected QHybridSupport getDeviceSupport(){
|
||||
return this.deviceSupport;
|
||||
}
|
||||
|
||||
protected Context getContext(){
|
||||
return getDeviceSupport().getContext();
|
||||
}
|
||||
|
||||
public abstract void initialize();
|
||||
|
||||
public abstract void playPairingAnimation();
|
||||
public abstract void playNotification(PackageConfig config);
|
||||
public abstract void setTime();
|
||||
public abstract void overwriteButtons();
|
||||
public abstract void setActivityHand(double progress);
|
||||
public abstract void setHands(short hour, short minute);
|
||||
public abstract void vibrate(PlayNotificationRequest.VibrationType vibration);
|
||||
public abstract void requestHandsControl();
|
||||
public abstract void releaseHandsControl();
|
||||
public abstract void setStepGoal(int stepGoal);
|
||||
public abstract void setVibrationStrength(short strength);
|
||||
|
||||
public abstract boolean onCharacteristicChanged(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic);
|
||||
|
||||
}
|
@ -0,0 +1,16 @@
|
||||
package nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.adapter;
|
||||
|
||||
import nodomain.freeyourgadget.gadgetbridge.service.btle.AbstractBTLEDeviceSupport;
|
||||
import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.QHybridSupport;
|
||||
import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.adapter.misfit.MisfitWatchAdapter;
|
||||
|
||||
public final class WatchAdapterFactory {
|
||||
public final WatchAdapter createWatchAdapter(String firmwareVersion, QHybridSupport deviceSupport){
|
||||
char major = firmwareVersion.charAt(6);
|
||||
switch (major){
|
||||
case 'a': return new MisfitWatchAdapter(deviceSupport);
|
||||
}
|
||||
|
||||
throw new UnsupportedOperationException("Firmware " + firmwareVersion + " not supported");
|
||||
}
|
||||
}
|
@ -0,0 +1,419 @@
|
||||
package nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.adapter.misfit;
|
||||
|
||||
import android.bluetooth.BluetoothGatt;
|
||||
import android.bluetooth.BluetoothGattCharacteristic;
|
||||
import android.content.Intent;
|
||||
import android.os.Build;
|
||||
import android.util.Log;
|
||||
import android.util.SparseArray;
|
||||
import android.widget.Toast;
|
||||
|
||||
import androidx.localbroadcastmanager.content.LocalBroadcastManager;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayDeque;
|
||||
import java.util.Date;
|
||||
import java.util.GregorianCalendar;
|
||||
import java.util.NoSuchElementException;
|
||||
import java.util.Queue;
|
||||
import java.util.TimeZone;
|
||||
|
||||
import nodomain.freeyourgadget.gadgetbridge.deviceevents.GBDeviceEventBatteryInfo;
|
||||
import nodomain.freeyourgadget.gadgetbridge.devices.DeviceManager;
|
||||
import nodomain.freeyourgadget.gadgetbridge.devices.qhybrid.PackageConfig;
|
||||
import nodomain.freeyourgadget.gadgetbridge.impl.GBDevice;
|
||||
import nodomain.freeyourgadget.gadgetbridge.model.BatteryState;
|
||||
import nodomain.freeyourgadget.gadgetbridge.model.GenericItem;
|
||||
import nodomain.freeyourgadget.gadgetbridge.service.DeviceSupport;
|
||||
import nodomain.freeyourgadget.gadgetbridge.service.btle.AbstractBTLEDeviceSupport;
|
||||
import nodomain.freeyourgadget.gadgetbridge.service.btle.TransactionBuilder;
|
||||
import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.QHybridSupport;
|
||||
import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.adapter.WatchAdapter;
|
||||
import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.misfit.ActivityPointGetRequest;
|
||||
import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.misfit.AnimationRequest;
|
||||
import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.misfit.BatteryLevelRequest;
|
||||
import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.misfit.DownloadFileRequest;
|
||||
import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.misfit.EraseFileRequest;
|
||||
import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.misfit.FileRequest;
|
||||
import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.misfit.GetCountdownSettingsRequest;
|
||||
import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.misfit.GetCurrentStepCountRequest;
|
||||
import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.misfit.GetStepGoalRequest;
|
||||
import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.misfit.GetVibrationStrengthRequest;
|
||||
import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.misfit.GoalTrackingGetRequest;
|
||||
import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.misfit.ListFilesRequest;
|
||||
import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.misfit.MoveHandsRequest;
|
||||
import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.misfit.OTAEnterRequest;
|
||||
import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.misfit.OTAEraseRequest;
|
||||
import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.misfit.PlayNotificationRequest;
|
||||
import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.misfit.ReleaseHandsControlRequest;
|
||||
import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.misfit.Request;
|
||||
import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.misfit.RequestHandControlRequest;
|
||||
import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.misfit.SetCurrentStepCountRequest;
|
||||
import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.misfit.SetStepGoalRequest;
|
||||
import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.misfit.SetTimeRequest;
|
||||
import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.misfit.SetVibrationStrengthRequest;
|
||||
import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.misfit.UploadFileRequest;
|
||||
import nodomain.freeyourgadget.gadgetbridge.util.GB;
|
||||
|
||||
import static nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.QHybridSupport.ITEM_ACTIVITY_POINT;
|
||||
import static nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.QHybridSupport.ITEM_STEP_COUNT;
|
||||
import static nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.QHybridSupport.ITEM_STEP_GOAL;
|
||||
import static nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.QHybridSupport.ITEM_VIBRATION_STRENGTH;
|
||||
import static nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.QHybridSupport.QHYBRID_EVENT_BUTTON_PRESS;
|
||||
import static nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.QHybridSupport.QHYBRID_EVENT_FILE_UPLOADED;
|
||||
|
||||
public class MisfitWatchAdapter extends WatchAdapter {
|
||||
private int lastButtonIndex = -1;
|
||||
private final SparseArray<Request> responseFilters = new SparseArray<>();
|
||||
private static final Logger logger = LoggerFactory.getLogger(QHybridSupport.class);
|
||||
|
||||
private UploadFileRequest uploadFileRequest;
|
||||
private Request fileRequest = null;
|
||||
|
||||
private Queue<Request> requestQueue = new ArrayDeque<>();
|
||||
|
||||
public MisfitWatchAdapter(QHybridSupport deviceSupport) {
|
||||
super(deviceSupport);
|
||||
|
||||
fillResponseList();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void initialize() {
|
||||
requestQueue.add(new GetCurrentStepCountRequest());
|
||||
requestQueue.add(new GetVibrationStrengthRequest());
|
||||
requestQueue.add(new ActivityPointGetRequest());
|
||||
requestQueue.add(prepareSetTimeRequest());
|
||||
requestQueue.add(new AnimationRequest());
|
||||
|
||||
//TODO
|
||||
// requestQueue.add(new SetCurrentStepCountRequest((int) (999999 * calculateNotificationProgress())));
|
||||
}
|
||||
|
||||
|
||||
private SetTimeRequest prepareSetTimeRequest() {
|
||||
long millis = System.currentTimeMillis();
|
||||
TimeZone zone = new GregorianCalendar().getTimeZone();
|
||||
return new SetTimeRequest(
|
||||
//TODO time offset
|
||||
(int) (millis / 1000 + 0 * 60),
|
||||
(short) (millis % 1000),
|
||||
(short) ((zone.getRawOffset() + zone.getDSTSavings()) / 60000));
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void playPairingAnimation() {
|
||||
queueWrite(new AnimationRequest());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void playNotification(PackageConfig config) {
|
||||
queueWrite(new PlayNotificationRequest(
|
||||
config.getVibration(),
|
||||
config.getHour(),
|
||||
config.getMin()
|
||||
));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setTime() {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onCharacteristicChanged(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic) {
|
||||
GBDevice gbDevice = getDeviceSupport().getDevice();
|
||||
switch (characteristic.getUuid().toString()) {
|
||||
case "3dda0004-957f-7d4a-34a6-74696673696d":
|
||||
case "3dda0003-957f-7d4a-34a6-74696673696d": {
|
||||
return handleFileDownloadCharacteristic(characteristic);
|
||||
}
|
||||
case "3dda0007-957f-7d4a-34a6-74696673696d": {
|
||||
return handleFileUploadCharacteristic(characteristic);
|
||||
}
|
||||
case "3dda0002-957f-7d4a-34a6-74696673696d": {
|
||||
return handleBasicCharacteristic(characteristic);
|
||||
}
|
||||
case "3dda0006-957f-7d4a-34a6-74696673696d": {
|
||||
return handleButtonCharacteristic(characteristic);
|
||||
}
|
||||
case "00002a19-0000-1000-8000-00805f9b34fb": {
|
||||
short level = characteristic.getValue()[0];
|
||||
gbDevice.setBatteryLevel(level);
|
||||
|
||||
gbDevice.setBatteryThresholdPercent((short) 2);
|
||||
|
||||
GBDeviceEventBatteryInfo batteryInfo = new GBDeviceEventBatteryInfo();
|
||||
batteryInfo.level = gbDevice.getBatteryLevel();
|
||||
batteryInfo.state = BatteryState.BATTERY_NORMAL;
|
||||
getDeviceSupport().handleGBDeviceEvent(batteryInfo);
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
Log.d("Service", "unknown shit on " + characteristic.getUuid().toString() + ": " + arrayToString(characteristic.getValue()));
|
||||
try {
|
||||
File charLog = new File("/sdcard/qFiles/charLog.txt");
|
||||
if (!charLog.exists()) {
|
||||
charLog.createNewFile();
|
||||
}
|
||||
|
||||
FileOutputStream fos = new FileOutputStream(charLog, true);
|
||||
fos.write((new Date().toString() + ": " + characteristic.getUuid().toString() + ": " + arrayToString(characteristic.getValue())).getBytes());
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
return getDeviceSupport().onCharacteristicChanged(gatt, characteristic);
|
||||
}
|
||||
|
||||
private String arrayToString(byte[] bytes) {
|
||||
if (bytes.length == 0) return "";
|
||||
StringBuilder s = new StringBuilder();
|
||||
final String chars = "0123456789ABCDEF";
|
||||
for (byte b : bytes) {
|
||||
s.append(chars.charAt((b >> 4) & 0xF)).append(chars.charAt(b & 0xF)).append(" ");
|
||||
}
|
||||
return s.substring(0, s.length() - 1) + "\n";
|
||||
}
|
||||
|
||||
private void fillResponseList() {
|
||||
Class<? extends Request>[] classes = new Class[]{
|
||||
BatteryLevelRequest.class,
|
||||
GetStepGoalRequest.class,
|
||||
GetVibrationStrengthRequest.class,
|
||||
GetCurrentStepCountRequest.class,
|
||||
OTAEnterRequest.class,
|
||||
GoalTrackingGetRequest.class,
|
||||
ActivityPointGetRequest.class,
|
||||
GetCountdownSettingsRequest.class
|
||||
};
|
||||
for (Class<? extends Request> c : classes) {
|
||||
try {
|
||||
c.getSuperclass().getDeclaredMethod("handleResponse", BluetoothGattCharacteristic.class);
|
||||
Request object = c.newInstance();
|
||||
byte[] sequence = object.getStartSequence();
|
||||
if (sequence.length > 1) {
|
||||
responseFilters.put((int) object.getStartSequence()[1], object);
|
||||
Log.d("Service", "response filter " + object.getStartSequence()[1] + ": " + c.getSimpleName());
|
||||
}
|
||||
} catch (NoSuchMethodException | IllegalAccessException | InstantiationException e) {
|
||||
Log.d("Service", "skipping class " + c.getName());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private boolean handleBasicCharacteristic(BluetoothGattCharacteristic characteristic) {
|
||||
byte[] values = characteristic.getValue();
|
||||
Request request = resolveAnswer(characteristic);
|
||||
GBDevice gbDevice = getDeviceSupport().getDevice();
|
||||
|
||||
if (request == null) {
|
||||
StringBuilder valueString = new StringBuilder(String.valueOf(values[0]));
|
||||
for (int i = 1; i < characteristic.getValue().length; i++) {
|
||||
valueString.append(", ").append(values[i]);
|
||||
}
|
||||
Log.d("Service", "unable to resolve " + characteristic.getUuid().toString() + ": " + valueString);
|
||||
return true;
|
||||
}
|
||||
Log.d("Service", "response: " + request.getClass().getSimpleName());
|
||||
request.handleResponse(characteristic);
|
||||
|
||||
if (request instanceof GetStepGoalRequest) {
|
||||
gbDevice.addDeviceInfo(new GenericItem(ITEM_STEP_GOAL, String.valueOf(((GetStepGoalRequest) request).stepGoal)));
|
||||
} else if (request instanceof GetVibrationStrengthRequest) {
|
||||
int strength = ((GetVibrationStrengthRequest) request).strength;
|
||||
gbDevice.addDeviceInfo(new GenericItem(ITEM_VIBRATION_STRENGTH, String.valueOf(strength)));
|
||||
} else if (request instanceof GetCurrentStepCountRequest) {
|
||||
int steps = ((GetCurrentStepCountRequest) request).steps;
|
||||
logger.debug("get current steps: " + steps);
|
||||
try {
|
||||
File f = new File("/sdcard/qFiles/");
|
||||
if (!f.exists()) f.mkdir();
|
||||
|
||||
File file = new File("/sdcard/qFiles/steps");
|
||||
if (!file.exists()) {
|
||||
file.createNewFile();
|
||||
}
|
||||
logger.debug("Writing file " + file.getPath());
|
||||
FileOutputStream fos = new FileOutputStream(file, true);
|
||||
fos.write((System.currentTimeMillis() + ": " + steps + "\n").getBytes());
|
||||
fos.close();
|
||||
logger.debug("file written.");
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
gbDevice.addDeviceInfo(new GenericItem(ITEM_STEP_COUNT, String.valueOf(((GetCurrentStepCountRequest) request).steps)));
|
||||
} else if (request instanceof OTAEnterRequest) {
|
||||
if (((OTAEnterRequest) request).success) {
|
||||
fileRequest = new OTAEraseRequest(1024 << 16);
|
||||
queueWrite(fileRequest);
|
||||
}
|
||||
} else if (request instanceof ActivityPointGetRequest) {
|
||||
gbDevice.addDeviceInfo(new GenericItem(ITEM_ACTIVITY_POINT, String.valueOf(((ActivityPointGetRequest) request).activityPoint)));
|
||||
}
|
||||
try {
|
||||
queueWrite(requestQueue.remove());
|
||||
} catch (NoSuchElementException e) {
|
||||
}
|
||||
LocalBroadcastManager.getInstance(getContext()).sendBroadcast(new Intent(DeviceManager.ACTION_DEVICES_CHANGED));
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
private Request resolveAnswer(BluetoothGattCharacteristic characteristic) {
|
||||
byte[] values = characteristic.getValue();
|
||||
if (values[0] != 3) return null;
|
||||
return responseFilters.get(values[1]);
|
||||
}
|
||||
|
||||
private boolean handleFileDownloadCharacteristic(BluetoothGattCharacteristic characteristic) {
|
||||
Request request;
|
||||
request = fileRequest;
|
||||
request.handleResponse(characteristic);
|
||||
if (request instanceof ListFilesRequest) {
|
||||
if (((ListFilesRequest) request).completed) {
|
||||
logger.debug("File count: " + ((ListFilesRequest) request).fileCount + " size: " + ((ListFilesRequest) request).size);
|
||||
if (((ListFilesRequest) request).fileCount == 0) return true;
|
||||
// queueWrite(new DownloadFileRequest((short) (256 + ((ListFilesRequest) request).fileCount)));
|
||||
}
|
||||
} else if (request instanceof DownloadFileRequest) {
|
||||
if (((FileRequest) request).completed) {
|
||||
logger.debug("file " + ((DownloadFileRequest) request).fileHandle + " completed: " + ((DownloadFileRequest) request).size);
|
||||
// backupFile((DownloadFileRequest) request);
|
||||
}
|
||||
} else if (request instanceof EraseFileRequest) {
|
||||
if (((EraseFileRequest) request).fileHandle > 257) {
|
||||
queueWrite(new DownloadFileRequest((short) (((EraseFileRequest) request).fileHandle - 1)));
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
private boolean handleFileUploadCharacteristic(BluetoothGattCharacteristic characteristic) {
|
||||
if (uploadFileRequest == null) {
|
||||
logger.debug("no uploadFileRequest to handle response");
|
||||
return true;
|
||||
}
|
||||
|
||||
uploadFileRequest.handleResponse(characteristic);
|
||||
|
||||
switch (uploadFileRequest.state) {
|
||||
case ERROR:
|
||||
Intent fileIntent = new Intent(QHYBRID_EVENT_FILE_UPLOADED);
|
||||
fileIntent.putExtra("EXTRA_ERROR", true);
|
||||
LocalBroadcastManager.getInstance(getContext()).sendBroadcast(fileIntent);
|
||||
uploadFileRequest = null;
|
||||
break;
|
||||
case UPLOAD:
|
||||
for (byte[] packet : this.uploadFileRequest.packets) {
|
||||
new TransactionBuilder("File upload").write(characteristic, packet).queue(getDeviceSupport().getQueue());
|
||||
}
|
||||
break;
|
||||
case UPLOADED:
|
||||
fileIntent = new Intent(QHYBRID_EVENT_FILE_UPLOADED);
|
||||
LocalBroadcastManager.getInstance(getContext()).sendBroadcast(fileIntent);
|
||||
uploadFileRequest = null;
|
||||
break;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
private boolean handleButtonCharacteristic(BluetoothGattCharacteristic characteristic) {
|
||||
byte[] value = characteristic.getValue();
|
||||
if (value.length != 11) {
|
||||
logger.debug("wrong button message");
|
||||
return true;
|
||||
}
|
||||
int index = value[6] & 0xFF;
|
||||
int button = value[8] >> 4 & 0xFF;
|
||||
|
||||
if (index != this.lastButtonIndex) {
|
||||
lastButtonIndex = index;
|
||||
logger.debug("Button press on button " + button);
|
||||
|
||||
Intent i = new Intent(QHYBRID_EVENT_BUTTON_PRESS);
|
||||
i.putExtra("BUTTON", button);
|
||||
|
||||
//ByteBuffer buffer = ByteBuffer.allocate(16);
|
||||
//buffer.put(new byte[]{0x01, 0x00, 0x08});
|
||||
//buffer.put(value, 2, 8);
|
||||
//buffer.put(new byte[]{(byte)0xFF, 0x05, 0x00, 0x01, 0x00});
|
||||
|
||||
//UploadFileRequest request = new UploadFileRequest((short)0, buffer.array());
|
||||
//for(byte[] packet : request.packets){
|
||||
// new TransactionBuilder("File upload").write(getCharacteristic(UUID.fromString("3dda0007-957f-7d4a-34a6-74696673696d")), packet).queue(getQueue());
|
||||
//}
|
||||
|
||||
getContext().sendBroadcast(i);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
public void setActivityHand(double progress) {
|
||||
queueWrite(new SetCurrentStepCountRequest(Math.min((int) (1000000 * progress), 999999)));
|
||||
}
|
||||
|
||||
|
||||
public void setHands(short hour, short minute) {
|
||||
queueWrite(new MoveHandsRequest(false, minute, hour, (short) -1));
|
||||
}
|
||||
|
||||
public void vibrate(PlayNotificationRequest.VibrationType vibration) {
|
||||
queueWrite(new PlayNotificationRequest(vibration, -1, -1));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void requestHandsControl() {
|
||||
queueWrite(new RequestHandControlRequest());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void releaseHandsControl() {
|
||||
queueWrite(new ReleaseHandsControlRequest());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setStepGoal(int stepGoal) {
|
||||
queueWrite(new SetStepGoalRequest(stepGoal));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setVibrationStrength(short strength) {
|
||||
queueWrite(new SetVibrationStrengthRequest(strength));
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void overwriteButtons() {
|
||||
uploadFileRequest = new UploadFileRequest((short) 0x0800, new byte[]{
|
||||
(byte) 0x01, (byte) 0x00, (byte) 0x00, (byte) 0x03, (byte) 0x10, (byte) 0x01, (byte) 0x01, (byte) 0x01, (byte) 0x0C, (byte) 0x00, (byte) 0x00, (byte) 0x20, (byte) 0x01, (byte) 0x01, (byte) 0x01, (byte) 0x0C, (byte) 0x00, (byte) 0x00,
|
||||
(byte) 0x30, (byte) 0x01, (byte) 0x01, (byte) 0x01, (byte) 0x0C, (byte) 0x00, (byte) 0x00, (byte) 0x01, (byte) 0x01, (byte) 0x00, (byte) 0x01, (byte) 0x01, (byte) 0x0C, (byte) 0x2E, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x01,
|
||||
(byte) 0x00, (byte) 0x06, (byte) 0x00, (byte) 0x01, (byte) 0x01, (byte) 0x01, (byte) 0x03, (byte) 0x00, (byte) 0x02, (byte) 0x01, (byte) 0x0F, (byte) 0x00, (byte) 0x8B, (byte) 0x00, (byte) 0x00, (byte) 0x93, (byte) 0x00, (byte) 0x01,
|
||||
(byte) 0x08, (byte) 0x01, (byte) 0x14, (byte) 0x00, (byte) 0x01, (byte) 0x00, (byte) 0xFE, (byte) 0x08, (byte) 0x00, (byte) 0x93, (byte) 0x00, (byte) 0x02, (byte) 0x01, (byte) 0x00, (byte) 0xBF, (byte) 0xD5, (byte) 0x54, (byte) 0xD1,
|
||||
(byte) 0x00
|
||||
});
|
||||
queueWrite(uploadFileRequest);
|
||||
}
|
||||
|
||||
private void queueWrite(Request request) {
|
||||
new TransactionBuilder(request.getClass().getSimpleName()).write(getDeviceSupport().getCharacteristic(request.getRequestUUID()), request.getRequestData()).queue(getDeviceSupport().getQueue());
|
||||
// if (request instanceof FileRequest) this.fileRequest = request;
|
||||
|
||||
if (!request.expectsResponse()) {
|
||||
try {
|
||||
queueWrite(requestQueue.remove());
|
||||
} catch (NoSuchElementException e) {
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -1,4 +1,4 @@
|
||||
package nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests;
|
||||
package nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.misfit;
|
||||
|
||||
import android.bluetooth.BluetoothGattCharacteristic;
|
||||
|
@ -1,4 +1,4 @@
|
||||
package nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests;
|
||||
package nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.misfit;
|
||||
|
||||
public class AnimationRequest extends Request{
|
||||
@Override
|
@ -1,4 +1,4 @@
|
||||
package nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests;
|
||||
package nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.misfit;
|
||||
|
||||
import android.bluetooth.BluetoothGattCharacteristic;
|
||||
|
@ -1,10 +1,9 @@
|
||||
package nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests;
|
||||
package nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.misfit;
|
||||
|
||||
import android.bluetooth.BluetoothGattCharacteristic;
|
||||
|
||||
import java.nio.ByteBuffer;
|
||||
import java.nio.ByteOrder;
|
||||
import java.util.UUID;
|
||||
import java.util.zip.CRC32;
|
||||
|
||||
public class DownloadFileRequest extends FileRequest {
|
@ -1,11 +1,10 @@
|
||||
package nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests;
|
||||
package nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.misfit;
|
||||
|
||||
import android.bluetooth.BluetoothGattCharacteristic;
|
||||
import android.util.Log;
|
||||
|
||||
import java.nio.ByteBuffer;
|
||||
import java.nio.ByteOrder;
|
||||
import java.util.UUID;
|
||||
|
||||
public class EraseFileRequest extends FileRequest{
|
||||
public short fileHandle, deletedHandle;
|
@ -1,4 +1,4 @@
|
||||
package nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests;
|
||||
package nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.misfit;
|
||||
|
||||
import java.nio.ByteBuffer;
|
||||
import java.util.UUID;
|
@ -1,4 +1,4 @@
|
||||
package nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests;
|
||||
package nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.misfit;
|
||||
|
||||
import java.util.UUID;
|
||||
|
@ -1,4 +1,4 @@
|
||||
package nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests;
|
||||
package nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.misfit;
|
||||
|
||||
import android.bluetooth.BluetoothGattCharacteristic;
|
||||
import android.util.Log;
|
@ -1,4 +1,4 @@
|
||||
package nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests;
|
||||
package nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.misfit;
|
||||
|
||||
import android.bluetooth.BluetoothGattCharacteristic;
|
||||
|
@ -1,4 +1,4 @@
|
||||
package nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests;
|
||||
package nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.misfit;
|
||||
|
||||
import android.bluetooth.BluetoothGattCharacteristic;
|
||||
|
@ -1,4 +1,4 @@
|
||||
package nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests;
|
||||
package nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.misfit;
|
||||
|
||||
public class GetTripleTapEnabledRequest extends Request {
|
||||
@Override
|
@ -1,4 +1,4 @@
|
||||
package nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests;
|
||||
package nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.misfit;
|
||||
|
||||
import android.bluetooth.BluetoothGattCharacteristic;
|
||||
|
@ -1,4 +1,4 @@
|
||||
package nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests;
|
||||
package nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.misfit;
|
||||
|
||||
import android.bluetooth.BluetoothGattCharacteristic;
|
||||
|
@ -1,4 +1,4 @@
|
||||
package nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests;
|
||||
package nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.misfit;
|
||||
|
||||
public class GoalTrackingSetRequest extends Request {
|
||||
public GoalTrackingSetRequest(int id, boolean state) {
|
@ -1,12 +1,9 @@
|
||||
package nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests;
|
||||
package nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.misfit;
|
||||
|
||||
import android.bluetooth.BluetoothGattCharacteristic;
|
||||
import android.util.Log;
|
||||
import android.util.SparseArray;
|
||||
|
||||
import java.nio.ByteBuffer;
|
||||
import java.nio.ByteOrder;
|
||||
import java.util.UUID;
|
||||
|
||||
public class ListFilesRequest extends FileRequest{
|
||||
public int fileCount = -1;
|
@ -1,4 +1,4 @@
|
||||
package nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests;
|
||||
package nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.misfit;
|
||||
|
||||
|
||||
import java.nio.ByteBuffer;
|
@ -1,4 +1,4 @@
|
||||
package nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests;
|
||||
package nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.misfit;
|
||||
|
||||
import android.bluetooth.BluetoothGattCharacteristic;
|
||||
|
@ -1,4 +1,4 @@
|
||||
package nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests;
|
||||
package nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.misfit;
|
||||
|
||||
import android.bluetooth.BluetoothGattCharacteristic;
|
||||
|
@ -1,4 +1,4 @@
|
||||
package nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests;
|
||||
package nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.misfit;
|
||||
|
||||
public class OTAResetRequest extends Request {
|
||||
@Override
|
@ -1,4 +1,4 @@
|
||||
package nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests;
|
||||
package nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.misfit;
|
||||
|
||||
import java.nio.ByteBuffer;
|
||||
import java.security.InvalidParameterException;
|
@ -1,4 +1,4 @@
|
||||
package nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests;
|
||||
package nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.misfit;
|
||||
|
||||
public class PutSettingsFileRequest extends Request {
|
||||
@Override
|
@ -1,8 +1,7 @@
|
||||
package nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests;
|
||||
package nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.misfit;
|
||||
|
||||
|
||||
import java.nio.ByteBuffer;
|
||||
import java.nio.ByteOrder;
|
||||
|
||||
public class ReleaseHandsControlRequest extends Request {
|
||||
public ReleaseHandsControlRequest(){
|
@ -1,4 +1,4 @@
|
||||
package nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests;
|
||||
package nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.misfit;
|
||||
|
||||
import android.bluetooth.BluetoothGattCharacteristic;
|
||||
import android.util.Log;
|
@ -1,8 +1,7 @@
|
||||
package nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests;
|
||||
package nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.misfit;
|
||||
|
||||
|
||||
import java.nio.ByteBuffer;
|
||||
import java.nio.ByteOrder;
|
||||
|
||||
public class RequestHandControlRequest extends Request {
|
||||
public RequestHandControlRequest(byte priority, boolean moveCompleteNotify, boolean controlLostNOtify){
|
@ -1,4 +1,4 @@
|
||||
package nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests;
|
||||
package nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.misfit;
|
||||
|
||||
import java.nio.ByteBuffer;
|
||||
|
@ -1,4 +1,4 @@
|
||||
package nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests;
|
||||
package nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.misfit;
|
||||
|
||||
import java.nio.ByteBuffer;
|
||||
|
@ -1,7 +1,6 @@
|
||||
package nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests;
|
||||
package nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.misfit;
|
||||
|
||||
import java.nio.ByteBuffer;
|
||||
import java.nio.ByteOrder;
|
||||
|
||||
public class SetCurrentTimeServiceRequest extends Request {
|
||||
public SetCurrentTimeServiceRequest(int timeStampSecs, short millis, short offsetInMins){
|
@ -1,7 +1,6 @@
|
||||
package nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests;
|
||||
package nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.misfit;
|
||||
|
||||
import java.nio.ByteBuffer;
|
||||
import java.nio.ByteOrder;
|
||||
|
||||
public class SetStepGoalRequest extends Request {
|
||||
public SetStepGoalRequest(int goal){
|
@ -1,4 +1,4 @@
|
||||
package nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests;
|
||||
package nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.misfit;
|
||||
|
||||
import java.nio.ByteBuffer;
|
||||
|
@ -1,4 +1,4 @@
|
||||
package nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests;
|
||||
package nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.misfit;
|
||||
|
||||
public class SetTripleTapEnabledRequest extends Request{
|
||||
@Override
|
@ -1,8 +1,7 @@
|
||||
package nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests;
|
||||
package nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.misfit;
|
||||
|
||||
|
||||
import java.nio.ByteBuffer;
|
||||
import java.nio.ByteOrder;
|
||||
|
||||
public class SetVibrationStrengthRequest extends Request {
|
||||
public SetVibrationStrengthRequest(short strength){
|
@ -1,4 +1,4 @@
|
||||
package nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests;
|
||||
package nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.misfit;
|
||||
|
||||
import java.nio.ByteBuffer;
|
||||
import java.util.UUID;
|
@ -1,4 +1,4 @@
|
||||
package nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests;
|
||||
package nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.misfit;
|
||||
|
||||
import android.bluetooth.BluetoothGattCharacteristic;
|
||||
|
||||
@ -8,8 +8,6 @@ import java.util.ArrayList;
|
||||
import java.util.UUID;
|
||||
import java.util.zip.CRC32;
|
||||
|
||||
import nodomain.freeyourgadget.gadgetbridge.service.btle.TransactionBuilder;
|
||||
|
||||
public class UploadFileRequest extends Request {
|
||||
public enum UploadState{INITIALIZED, UPLOAD, UPLOADED, ERROR}
|
||||
|
@ -1,4 +1,4 @@
|
||||
package nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests;
|
||||
package nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.misfit;
|
||||
|
||||
|
||||
import java.nio.ByteBuffer;
|
Loading…
Reference in New Issue
Block a user