use of android.bluetooth.BluetoothGatt in project nikeplus-fuelband-se-reversed by evilsocket.
the class MainActivity method onCreate.
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Logger.setLogView(this, (TextView) findViewById(R.id.log_view));
_btManager = (BluetoothManager) getSystemService(Context.BLUETOOTH_SERVICE);
_btAdapter = _btManager.getAdapter();
if (_btAdapter.isEnabled() == false) {
Logger.w("Bluetooth is disabled.");
Intent enableIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
startActivityForResult(enableIntent, REQUEST_ENABLE_BT);
}
_leScanCallback = new BluetoothAdapter.LeScanCallback() {
@Override
public void onLeScan(BluetoothDevice device, int rssi, byte[] scanRecord) {
if (_scanning == false)
return;
try {
/*
* Parse device advertisment data.
*/
final Bundle advData = AdvertisementData.parse(scanRecord);
/*
* Is this a nike device?
*/
if (Arrays.equals(advData.getByteArray("COMPANYCODE"), NIKE_COMPANY_CODE)) {
Logger.i("FOUND NIKE DEVICE [" + device + "]");
dumpDeviceAdvData(advData);
_scanning = false;
_btAdapter.stopLeScan(_leScanCallback);
Logger.i("Connecting to GATT server ...");
_ioqueue = new BLEIoQueue(new BLEIoQueue.QueueCallbacks() {
private BluetoothGattService _CopperheadService = null;
private BluetoothGattCharacteristic _CommandChannel = null;
private BluetoothGattCharacteristic _ResponseChannel = null;
// add a raw packet to the queue
private void addPacket(BLEIoQueue queue, byte[] data, BLEIoOperation.OnResponseCallback callback) {
BLEIoOperation op = new BLEIoOperation(BLEIoOperation.Type.WRITE_CHARACTERISTICS, "Sending command.", callback);
op.set_data(data);
op.set_characteristic(_CommandChannel);
queue.add(op);
}
private void addPacket(BLEIoQueue queue, String s, BLEIoOperation.OnResponseCallback callback) {
byte[] buffer = new byte[s.length() / 2];
for (int i = 0, j = 0; i < s.length(); i += 2, ++j) {
buffer[j] = (byte) ((Character.digit(s.charAt(i), 16) << 4) + Character.digit(s.charAt(i + 1), 16));
}
addPacket(queue, buffer, callback);
}
// create the needed packet to request a specific setting from the device
private void requestSetting(BLEIoQueue queue, int code) {
CopperheadPacket oppacket = new CopperheadPacket(5);
oppacket.setOpcode((byte) 10);
ByteBuffer b = oppacket.getPayloadBuffer();
b.put((byte) 1);
b.put((byte) code);
Packet p = Packet.wrap(oppacket);
p.setProtocolLayer(CommandResponseOperation.ProtocolLayer.COMMAND);
p.setPacketCount(0);
p.setPacketIndex(0);
p.setSequenceNumber(1);
addPacket(queue, p.getBuffer(), new BLEIoOperation.OnResponseCallback() {
@Override
public void onData(Packet config) {
byte[] raw = config.getBuffer();
try {
Utils.processGetSettingsResponse(raw);
} catch (Exception e) {
Logger.e(e.toString());
}
}
});
}
@Override
public void onServicesDiscovered(BLEIoQueue queue, BluetoothGatt gatt, int status) {
dumpServices(gatt);
_CopperheadService = gatt.getService(COPPERHEAD_SERVICE_UUID);
if (_CopperheadService == null) {
Logger.e("No Copperhead service found.");
return;
}
/*
* Get command and response channels.
*/
_CommandChannel = _CopperheadService.getCharacteristic(COPPERHEAD_CMD_UUID);
_ResponseChannel = _CopperheadService.getCharacteristic(COPPERHEAD_RSP_UUID);
if (_CommandChannel == null) {
Logger.e("Could not find COPPERHEAD_CMD_UUID");
return;
} else if (_ResponseChannel == null) {
Logger.e("Could not find COPPERHEAD_RSP_UUID");
return;
}
/*
* Enable the response channel to receive incoming data notifications.
*/
BluetoothGattDescriptor rsp_config_desc = _ResponseChannel.getDescriptor(CLIENT_CHARACTERISTIC_CONFIG_UUID);
if (rsp_config_desc == null) {
Logger.e("RSP has no client config.");
return;
}
BLEIoOperation notify = new BLEIoOperation(BLEIoOperation.Type.NOTIFY_START, "Enable response channel notifications.");
notify.set_characteristic(_ResponseChannel);
notify.set_descriptor(rsp_config_desc);
queue.add(notify);
final BLEIoQueue fq = queue;
Packet auth = new Packet(19);
/*
* Send the "START AUTH" packet -> 0x90 0x01 0x01 0x00 .....
*/
auth.setProtocolLayer(CommandResponseOperation.ProtocolLayer.SESSION);
auth.setPacketCount(0);
auth.setPacketIndex(0);
auth.setSequenceNumber(1);
auth.setCommandBytes((byte) 1, (byte) 1);
addPacket(queue, auth.getBuffer(), new BLEIoOperation.OnResponseCallback() {
@Override
public void onData(Packet challenge_packet) {
Logger.d("<< " + challenge_packet.toString());
ByteBuffer buffer = challenge_packet.getBuffered(ByteOrder.LITTLE_ENDIAN);
// remove op code and length
int opcode = buffer.get();
int length = buffer.get();
switch(buffer.get()) {
case 0x41:
Logger.i("Received authentication challenge");
/*
* Get 16 bytes of AUTH nonce
*/
byte[] nonce = new byte[16];
buffer.get(nonce);
if ((nonce == null) || (nonce.length != 16)) {
Logger.e("Missing or invalid authentication challenge nonce");
} else {
CopperheadCRC32 crc = new CopperheadCRC32();
byte[] auth_token = Utils.hexToBytes("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF");
Logger.d("NONCE: " + Utils.bytesToHex(nonce));
/*
* Create the response packet: 0xb0 0x03 0x02 [2 BYTES OF CRC] 0x00 ...
*/
Packet resp_packet = new Packet(19);
resp_packet.setProtocolLayer(CommandResponseOperation.ProtocolLayer.SESSION);
resp_packet.setPacketCount(0);
resp_packet.setPacketIndex(0);
resp_packet.setSequenceNumber(challenge_packet.getSequenceNumber() + 1);
ByteBuffer response = ByteBuffer.allocate(18);
response.put((byte) 0x03);
response.put((byte) 0x02);
crc.update(nonce);
crc.update(auth_token);
short sum = (short) ((0xFFFF & crc.getValue()) ^ (0xFFFF & crc.getValue() >>> 16));
response.putShort(sum);
resp_packet.setPayload(response.array());
addPacket(fq, resp_packet.getBuffer(), new BLEIoOperation.OnResponseCallback() {
@Override
public void onData(Packet challenge_response) {
Logger.d("<< " + challenge_response.toString());
ByteBuffer buffer = challenge_response.getBuffered(ByteOrder.LITTLE_ENDIAN);
// remove op code and length
int opcode = buffer.get();
int length = buffer.get();
/*
* Get the authentication reply code.
*/
int reply = buffer.get();
if (reply == 0x42) {
Logger.i("Succesfully authenticated.");
// Request some settings
requestSetting(fq, Utils.getSettingCode("BAND_COLOR"));
requestSetting(fq, Utils.getSettingCode("FUEL"));
requestSetting(fq, Utils.getSettingCode("FIRST_NAME"));
requestSetting(fq, Utils.getSettingCode("SERIAL_NUMBER"));
} else {
Logger.e("Authentication failure, reply: " + reply);
}
}
});
}
break;
default:
Logger.e("Unknown auth code.");
}
}
});
}
});
device.connectGatt(MainActivity.this, false, _ioqueue);
}
} catch (Exception e) {
Logger.e(e.toString());
}
}
};
Logger.i("Starting scann ...");
_scanning = true;
_btAdapter.startLeScan(_leScanCallback);
}
use of android.bluetooth.BluetoothGatt in project BleLiteLib4android by afunx.
the class BleGattClientProxyImpl method __requestMtu.
private boolean __requestMtu(final int mtu, final long timeout) {
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP) {
BleLiteLog.w(TAG, "__requestMtu() fail for android version is to low(lower than 5.0 LOLLIPOP)");
return false;
}
final BluetoothGatt bluetoothGatt = getBluetoothGatt();
if (bluetoothGatt == null) {
BleLiteLog.w(TAG, "__requestMtu() fail for bluetoothGatt is null");
return false;
}
// create operation
final BleRequestMtuOperation requestMtuOperation = BleRequestMtuOperation.createInstance(bluetoothGatt, mtu);
// register
register(requestMtuOperation);
// execute operation
long startTimestamp = System.currentTimeMillis();
requestMtuOperation.doRunnableSelfAsync(false);
requestMtuOperation.waitLock(timeout);
long consume = System.currentTimeMillis() - startTimestamp;
boolean isRequestMtuSuc = requestMtuOperation.isNotified();
BleLiteLog.i(TAG, "__requestMtu() mtu: " + mtu + " suc: " + isRequestMtuSuc + ", consume: " + consume + " ms");
return isRequestMtuSuc;
}
use of android.bluetooth.BluetoothGatt in project BleLiteLib4android by afunx.
the class BleGattClientProxyImpl method __readCharacteristic.
private byte[] __readCharacteristic(BluetoothGattCharacteristic gattCharacteristic, long timeout) {
final BluetoothGatt bluetoothGatt = getBluetoothGatt();
if (bluetoothGatt == null) {
BleLiteLog.w(TAG, "__readCharacteristic() fail for bluetoothGatt is null");
return null;
}
// create operation
final BleReadCharacteristicOperation readCharacteristicOperation = BleReadCharacteristicOperation.createInstance(bluetoothGatt, gattCharacteristic);
// register
register(readCharacteristicOperation);
// execute operation
long startTimestamp = System.currentTimeMillis();
readCharacteristicOperation.doRunnableSelfAsync(false);
readCharacteristicOperation.waitLock(timeout);
long consume = System.currentTimeMillis() - startTimestamp;
final byte[] msg = readCharacteristicOperation.isNotified() ? readCharacteristicOperation.getResult() : null;
BleLiteLog.i(TAG, "__readCharacteristic() gattCharacteristic's uuid: " + gattCharacteristic.getUuid() + ", consume: " + consume + " ms" + ", msg: " + Arrays.toString(msg));
return msg;
}
use of android.bluetooth.BluetoothGatt in project BleLiteLib4android by afunx.
the class BleGattClientProxyImpl method __writeCharacteristic.
private boolean __writeCharacteristic(final BluetoothGattCharacteristic gattCharacteristic, final byte[] msg, long timeout) {
final BluetoothGatt bluetoothGatt = getBluetoothGatt();
if (bluetoothGatt == null) {
BleLiteLog.w(TAG, "__writeCharacteristic() fail for bluetoothGatt is null");
return false;
}
// create operation
BleWriteCharacteristicOperation writeCharacteristicOperation = BleWriteCharacteristicOperation.createInstance(bluetoothGatt, gattCharacteristic, msg);
// register
register(writeCharacteristicOperation);
// execute operation
long startTimestamp = System.currentTimeMillis();
writeCharacteristicOperation.doRunnableSelfAsync(false);
writeCharacteristicOperation.waitLock(timeout);
long consume = System.currentTimeMillis() - startTimestamp;
boolean isWriteCharacteristicSuc = writeCharacteristicOperation.isNotified();
BleLiteLog.i(TAG, "__writeCharacteristic() msg: " + Arrays.toString(msg) + " suc: " + isWriteCharacteristicSuc + ", consume: " + consume + " ms");
return isWriteCharacteristicSuc;
}
use of android.bluetooth.BluetoothGatt in project BleLiteLib4android by afunx.
the class BleGattClientProxyImpl method __discoverService.
private BluetoothGattService __discoverService(UUID uuid, long timeout) {
final BluetoothGatt bluetoothGatt = getBluetoothGatt();
boolean isServiceDiscoverSuc = __discoverService(bluetoothGatt, timeout);
if (isServiceDiscoverSuc) {
final BluetoothGattService gattService = bluetoothGatt.getService(uuid);
BleLiteLog.i(TAG, "__discoverService() uuid: " + uuid + ", gattService is " + (gattService != null ? "found" : "missed"));
return gattService;
} else {
return null;
}
}
Aggregations