use of android.bluetooth.BluetoothGattDescriptor in project nikeplus-fuelband-se-reversed by evilsocket.
the class BLEIoQueue method next.
private void next() {
BLEIoOperation op = _ops.poll();
if (op == null) {
Logger.d("No I/O operations to execute.");
return;
}
_current = op;
boolean ok = false;
BluetoothGattDescriptor desc = op.get_descriptor();
BluetoothGattCharacteristic charact = op.get_characteristic();
byte[] data = op.get_data();
if (op.get_type() == Type.NOTIFY_START) {
ok = _gatt.setCharacteristicNotification(charact, true);
if (ok) {
desc.setValue(BluetoothGattDescriptor.ENABLE_NOTIFICATION_VALUE);
ok = _gatt.writeDescriptor(desc);
}
} else if (op.get_type() == Type.WRITE_DESCRIPTOR) {
desc.setValue(data);
ok = _gatt.writeDescriptor(desc);
} else if (op.get_type() == Type.WRITE_CHARACTERISTICS) {
charact.setValue(data);
Packet p = new Packet(charact.getValue());
Logger.d(">> " + p.toString());
ok = _gatt.writeCharacteristic(charact);
} else if (op.get_type() == Type.READ_CHARACTERISTICS) {
ok = _gatt.readCharacteristic(charact);
} else {
Logger.e("Unhandled Operation");
}
if (ok == false) {
Logger.e("Operation failed, fetching next ...");
next();
}
}
use of android.bluetooth.BluetoothGattDescriptor 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.BluetoothGattDescriptor in project Android-Developers-Samples by johnjohndoe.
the class BluetoothLeService method setCharacteristicNotification.
/**
* Enables or disables notification on a give characteristic.
*
* @param characteristic Characteristic to act on.
* @param enabled If true, enable notification. False otherwise.
*/
public void setCharacteristicNotification(BluetoothGattCharacteristic characteristic, boolean enabled) {
if (mBluetoothAdapter == null || mBluetoothGatt == null) {
Log.w(TAG, "BluetoothAdapter not initialized");
return;
}
mBluetoothGatt.setCharacteristicNotification(characteristic, enabled);
// This is specific to Heart Rate Measurement.
if (UUID_HEART_RATE_MEASUREMENT.equals(characteristic.getUuid())) {
BluetoothGattDescriptor descriptor = characteristic.getDescriptor(UUID.fromString(SampleGattAttributes.CLIENT_CHARACTERISTIC_CONFIG));
descriptor.setValue(BluetoothGattDescriptor.ENABLE_NOTIFICATION_VALUE);
mBluetoothGatt.writeDescriptor(descriptor);
}
}
use of android.bluetooth.BluetoothGattDescriptor in project Gadgetbridge by Freeyourgadget.
the class PebbleGATTClient method subscribeToConnectionParams.
private void subscribeToConnectionParams(BluetoothGatt gatt) {
LOG.info("subscribing to connection parameters characteristic");
BluetoothGattDescriptor descriptor = gatt.getService(SERVICE_UUID).getCharacteristic(CONNECTION_PARAMETERS_CHARACTERISTIC).getDescriptor(CHARACTERISTIC_CONFIGURATION_DESCRIPTOR);
descriptor.setValue(BluetoothGattDescriptor.ENABLE_NOTIFICATION_VALUE);
gatt.writeDescriptor(descriptor);
gatt.setCharacteristicNotification(gatt.getService(SERVICE_UUID).getCharacteristic(CONNECTION_PARAMETERS_CHARACTERISTIC), true);
}
use of android.bluetooth.BluetoothGattDescriptor in project nikeplus-fuelband-se-reversed by evilsocket.
the class MainActivity method dumpServices.
private void dumpServices(BluetoothGatt gatt) {
for (BluetoothGattService svc : gatt.getServices()) {
String svc_uuid = svc.getUuid().toString(), svc_name = GATTAttributes.lookup(svc_uuid, "");
Logger.d("SERVICE " + svc_name + " ( " + svc_uuid + " )");
for (BluetoothGattCharacteristic chara : svc.getCharacteristics()) {
String chr_uuid = chara.getUuid().toString(), chr_name = GATTAttributes.lookup(chr_uuid, "");
int chr_props = chara.getProperties();
String props = "";
Iterator it = propsMap.entrySet().iterator();
while (it.hasNext()) {
Map.Entry pairs = (Map.Entry) it.next();
if ((chr_props & (Integer) pairs.getKey()) != 0) {
props += pairs.getValue().toString() + " ";
}
}
Logger.d(" " + chr_name + " ( " + chr_uuid + " ) [" + props + "] : " + Utils.bytesToHex(chara.getValue()));
for (BluetoothGattDescriptor desc : chara.getDescriptors()) {
Logger.d(" DESC: " + desc.getUuid());
}
}
}
Logger.d("---------------------------------------------------------------------------");
}
Aggregations