/** * Method to store temporarily the activity data values got from the Mi Band. * * <p>Since we expect chunks of 20 bytes each, we do not store the received bytes it the length is * different. * * @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(); } } else { // the length of the chunk is not what we expect. We need to make sense of this data LOG.warn( "GOT UNEXPECTED ACTIVITY DATA WITH LENGTH: " + value.length + ", EXPECTED LENGTH: " + activityStruct.activityDataRemainingBytes); getSupport().logMessageContent(value); } } else { GB.toast( getContext(), "error buffering activity data: remaining bytes: " + activityStruct.activityDataRemainingBytes + ", received: " + value.length, Toast.LENGTH_LONG, GB.ERROR); 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) { LOG.error("error stopping activity sync", e); } } }
@Override protected void doPerform() throws IOException { // scheduleTaskExecutor = Executors.newScheduledThreadPool(1); TransactionBuilder builder = performInitialized("fetch activity data"); // builder.write(getCharacteristic(MiBandService.UUID_CHARACTERISTIC_LE_PARAMS), // getLowLatency()); builder.add( new SetDeviceBusyAction( getDevice(), getContext().getString(R.string.busy_task_fetch_activity_data), getContext())); builder.write(getCharacteristic(MiBandService.UUID_CHARACTERISTIC_CONTROL_POINT), fetch); builder.queue(getQueue()); }
/** * Acknowledge the transfer of activity data to the Mi Band. * * <p>After receiving data from the band, it has to be acknowledged. This way the Mi Band will * delete the data it has on record. * * @param time * @param bytesTransferred */ private void sendAckDataTransfer(Calendar time, int bytesTransferred) { byte[] ackTime = MiBandDateConverter.calendarToRawBytes(time); SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(GBApplication.getContext()); byte[] ackChecksum = new byte[] {(byte) (bytesTransferred & 0xff), (byte) (0xff & (bytesTransferred >> 8))}; if (prefs.getBoolean(MiBandConst.PREF_MIBAND_DONT_ACK_TRANSFER, false)) { ackChecksum = new byte[] {(byte) (~bytesTransferred & 0xff), (byte) (0xff & (~bytesTransferred >> 8))}; } byte[] ack = new byte[] { MiBandService.COMMAND_CONFIRM_ACTIVITY_DATA_TRANSFER_COMPLETE, ackTime[0], ackTime[1], ackTime[2], ackTime[3], ackTime[4], ackTime[5], ackChecksum[0], ackChecksum[1] }; try { TransactionBuilder builder = performInitialized("send acknowledge"); builder.write(getCharacteristic(MiBandService.UUID_CHARACTERISTIC_CONTROL_POINT), ack); builder.queue(getQueue()); // flush to the DB after queueing the ACK flushActivityDataHolder(); // The last data chunk sent by the miband has always length 0. // When we ack this chunk, the transfer is done. if (getDevice().isBusy() && bytesTransferred == 0) { // if we are not clearing miband's data, we have to stop the sync if (prefs.getBoolean(MiBandConst.PREF_MIBAND_DONT_ACK_TRANSFER, false)) { builder = performInitialized("send acknowledge"); builder.write( getCharacteristic(MiBandService.UUID_CHARACTERISTIC_CONTROL_POINT), new byte[] {MiBandService.COMMAND_STOP_SYNC_DATA}); builder.queue(getQueue()); } handleActivityFetchFinish(); } } catch (IOException ex) { LOG.error("Unable to send ack to MI", ex); } }