mirror of
https://codeberg.org/Freeyourgadget/Gadgetbridge
synced 2024-06-02 03:16:07 +02:00
3a58314db6
- communication protocols - device support implementation - download FIT file storage Features: - basic connectivity: time sync, battery status, HW/FW version info - real-time activity tracking - fitness data sync - find the device, find the phone - factory reset Features implemented but not working: - notifications: fully implemented, seem to communicate correctly, but not shown on watch Features implemented partially (not expected to work now): - weather information (and in future possibly weather alerts) - music info - firmware update: only the initial file upload implemented, not used Things to improve/change: - Device name hardcoded in `VivomoveHrCoordinator.getSupportedType`, service UUIDs not available - Download FIT file storage: Should be store (and offer the user to export?) the FIT data forever? - Obviously, various code improvements, cleanup, etc.
98 lines
3.6 KiB
Java
98 lines
3.6 KiB
Java
package nodomain.freeyourgadget.gadgetbridge.service.devices.vivomovehr.ancs;
|
|
|
|
import nodomain.freeyourgadget.gadgetbridge.service.devices.vivomovehr.VivomoveHrCommunicator;
|
|
import nodomain.freeyourgadget.gadgetbridge.service.devices.vivomovehr.messages.GncsDataSourceMessage;
|
|
import nodomain.freeyourgadget.gadgetbridge.service.devices.vivomovehr.messages.GncsDataSourceResponseMessage;
|
|
import org.slf4j.Logger;
|
|
import org.slf4j.LoggerFactory;
|
|
|
|
import java.util.LinkedList;
|
|
import java.util.Queue;
|
|
|
|
public class GncsDataSourceQueue {
|
|
private static final Logger LOG = LoggerFactory.getLogger(GncsDataSourceQueue.class);
|
|
|
|
private final VivomoveHrCommunicator communicator;
|
|
private final int maxPacketSize;
|
|
private final Queue<byte[]> queue = new LinkedList<>();
|
|
|
|
private byte[] currentPacket;
|
|
private int currentDataOffset;
|
|
private int lastSentSize;
|
|
|
|
public GncsDataSourceQueue(VivomoveHrCommunicator communicator, int maxPacketSize) {
|
|
this.communicator = communicator;
|
|
this.maxPacketSize = maxPacketSize;
|
|
}
|
|
|
|
public void addToQueue(byte[] packet) {
|
|
queue.add(packet);
|
|
checkStartUpload();
|
|
}
|
|
|
|
public void responseReceived(GncsDataSourceResponseMessage responseMessage) {
|
|
if (currentPacket == null) {
|
|
LOG.error("Unexpected GNCS data source response, no current packet");
|
|
return;
|
|
}
|
|
switch (responseMessage.response) {
|
|
case GncsDataSourceResponseMessage.RESPONSE_TRANSFER_SUCCESSFUL:
|
|
LOG.debug("Confirmed {}B@{} GNCS transfer", lastSentSize, currentDataOffset);
|
|
currentDataOffset += lastSentSize;
|
|
if (currentDataOffset >= currentPacket.length) {
|
|
LOG.debug("ANCS packet transfer done");
|
|
currentPacket = null;
|
|
checkStartUpload();
|
|
} else {
|
|
sendNextMessage();
|
|
}
|
|
break;
|
|
|
|
case GncsDataSourceResponseMessage.RESPONSE_RESEND_LAST_DATA_PACKET:
|
|
LOG.info("Received RESEND_LAST_DATA_PACKET GNCS response");
|
|
sendNextMessage();
|
|
break;
|
|
|
|
case GncsDataSourceResponseMessage.RESPONSE_ABORT_REQUEST:
|
|
LOG.info("Received RESPONSE_ABORT_REQUEST GNCS response");
|
|
currentPacket = null;
|
|
checkStartUpload();
|
|
break;
|
|
|
|
case GncsDataSourceResponseMessage.RESPONSE_ERROR_CRC_MISMATCH:
|
|
case GncsDataSourceResponseMessage.RESPONSE_ERROR_DATA_OFFSET_MISMATCH:
|
|
default:
|
|
LOG.error("Received {} GNCS response", responseMessage.response);
|
|
currentPacket = null;
|
|
checkStartUpload();
|
|
break;
|
|
}
|
|
}
|
|
|
|
private void checkStartUpload() {
|
|
if (currentPacket != null) {
|
|
LOG.debug("Another upload is still running");
|
|
return;
|
|
}
|
|
if (queue.isEmpty()) {
|
|
LOG.debug("Nothing in queue");
|
|
return;
|
|
}
|
|
startNextUpload();
|
|
}
|
|
|
|
private void startNextUpload() {
|
|
currentPacket = queue.remove();
|
|
currentDataOffset = 0;
|
|
LOG.debug("Sending {}B ANCS data", currentPacket.length);
|
|
sendNextMessage();
|
|
}
|
|
|
|
private void sendNextMessage() {
|
|
final int remainingSize = currentPacket.length - currentDataOffset;
|
|
final int availableSize = Math.min(remainingSize, maxPacketSize);
|
|
communicator.sendMessage(new GncsDataSourceMessage(currentPacket, currentDataOffset, Math.min(remainingSize, maxPacketSize)).packet);
|
|
lastSentSize = availableSize;
|
|
}
|
|
}
|