From da297ecd8b1810f605e9d0168a71a5bcf75b11b8 Mon Sep 17 00:00:00 2001 From: cpfeiffer Date: Thu, 1 Dec 2016 22:49:58 +0100 Subject: [PATCH] Fix + cleanup time setting and calendar sending #441 --- .../devices/miband/MiBand2Support.java | 98 +++++++------------ .../operations/FetchActivityOperation.java | 3 +- .../miband2/operations/InitOperation.java | 2 +- 3 files changed, 38 insertions(+), 65 deletions(-) diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/miband/MiBand2Support.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/miband/MiBand2Support.java index 62016c4d..e6466471 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/miband/MiBand2Support.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/miband/MiBand2Support.java @@ -18,10 +18,10 @@ import java.io.IOException; import java.util.ArrayList; import java.util.Arrays; import java.util.Calendar; -import java.util.Date; import java.util.GregorianCalendar; import java.util.List; import java.util.UUID; +import java.util.concurrent.TimeUnit; import nodomain.freeyourgadget.gadgetbridge.GBApplication; import nodomain.freeyourgadget.gadgetbridge.R; @@ -182,8 +182,15 @@ public class MiBand2Support extends AbstractBTLEDeviceSupport { return builder; } - public byte[] getTimeBytes(Calendar calendar) { - byte[] bytes = BLETypeConversions.shortCalendarToRawBytes(calendar, true); + public byte[] getTimeBytes(Calendar calendar, TimeUnit precision) { + byte[] bytes; + if (precision == TimeUnit.MINUTES) { + bytes = BLETypeConversions.shortCalendarToRawBytes(calendar, true); + } else if (precision == TimeUnit.SECONDS) { + bytes = BLETypeConversions.calendarToRawBytes(calendar, true); + } else { + throw new IllegalArgumentException("Unsupported precision, only MINUTES and SECONDS are supported till now"); + } byte[] tail = new byte[] { 0, BLETypeConversions.mapTimeZone(calendar.getTimeZone()) }; // 0 = adjust reason bitflags? or DST offset?? , timezone // byte[] tail = new byte[] { 0x2 }; // reason byte[] all = BLETypeConversions.join(bytes, tail); @@ -197,8 +204,9 @@ public class MiBand2Support extends AbstractBTLEDeviceSupport { public MiBand2Support setCurrentTimeWithService(TransactionBuilder builder) { GregorianCalendar now = BLETypeConversions.createCalendar(); - byte[] bytes = getTimeBytes(now); + byte[] bytes = getTimeBytes(now, TimeUnit.SECONDS); builder.write(getCharacteristic(GattCharacteristic.UUID_CHARACTERISTIC_CURRENT_TIME), bytes); + // byte[] localtime = BLETypeConversions.calendarToLocalTimeBytes(now); // builder.write(getCharacteristic(GattCharacteristic.UUID_CHARACTERISTIC_LOCAL_TIME_INFORMATION), localtime); // builder.write(getCharacteristic(GattCharacteristic.UUID_CHARACTERISTIC_CURRENT_TIME), new byte[] {0x2, 0x00}); @@ -577,46 +585,13 @@ public class MiBand2Support extends AbstractBTLEDeviceSupport { public void onSetTime() { try { TransactionBuilder builder = performInitialized("Set date and time"); - setCurrentTime(builder); + setCurrentTimeWithService(builder); + //TODO: once we have a common strategy for sending events (e.g. EventHandler), remove this call from here. Meanwhile it does no harm. + sendCalendarEvents(builder); builder.queue(getQueue()); } catch (IOException ex) { LOG.error("Unable to set time on MI device", ex); } - //TODO: once we have a common strategy for sending events (e.g. EventHandler), remove this call from here. Meanwhile it does no harm. - sendCalendarEvents(); - } - - /** - * Sets the current time to the Mi device using the given builder. - * - * @param builder - */ - private MiBand2Support setCurrentTime(TransactionBuilder builder) { - Calendar now = GregorianCalendar.getInstance(); - Date date = now.getTime(); - LOG.info("Sending current time to Mi Band: " + DateTimeUtils.formatDate(date) + " (" + date.toGMTString() + ")"); - byte[] nowBytes = MiBandDateConverter.calendarToRawBytes(now); - byte[] time = new byte[]{ - nowBytes[0], - nowBytes[1], - nowBytes[2], - nowBytes[3], - nowBytes[4], - nowBytes[5], - (byte) 0x0f, - (byte) 0x0f, - (byte) 0x0f, - (byte) 0x0f, - (byte) 0x0f, - (byte) 0x0f - }; - BluetoothGattCharacteristic characteristic = getCharacteristic(MiBandService.UUID_CHARACTERISTIC_DATE_TIME); - if (characteristic != null) { - builder.write(characteristic, time); - } else { - LOG.info("Unable to set time -- characteristic not available"); - } - return this; } @Override @@ -1209,36 +1184,33 @@ public class MiBand2Support extends AbstractBTLEDeviceSupport { /** * Fetch the events from the android device calendars and set the alarms on the miband. + * @param builder */ - private void sendCalendarEvents() { - try { - TransactionBuilder builder = performInitialized("Send upcoming events"); - BluetoothGattCharacteristic characteristic = getCharacteristic(MiBand2Service.UUID_UNKNOWN_CHARACTERISTIC3); + private MiBand2Support sendCalendarEvents(TransactionBuilder builder) { + BluetoothGattCharacteristic characteristic = getCharacteristic(MiBand2Service.UUID_UNKNOWN_CHARACTERISTIC3); - Prefs prefs = GBApplication.getPrefs(); - int availableSlots = prefs.getInt(MiBandConst.PREF_MIBAND_RESERVE_ALARM_FOR_CALENDAR, 0); + Prefs prefs = GBApplication.getPrefs(); + int availableSlots = prefs.getInt(MiBandConst.PREF_MIBAND_RESERVE_ALARM_FOR_CALENDAR, 0); - if (availableSlots > 0) { - CalendarEvents upcomingEvents = new CalendarEvents(); - List mEvents = upcomingEvents.getCalendarEventList(getContext()); + if (availableSlots > 0) { + CalendarEvents upcomingEvents = new CalendarEvents(); + List mEvents = upcomingEvents.getCalendarEventList(getContext()); - int iteration = 0; - for (CalendarEvents.CalendarEvent mEvt : mEvents) { - if (iteration >= availableSlots || iteration > 2) { - break; - } - int slotToUse = 2 - iteration; - Calendar calendar = Calendar.getInstance(); - calendar.setTimeInMillis(mEvt.getBegin()); - Alarm alarm = GBAlarm.createSingleShot(slotToUse, false, calendar); - queueAlarm(alarm, builder, characteristic); - iteration++; + int iteration = 0; + for (CalendarEvents.CalendarEvent mEvt : mEvents) { + if (iteration >= availableSlots || iteration > 2) { + break; } - builder.queue(getQueue()); + int slotToUse = 2 - iteration; + Calendar calendar = Calendar.getInstance(); + calendar.setTimeInMillis(mEvt.getBegin()); + Alarm alarm = GBAlarm.createSingleShot(slotToUse, false, calendar); + queueAlarm(alarm, builder, characteristic); + iteration++; } - } catch (IOException ex) { - LOG.error("Unable to send Events to MI device", ex); + builder.queue(getQueue()); } + return this; } @Override diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/miband2/operations/FetchActivityOperation.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/miband2/operations/FetchActivityOperation.java index 4979d70f..8ffbd839 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/miband2/operations/FetchActivityOperation.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/miband2/operations/FetchActivityOperation.java @@ -15,6 +15,7 @@ import java.util.Calendar; import java.util.GregorianCalendar; import java.util.List; import java.util.UUID; +import java.util.concurrent.TimeUnit; import nodomain.freeyourgadget.gadgetbridge.GBApplication; import nodomain.freeyourgadget.gadgetbridge.Logging; @@ -73,7 +74,7 @@ public class FetchActivityOperation extends AbstractMiBand2Operation { BluetoothGattCharacteristic characteristicActivityData = getCharacteristic(MiBand2Service.UUID_CHARACTERISTIC_ACTIVITY_DATA); GregorianCalendar sinceWhen = getLastSuccessfulSynchronizedTime(); - builder.write(characteristicFetch, BLETypeConversions.join(new byte[] { MiBand2Service.COMMAND_ACTIVITY_DATA_START_DATE, 0x01 }, getSupport().getTimeBytes(sinceWhen))); + builder.write(characteristicFetch, BLETypeConversions.join(new byte[] { MiBand2Service.COMMAND_ACTIVITY_DATA_START_DATE, 0x01 }, getSupport().getTimeBytes(sinceWhen, TimeUnit.MINUTES))); builder.add(new WaitAction(1000)); // TODO: actually wait for the success-reply builder.notify(characteristicActivityData, true); builder.write(characteristicFetch, new byte[] { MiBand2Service.COMMAND_FETCH_ACTIVITY_DATA }); diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/miband2/operations/InitOperation.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/miband2/operations/InitOperation.java index 0d59c4b5..5adabc67 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/miband2/operations/InitOperation.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/miband2/operations/InitOperation.java @@ -98,7 +98,7 @@ public class InitOperation extends AbstractBTLEOperation { } else if (value[0] == MiBand2Service.AUTH_RESPONSE && value[1] == MiBand2Service.AUTH_SEND_ENCRYPTED_AUTH_NUMBER && value[2] == MiBand2Service.AUTH_SUCCESS) { - TransactionBuilder builder = createTransactionBuilder("Sending the encrypted random key to the band"); + TransactionBuilder builder = createTransactionBuilder("Authenticated, now initialize phase 2"); builder.add(new SetDeviceStateAction(getDevice(), GBDevice.State.INITIALIZING, getContext())); getSupport().requestDeviceInfo(builder); getSupport().phase2Initialize(builder);