Search in sources :

Example 1 with BluetoothGatt

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);
}
Also used : BluetoothDevice(android.bluetooth.BluetoothDevice) Bundle(android.os.Bundle) BluetoothGattService(android.bluetooth.BluetoothGattService) Intent(android.content.Intent) BluetoothGattCharacteristic(android.bluetooth.BluetoothGattCharacteristic) ByteBuffer(java.nio.ByteBuffer) BluetoothGatt(android.bluetooth.BluetoothGatt) BluetoothGattDescriptor(android.bluetooth.BluetoothGattDescriptor) BluetoothAdapter(android.bluetooth.BluetoothAdapter)

Example 2 with BluetoothGatt

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;
}
Also used : BluetoothGatt(android.bluetooth.BluetoothGatt) BleRequestMtuOperation(com.afunx.ble.blelitelib.operation.BleRequestMtuOperation)

Example 3 with BluetoothGatt

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;
}
Also used : BleReadCharacteristicOperation(com.afunx.ble.blelitelib.operation.BleReadCharacteristicOperation) BluetoothGatt(android.bluetooth.BluetoothGatt)

Example 4 with BluetoothGatt

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;
}
Also used : BluetoothGatt(android.bluetooth.BluetoothGatt) BleWriteCharacteristicOperation(com.afunx.ble.blelitelib.operation.BleWriteCharacteristicOperation)

Example 5 with BluetoothGatt

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;
    }
}
Also used : BluetoothGatt(android.bluetooth.BluetoothGatt) BluetoothGattService(android.bluetooth.BluetoothGattService)

Aggregations

BluetoothGatt (android.bluetooth.BluetoothGatt)12 BluetoothGattService (android.bluetooth.BluetoothGattService)2 TargetApi (android.annotation.TargetApi)1 BluetoothAdapter (android.bluetooth.BluetoothAdapter)1 BluetoothDevice (android.bluetooth.BluetoothDevice)1 BluetoothGattCharacteristic (android.bluetooth.BluetoothGattCharacteristic)1 BluetoothGattDescriptor (android.bluetooth.BluetoothGattDescriptor)1 Intent (android.content.Intent)1 Bundle (android.os.Bundle)1 BleCloseOperation (com.afunx.ble.blelitelib.operation.BleCloseOperation)1 BleReadCharacteristicOperation (com.afunx.ble.blelitelib.operation.BleReadCharacteristicOperation)1 BleRequestMtuOperation (com.afunx.ble.blelitelib.operation.BleRequestMtuOperation)1 BleWriteCharacteristicOperation (com.afunx.ble.blelitelib.operation.BleWriteCharacteristicOperation)1 Constructor (java.lang.reflect.Constructor)1 InvocationTargetException (java.lang.reflect.InvocationTargetException)1 ByteBuffer (java.nio.ByteBuffer)1 BtLEAction (nodomain.freeyourgadget.gadgetbridge.service.btle.BtLEAction)1 ConditionalWriteAction (nodomain.freeyourgadget.gadgetbridge.service.btle.actions.ConditionalWriteAction)1 WriteAction (nodomain.freeyourgadget.gadgetbridge.service.btle.actions.WriteAction)1