- add code to send the confirmation of the activity data transfer after a timeout.

==> This is currently commented out because it was done to solve #141 but while doing this #143 popped out.
- send a stop_sync message to the band if the data doesn't fit the buffer. This way the data remains on the band.
here
Daniele Gobbetti 2015-10-19 16:17:03 +02:00
parent 6460b391d9
commit cee03debbb
1 changed files with 76 additions and 32 deletions

View File

@ -15,6 +15,9 @@ import java.text.DateFormat;
import java.util.Calendar;
import java.util.GregorianCalendar;
import java.util.UUID;
//import java.util.concurrent.Executors;
//import java.util.concurrent.ScheduledExecutorService;
//import java.util.concurrent.ScheduledFuture;
import java.util.concurrent.TimeUnit;
import nodomain.freeyourgadget.gadgetbridge.GBApplication;
@ -39,6 +42,12 @@ public class FetchActivityOperation extends AbstractBTLEOperation<MiBandSupport>
private static final Logger LOG = LoggerFactory.getLogger(FetchActivityOperation.class);
private static final byte[] fetch = new byte[]{MiBandService.COMMAND_FETCH_DATA};
//sometimes the Mi Band stops sending data, we confirm the part of the data transfer after some time
//private ScheduledExecutorService scheduleTaskExecutor;
//private ScheduledFuture scheduledTask;
private int activityMetadataLength = 11;
//temporary buffer, size is a multiple of 60 because we want to store complete minutes (1 minute = 3 bytes)
private static final int activityDataHolderSize = 3 * 60 * 4; // 4h
@ -122,6 +131,8 @@ public class FetchActivityOperation extends AbstractBTLEOperation<MiBandSupport>
@Override
public void perform() throws IOException {
// scheduleTaskExecutor = Executors.newScheduledThreadPool(1);
TransactionBuilder builder = performInitialized("fetch activity data");
// builder.write(getCharacteristic(MiBandService.UUID_CHARACTERISTIC_LE_PARAMS), getLowLatency());
@ -169,7 +180,27 @@ public class FetchActivityOperation extends AbstractBTLEOperation<MiBandSupport>
* @see #bufferActivityData(byte[])
*/
private void handleActivityNotif(byte[] value) {
if (value.length == 11) {
if (value.length == activityMetadataLength) {
handleActivityMetadata(value);
} else {
bufferActivityData(value);
}
LOG.debug("activity data: length: " + value.length + ", remaining bytes: " + activityStruct.activityDataRemainingBytes);
GB.updateTransferNotification(getContext().getString(R.string.busy_task_fetch_activity_data), true, (int) (((float) (activityStruct.activityDataUntilNextHeader - activityStruct.activityDataRemainingBytes)) / activityStruct.activityDataUntilNextHeader * 100), getContext());
if (activityStruct.isBlockFinished()) {
sendAckDataTransfer(activityStruct.activityDataTimestampToAck, activityStruct.activityDataUntilNextHeader);
GB.updateTransferNotification("", false, 100, getContext());
}
}
private void handleActivityMetadata(byte[] value) {
if (value.length != activityMetadataLength) {
return;
}
// byte 0 is the data type: 1 means that each minute is represented by a triplet of bytes
int dataType = value[0];
// byte 1 to 6 represent a timestamp
@ -199,18 +230,6 @@ public class FetchActivityOperation extends AbstractBTLEOperation<MiBandSupport>
LOG.info("TIMESTAMP: " + DateFormat.getDateTimeInstance().format(timestamp.getTime()).toString() + " magic byte: " + dataUntilNextHeader);
activityStruct.startNewBlock(timestamp, dataUntilNextHeader);
} else {
bufferActivityData(value);
}
LOG.debug("activity data: length: " + value.length + ", remaining bytes: " + activityStruct.activityDataRemainingBytes);
GB.updateTransferNotification(getContext().getString(R.string.busy_task_fetch_activity_data), true, (int)(((float) (activityStruct.activityDataUntilNextHeader - activityStruct.activityDataRemainingBytes)) / activityStruct.activityDataUntilNextHeader * 100), getContext());
if (activityStruct.isBlockFinished()) {
sendAckDataTransfer(activityStruct.activityDataTimestampToAck, activityStruct.activityDataUntilNextHeader);
GB.updateTransferNotification("", false, 100, getContext());
}
}
/**
@ -221,10 +240,24 @@ public class FetchActivityOperation extends AbstractBTLEOperation<MiBandSupport>
* @param value
*/
private void bufferActivityData(byte[] value) {
/*
if (scheduledTask != null) {
scheduledTask.cancel(true);
}
*/
if (activityStruct.hasRoomFor(value)) {
if (activityStruct.isValidData(value)) {
activityStruct.buffer(value);
/* scheduledTask = scheduleTaskExecutor.schedule(new Runnable() {
@Override
public void run() {
GB.toast(getContext(), "chiederei " + activityStruct.activityDataTimestampToAck + " "+ activityStruct.activityDataUntilNextHeader, Toast.LENGTH_LONG, GB.ERROR);
//sendAckDataTransfer(activityStruct.activityDataTimestampToAck, activityStruct.activityDataUntilNextHeader);
LOG.debug("runnable called");
}
}, 10l, TimeUnit.SECONDS);
*/
if (activityStruct.isBufferFull()) {
flushActivityDataHolder();
}
@ -234,6 +267,17 @@ public class FetchActivityOperation extends AbstractBTLEOperation<MiBandSupport>
getSupport().logMessageContent(value);
}
} else {
try {
TransactionBuilder builder = performInitialized("send stop sync data");
builder.write(getCharacteristic(MiBandService.UUID_CHARACTERISTIC_CONTROL_POINT), new byte[]{MiBandService.COMMAND_STOP_SYNC_DATA});
builder.queue(getQueue());
GB.updateTransferNotification("Data transfer failed", false, 0, getContext());
handleActivityFetchFinish();
} catch (IOException e) {
e.printStackTrace();
}
GB.toast(getContext(), "error buffering activity data: remaining bytes: " + activityStruct.activityDataRemainingBytes + ", received: " + value.length, Toast.LENGTH_LONG, GB.ERROR);
LOG.error("error buffering activity data: remaining bytes: " + activityStruct.activityDataRemainingBytes + ", received: " + value.length);
}
}