mirror of
https://codeberg.org/Freeyourgadget/Gadgetbridge.git
synced 2026-07-31 07:44:24 +02:00
Liveview: Switch to BTBR support class
This commit is contained in:
-99
@@ -1,99 +0,0 @@
|
||||
/* Copyright (C) 2016-2024 Carsten Pfeiffer, Daniele Gobbetti
|
||||
|
||||
This file is part of Gadgetbridge.
|
||||
|
||||
Gadgetbridge is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Affero General Public License as published
|
||||
by the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
Gadgetbridge is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Affero General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Affero General Public License
|
||||
along with this program. If not, see <https://www.gnu.org/licenses/>. */
|
||||
package nodomain.freeyourgadget.gadgetbridge.service.devices.liveview;
|
||||
|
||||
import android.bluetooth.BluetoothAdapter;
|
||||
import android.content.Context;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.util.UUID;
|
||||
|
||||
import nodomain.freeyourgadget.gadgetbridge.devices.liveview.LiveviewConstants;
|
||||
import nodomain.freeyourgadget.gadgetbridge.impl.GBDevice;
|
||||
import nodomain.freeyourgadget.gadgetbridge.service.btclassic.BtClassicIoThread;
|
||||
import nodomain.freeyourgadget.gadgetbridge.service.serial.GBDeviceProtocol;
|
||||
import nodomain.freeyourgadget.gadgetbridge.util.GB;
|
||||
|
||||
public class LiveviewIoThread extends BtClassicIoThread {
|
||||
private static final Logger LOG = LoggerFactory.getLogger(LiveviewIoThread.class);
|
||||
|
||||
private static final UUID SERIAL = UUID.fromString("00001101-0000-1000-8000-00805F9B34FB");
|
||||
|
||||
public LiveviewIoThread(GBDevice gbDevice, Context context, GBDeviceProtocol lvProtocol, LiveviewSupport lvSupport, BluetoothAdapter lvBtAdapter) {
|
||||
super(gbDevice, context, lvProtocol, lvSupport, lvBtAdapter);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected byte[] parseIncoming(InputStream inputStream) throws IOException {
|
||||
ByteArrayOutputStream msgStream = new ByteArrayOutputStream();
|
||||
|
||||
boolean finished = false;
|
||||
ReaderState state = ReaderState.ID;
|
||||
byte[] incoming = new byte[1];
|
||||
|
||||
while (!finished) {
|
||||
inputStream.read(incoming);
|
||||
msgStream.write(incoming);
|
||||
|
||||
switch (state) {
|
||||
case ID:
|
||||
state = ReaderState.HEADER_LEN;
|
||||
incoming = new byte[1];
|
||||
break;
|
||||
case HEADER_LEN:
|
||||
int headerSize = 0xff & incoming[0];
|
||||
state = ReaderState.HEADER;
|
||||
incoming = new byte[headerSize];
|
||||
break;
|
||||
case HEADER:
|
||||
int payloadSize = getLastInt(msgStream);
|
||||
if (payloadSize < 0 || payloadSize > 8000) //this will possibly be changed in the future
|
||||
throw new IOException();
|
||||
state = ReaderState.PAYLOAD;
|
||||
incoming = new byte[payloadSize];
|
||||
break;
|
||||
case PAYLOAD: //read is blocking, if we are here we have all the data
|
||||
finished = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
byte[] msgArray = msgStream.toByteArray();
|
||||
LOG.debug("received: " + GB.hexdump(msgArray, 0, msgArray.length));
|
||||
return msgArray;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Enumeration containing the possible internal status of the reader.
|
||||
*/
|
||||
private enum ReaderState {
|
||||
ID, HEADER_LEN, HEADER, PAYLOAD;
|
||||
}
|
||||
|
||||
private int getLastInt(ByteArrayOutputStream stream) {
|
||||
byte[] array = stream.toByteArray();
|
||||
ByteBuffer buffer = ByteBuffer.wrap(array, array.length - 4, 4);
|
||||
buffer.order(LiveviewConstants.BYTE_ORDER);
|
||||
return buffer.getInt();
|
||||
}
|
||||
}
|
||||
+78
-12
@@ -17,28 +17,94 @@
|
||||
along with this program. If not, see <https://www.gnu.org/licenses/>. */
|
||||
package nodomain.freeyourgadget.gadgetbridge.service.devices.liveview;
|
||||
|
||||
import nodomain.freeyourgadget.gadgetbridge.service.serial.AbstractSerialDeviceSupport;
|
||||
import nodomain.freeyourgadget.gadgetbridge.service.serial.GBDeviceIoThread;
|
||||
import nodomain.freeyourgadget.gadgetbridge.service.serial.GBDeviceProtocol;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.nio.ByteBuffer;
|
||||
import java.util.UUID;
|
||||
|
||||
import nodomain.freeyourgadget.gadgetbridge.devices.liveview.LiveviewConstants;
|
||||
import nodomain.freeyourgadget.gadgetbridge.impl.GBDevice;
|
||||
import nodomain.freeyourgadget.gadgetbridge.service.btbr.TransactionBuilder;
|
||||
import nodomain.freeyourgadget.gadgetbridge.service.serial.AbstractSerialDeviceSupportV2;
|
||||
|
||||
public class LiveviewSupport extends AbstractSerialDeviceSupportV2<LiveviewProtocol> {
|
||||
private static final Logger LOG = LoggerFactory.getLogger(LiveviewSupport.class);
|
||||
|
||||
private final ByteBuffer packetBuffer = ByteBuffer.allocate(8000).order(LiveviewConstants.BYTE_ORDER);
|
||||
|
||||
public LiveviewSupport() {
|
||||
super(8000);
|
||||
addSupportedService(UUID.fromString("00001101-0000-1000-8000-00805F9B34FB"));
|
||||
}
|
||||
|
||||
public class LiveviewSupport extends AbstractSerialDeviceSupport {
|
||||
@Override
|
||||
protected GBDeviceProtocol createDeviceProtocol() {
|
||||
protected LiveviewProtocol createDeviceProtocol() {
|
||||
return new LiveviewProtocol(getDevice());
|
||||
}
|
||||
|
||||
@Override
|
||||
protected GBDeviceIoThread createDeviceIOThread() {
|
||||
return new LiveviewIoThread(getDevice(), getContext(), getDeviceProtocol(), LiveviewSupport.this, getBluetoothAdapter());
|
||||
protected TransactionBuilder initializeDevice(final TransactionBuilder builder) {
|
||||
packetBuffer.clear();
|
||||
builder.write(mDeviceProtocol.encodeSetTime());
|
||||
builder.setDeviceState(GBDevice.State.INITIALIZED);
|
||||
return builder;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean useAutoConnect() {
|
||||
return false;
|
||||
public void onSocketRead(final byte[] data) {
|
||||
packetBuffer.put(data);
|
||||
packetBuffer.flip();
|
||||
|
||||
while (packetBuffer.hasRemaining()) {
|
||||
final int start = packetBuffer.position();
|
||||
packetBuffer.mark();
|
||||
|
||||
if (packetBuffer.remaining() < 2) {
|
||||
// not enough bytes for min packet
|
||||
packetBuffer.reset();
|
||||
break;
|
||||
}
|
||||
|
||||
packetBuffer.get(); // id
|
||||
|
||||
final int headerLength = packetBuffer.get() & 0xff;
|
||||
if (packetBuffer.remaining() < headerLength) {
|
||||
// not enough bytes
|
||||
packetBuffer.reset();
|
||||
break;
|
||||
}
|
||||
|
||||
final byte[] header = new byte[headerLength];
|
||||
packetBuffer.get(header);
|
||||
|
||||
final int payloadSize = getLastInt(header);
|
||||
if (packetBuffer.remaining() < payloadSize) {
|
||||
// not enough bytes
|
||||
packetBuffer.reset();
|
||||
break;
|
||||
}
|
||||
|
||||
final int end = packetBuffer.position() + payloadSize;
|
||||
|
||||
final byte[] packet = new byte[end - start];
|
||||
packetBuffer.position(start);
|
||||
packetBuffer.get(packet);
|
||||
|
||||
// Handle it upstream, to the protocol
|
||||
try {
|
||||
super.onSocketRead(packet);
|
||||
} catch (final Exception e) {
|
||||
LOG.error("Failed to handle command", e);
|
||||
}
|
||||
}
|
||||
|
||||
packetBuffer.compact();
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized LiveviewIoThread getDeviceIOThread() {
|
||||
return (LiveviewIoThread) super.getDeviceIOThread();
|
||||
private int getLastInt(final byte[] array) {
|
||||
final ByteBuffer buffer = ByteBuffer.wrap(array, array.length - 4, 4);
|
||||
buffer.order(LiveviewConstants.BYTE_ORDER);
|
||||
return buffer.getInt();
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user