Reply to Pebbles version requests

This commit is contained in:
Andreas Shimokawa 2015-01-20 23:51:55 +01:00
parent fcaf099e70
commit 59c281c61c
2 changed files with 87 additions and 15 deletions

View File

@ -17,6 +17,8 @@ import android.widget.Toast;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.util.Set;
import java.util.UUID;
@ -182,22 +184,50 @@ public class BluetoothCommunicationService extends Service {
}
public void run() {
byte[] buffer = new byte[1000]; // buffer store for the stream
int bytes; // bytes returned from read()
byte[] buffer = new byte[8192];
int bytes;
while (true) {
try {
byte[] ping = {0, 0, 0, 0};
byte[] version = {0x00, 0x0d, 0x00, 0x11, 0x01, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x72};
// Read from the InputStream
//bytes = mmInStream.read(buffer,0,2);
//ByteBuffer buf = ByteBuffer.wrap(buffer);
//buf.order(ByteOrder.BIG_ENDIAN);
//short length = buf.getShort();
//Log.e(TAG,Integer.toString(length+4) + " as total length");
bytes = mmInStream.read(buffer);
Log.e(TAG, Integer.toString(bytes) + ": " + PebbleProtocol.decodeResponse(buffer));
//write(version);
bytes = mmInStream.read(buffer, 0, 4);
if (bytes < 4)
continue;
ByteBuffer buf = ByteBuffer.wrap(buffer);
buf.order(ByteOrder.BIG_ENDIAN);
short length = buf.getShort();
short endpoint = buf.getShort();
if (length < 0 || length > 8192) {
Log.i(TAG, "invalid length " + length);
while (mmInStream.available() > 0) {
mmInStream.read(buffer); // read all
}
continue;
}
bytes = mmInStream.read(buffer, 4, length);
if (bytes < length) {
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
Log.i(TAG, "Read " + bytes + ", expected " + length + " reading remaining " + (length - bytes));
int bytes_rest = mmInStream.read(buffer, 4 + bytes, length - bytes);
bytes += bytes_rest;
}
if (length == 1 && endpoint == PebbleProtocol.ENDPOINT_PHONEVERSION) {
Log.i(TAG, "Pebble asked for Phone/App Version - repLYING!");
write(PebbleProtocol.encodePhoneVersion(PebbleProtocol.PHONEVERSION_REMOTE_OS_ANDROID));
} else {
Log.i(TAG, "unhandled message to endpoint " + endpoint + " (" + bytes + " bytes)");
}
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
} catch (IOException e) {
}
}

View File

@ -44,11 +44,32 @@ public class PebbleProtocol {
static final byte PHONECONTROL_START = 8;
static final byte PHONECONTROL_END = 9;
static final short LENGTH_PREFIX = 4;
static final short LENGTH_SETTIME = 9;
static final short LENGTH_PHONEVERSION = 17;
static final byte TIME_GETTIME = 0;
static final byte TIME_SETTIME = 2;
static final byte LENGTH_PREFIX = 4;
static final byte LENGTH_SETTIME = 9;
static final byte PHONEVERSION_APPVERSION = 2; // increase this if pebble complains
static final int PHONEVERSION_SESSION_CAPS_GAMMARAY = (int) 0x80000000;
static final int PHONEVERSION_REMOTE_CAPS_TELEPHONY = 0x00000010;
static final int PHONEVERSION_REMOTE_CAPS_SMS = 0x00000020;
static final int PHONEVERSION_REMOTE_CAPS_GPS = 0x00000040;
static final int PHONEVERSION_REMOTE_CAPS_BTLE = 0x00000080;
static final int PHONEVERSION_REMOTE_CAPS_REARCAMERA = 0x00000100;
static final int PHONEVERSION_REMOTE_CAPS_ACCEL = 0x00000200;
static final int PHONEVERSION_REMOTE_CAPS_GYRO = 0x00000400;
static final int PHONEVERSION_REMOTE_CAPS_COMPASS = 0x00000800;
static final byte PHONEVERSION_REMOTE_OS_UNKNOWN = 0;
static final byte PHONEVERSION_REMOTE_OS_IOS = 1;
static final byte PHONEVERSION_REMOTE_OS_ANDROID = 2;
static final byte PHONEVERSION_REMOTE_OS_OSX = 3;
static final byte PHONEVERSION_REMOTE_OS_LINUX = 4;
static final byte PHONEVERSION_REMOTE_OS_WINDOWS = 5;
static byte[] encodeMessage(short endpoint, byte type, String[] parts) {
// Calculate length first
@ -78,6 +99,7 @@ public class PebbleProtocol {
public static byte[] encodeSMS(String from, String body) {
Long ts = System.currentTimeMillis() / 1000;
ts += SimpleTimeZone.getDefault().getOffset(ts) / 1000;
String tsstring = ts.toString(); // SIC
String[] parts = {from, body, tsstring};
@ -86,6 +108,7 @@ public class PebbleProtocol {
public static byte[] encodeEmail(String from, String subject, String body) {
Long ts = System.currentTimeMillis() / 1000;
ts += SimpleTimeZone.getDefault().getOffset(ts) / 1000;
String tsstring = ts.toString(); // SIC
String[] parts = {from, body, tsstring, subject};
@ -113,6 +136,25 @@ public class PebbleProtocol {
return encodeMessage(ENDPOINT_PHONECONTROL, PHONECONTROL_INCOMINGCALL, parts);
}
public static byte[] encodePhoneVersion(byte os) {
ByteBuffer buf = ByteBuffer.allocate(LENGTH_PHONEVERSION);
buf.order(ByteOrder.BIG_ENDIAN);
buf.putShort((short) (LENGTH_PHONEVERSION - LENGTH_PREFIX));
buf.putShort(ENDPOINT_PHONEVERSION);
buf.put(PHONEVERSION_APPVERSION);
buf.putInt(-1); // TODO: Find out what this is (cookie?)
if (os == PHONEVERSION_REMOTE_OS_ANDROID) {
buf.putInt(PHONEVERSION_SESSION_CAPS_GAMMARAY);
} else {
buf.putInt(0);
}
buf.putInt(PHONEVERSION_REMOTE_CAPS_SMS | PHONEVERSION_REMOTE_CAPS_TELEPHONY | os);
return buf.array();
}
// FIXME: that should return data into some unified struct/Class
public static String decodeResponse(byte[] responseData) {
ByteBuffer buf = ByteBuffer.wrap(responseData);