Search in sources :

Example 1 with BluetoothGattDescriptor

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

Example 2 with BluetoothGattDescriptor

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);
}
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 3 with BluetoothGattDescriptor

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

Example 4 with BluetoothGattDescriptor

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

Example 5 with BluetoothGattDescriptor

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("---------------------------------------------------------------------------");
}
Also used : Iterator(java.util.Iterator) BluetoothGattService(android.bluetooth.BluetoothGattService) BluetoothGattDescriptor(android.bluetooth.BluetoothGattDescriptor) BluetoothGattCharacteristic(android.bluetooth.BluetoothGattCharacteristic) HashMap(java.util.HashMap) Map(java.util.Map)

Aggregations

BluetoothGattDescriptor (android.bluetooth.BluetoothGattDescriptor)10 BluetoothGattCharacteristic (android.bluetooth.BluetoothGattCharacteristic)5 BluetoothGattService (android.bluetooth.BluetoothGattService)3 BluetoothAdapter (android.bluetooth.BluetoothAdapter)1 BluetoothDevice (android.bluetooth.BluetoothDevice)1 BluetoothGatt (android.bluetooth.BluetoothGatt)1 BluetoothManager (android.bluetooth.BluetoothManager)1 Intent (android.content.Intent)1 Bundle (android.os.Bundle)1 ByteBuffer (java.nio.ByteBuffer)1 HashMap (java.util.HashMap)1 Iterator (java.util.Iterator)1 Map (java.util.Map)1