Search in sources :

Example 1 with BluetoothService

use of org.eclipse.smarthome.binding.bluetooth.BluetoothService in project smarthome by eclipse.

the class BlueZBluetoothDevice method refreshServices.

protected void refreshServices() {
    if (device.getServices().size() > getServices().size()) {
        for (BluetoothGattService tinybService : device.getServices()) {
            BluetoothService service = new BluetoothService(UUID.fromString(tinybService.getUUID()), tinybService.getPrimary());
            for (BluetoothGattCharacteristic tinybCharacteristic : tinybService.getCharacteristics()) {
                BluetoothCharacteristic characteristic = new BluetoothCharacteristic(UUID.fromString(tinybCharacteristic.getUUID()), 0);
                for (BluetoothGattDescriptor tinybDescriptor : tinybCharacteristic.getDescriptors()) {
                    BluetoothDescriptor descriptor = new BluetoothDescriptor(characteristic, UUID.fromString(tinybDescriptor.getUUID()));
                    characteristic.addDescriptor(descriptor);
                }
                service.addCharacteristic(characteristic);
            }
            addService(service);
        }
        notifyListeners(BluetoothEventType.SERVICES_DISCOVERED);
    }
}
Also used : BluetoothDescriptor(org.eclipse.smarthome.binding.bluetooth.BluetoothDescriptor) BluetoothService(org.eclipse.smarthome.binding.bluetooth.BluetoothService) BluetoothCharacteristic(org.eclipse.smarthome.binding.bluetooth.BluetoothCharacteristic) BluetoothGattService(tinyb.BluetoothGattService) BluetoothGattDescriptor(tinyb.BluetoothGattDescriptor) BluetoothGattCharacteristic(tinyb.BluetoothGattCharacteristic)

Example 2 with BluetoothService

use of org.eclipse.smarthome.binding.bluetooth.BluetoothService in project smarthome by eclipse.

the class BlueGigaBluetoothDevice method bluegigaEventReceived.

@Override
public void bluegigaEventReceived(BlueGigaResponse event) {
    if (event instanceof BlueGigaScanResponseEvent) {
        BlueGigaScanResponseEvent scanEvent = (BlueGigaScanResponseEvent) event;
        // Check if this is addressed to this device
        if (!address.equals(new BluetoothAddress(scanEvent.getSender()))) {
            return;
        }
        // Set device properties
        rssi = scanEvent.getRssi();
        addressType = scanEvent.getAddressType();
        byte[] manufacturerData = null;
        // If the packet contains data, then process it and add anything relevant to the device...
        if (scanEvent.getData() != null) {
            EirPacket eir = new EirPacket(scanEvent.getData());
            for (EirDataType record : eir.getRecords().keySet()) {
                switch(record) {
                    case EIR_FLAGS:
                        break;
                    case EIR_MANUFACTURER_SPECIFIC:
                        manufacturerData = (byte[]) eir.getRecord(EirDataType.EIR_MANUFACTURER_SPECIFIC);
                        if (manufacturerData.length > 2) {
                            int id = manufacturerData[0] + (manufacturerData[1] << 8);
                            manufacturer = id;
                        }
                        break;
                    case EIR_NAME_LONG:
                    case EIR_NAME_SHORT:
                        name = (String) eir.getRecord(record);
                        break;
                    case EIR_SLAVEINTERVALRANGE:
                        break;
                    case EIR_SVC_DATA_UUID128:
                        break;
                    case EIR_SVC_DATA_UUID16:
                        break;
                    case EIR_SVC_DATA_UUID32:
                        break;
                    case EIR_SVC_UUID128_INCOMPLETE:
                    case EIR_SVC_UUID16_COMPLETE:
                    case EIR_SVC_UUID16_INCOMPLETE:
                    case EIR_SVC_UUID32_COMPLETE:
                    case EIR_SVC_UUID32_INCOMPLETE:
                    case EIR_SVC_UUID128_COMPLETE:
                        // addServices((List<UUID>) eir.getRecord(record));
                        break;
                    case EIR_TXPOWER:
                        txPower = (int) eir.getRecord(EirDataType.EIR_TXPOWER);
                        break;
                    default:
                        break;
                }
            }
        }
        if (connectionState == ConnectionState.DISCOVERING) {
            // We want to wait for an advertisement and a scan response before we call this discovered.
            // The intention is to gather a reasonable amount of data about the device given devices send
            // different data in different packets...
            // Note that this is possible a bit arbitrary and may be refined later.
            scanResponses.add(scanEvent.getPacketType());
            if ((scanResponses.contains(ScanResponseType.CONNECTABLE_ADVERTISEMENT) || scanResponses.contains(ScanResponseType.DISCOVERABLE_ADVERTISEMENT) || scanResponses.contains(ScanResponseType.NON_CONNECTABLE_ADVERTISEMENT)) && scanResponses.contains(ScanResponseType.SCAN_RESPONSE)) {
                // Set our state to disconnected
                connectionState = ConnectionState.DISCONNECTED;
                connection = -1;
                // But notify listeners that the state is now DISCOVERED
                notifyListeners(BluetoothEventType.CONNECTION_STATE, new BluetoothConnectionStatusNotification(ConnectionState.DISCOVERED));
                // Notify the bridge - for inbox notifications
                bgHandler.deviceDiscovered(this);
            }
        }
        // Notify listeners of all scan records - for RSSI, beacon processing (etc)
        BluetoothScanNotification scanNotification = new BluetoothScanNotification();
        scanNotification.setRssi(scanEvent.getRssi());
        switch(scanEvent.getPacketType()) {
            case CONNECTABLE_ADVERTISEMENT:
            case DISCOVERABLE_ADVERTISEMENT:
            case NON_CONNECTABLE_ADVERTISEMENT:
                scanNotification.setBeaconType(BluetoothBeaconType.BEACON_ADVERTISEMENT);
                break;
            case SCAN_RESPONSE:
                scanNotification.setBeaconType(BluetoothBeaconType.BEACON_SCANRESPONSE);
                break;
            default:
                break;
        }
        if (manufacturerData != null) {
            scanNotification.setManufacturerData(manufacturerData);
        }
        notifyListeners(BluetoothEventType.SCAN_RECORD, scanNotification);
        return;
    }
    if (event instanceof BlueGigaGroupFoundEvent) {
        // A Service has been discovered
        BlueGigaGroupFoundEvent serviceEvent = (BlueGigaGroupFoundEvent) event;
        // If this is not our connection handle then ignore.
        if (connection != serviceEvent.getConnection()) {
            return;
        }
        logger.trace("BlueGiga Group: {} svcs={}", this, supportedServices);
        BluetoothService service = new BluetoothService(serviceEvent.getUuid(), true, serviceEvent.getStart(), serviceEvent.getEnd());
        addService(service);
        return;
    }
    if (event instanceof BlueGigaFindInformationFoundEvent) {
        // A Characteristic has been discovered
        BlueGigaFindInformationFoundEvent infoEvent = (BlueGigaFindInformationFoundEvent) event;
        // If this is not our connection handle then ignore.
        if (connection != infoEvent.getConnection()) {
            return;
        }
        logger.trace("BlueGiga FindInfo: {} svcs={}", this, supportedServices);
        BluetoothCharacteristic characteristic = new BluetoothCharacteristic(infoEvent.getUuid(), infoEvent.getChrHandle());
        BluetoothService service = getServiceByHandle(characteristic.getHandle());
        if (service == null) {
            logger.debug("BlueGiga: Unable to find service for handle {}", characteristic.getHandle());
            return;
        }
        characteristic.setService(service);
        service.addCharacteristic(characteristic);
        return;
    }
    if (event instanceof BlueGigaProcedureCompletedEvent) {
        BlueGigaProcedureCompletedEvent completedEvent = (BlueGigaProcedureCompletedEvent) event;
        // If this is not our connection handle then ignore.
        if (connection != completedEvent.getConnection()) {
            return;
        }
        if (procedureProgress == null) {
            logger.debug("BlueGiga procedure completed but procedure is null with connection {}, address {}", connection, address);
            return;
        }
        // The current procedure is now complete - move on...
        switch(procedureProgress) {
            case GET_SERVICES:
                // We've downloaded all services, now get the characteristics
                procedureProgress = BlueGigaProcedure.GET_CHARACTERISTICS;
                bgHandler.bgFindCharacteristics(connection);
                break;
            case GET_CHARACTERISTICS:
                // We've downloaded all characteristics
                procedureProgress = BlueGigaProcedure.NONE;
                notifyListeners(BluetoothEventType.SERVICES_DISCOVERED);
                break;
            case CHARACTERISTIC_READ:
                // The read failed
                notifyListeners(BluetoothEventType.CHARACTERISTIC_READ_COMPLETE, procedureCharacteristic, BluetoothCompletionStatus.ERROR);
                procedureProgress = BlueGigaProcedure.NONE;
                procedureCharacteristic = null;
                break;
            case CHARACTERISTIC_WRITE:
                // The write completed - failure or success
                BluetoothCompletionStatus result = completedEvent.getResult() == BgApiResponse.SUCCESS ? BluetoothCompletionStatus.SUCCESS : BluetoothCompletionStatus.ERROR;
                notifyListeners(BluetoothEventType.CHARACTERISTIC_WRITE_COMPLETE, procedureCharacteristic, result);
                procedureProgress = BlueGigaProcedure.NONE;
                procedureCharacteristic = null;
                break;
            default:
                break;
        }
        return;
    }
    if (event instanceof BlueGigaConnectionStatusEvent) {
        BlueGigaConnectionStatusEvent connectionEvent = (BlueGigaConnectionStatusEvent) event;
        // Check if this is addressed to this device
        if (!address.equals(new BluetoothAddress(connectionEvent.getAddress()))) {
            return;
        }
        // If we're connected, then remember the connection handle
        if (connectionEvent.getFlags().contains(ConnectionStatusFlag.CONNECTION_CONNECTED)) {
            connectionState = ConnectionState.CONNECTED;
            connection = connectionEvent.getConnection();
        }
        if (connectionEvent.getFlags().contains(ConnectionStatusFlag.CONNECTION_CONNECTED)) {
            notifyListeners(BluetoothEventType.CONNECTION_STATE, new BluetoothConnectionStatusNotification(connectionState));
        }
        return;
    }
    if (event instanceof BlueGigaDisconnectedEvent) {
        BlueGigaDisconnectedEvent disconnectedEvent = (BlueGigaDisconnectedEvent) event;
        // If this is not our connection handle then ignore.
        if (connection != disconnectedEvent.getConnection()) {
            return;
        }
        connectionState = ConnectionState.DISCONNECTED;
        connection = -1;
        notifyListeners(BluetoothEventType.CONNECTION_STATE, new BluetoothConnectionStatusNotification(connectionState));
        return;
    }
    if (event instanceof BlueGigaAttributeValueEvent) {
        // A read request has completed - update the characteristic
        BlueGigaAttributeValueEvent valueEvent = (BlueGigaAttributeValueEvent) event;
        BluetoothCharacteristic characteristic = getCharacteristicByHandle(valueEvent.getAttHandle());
        if (characteristic == null) {
            logger.debug("BlueGiga didn't find characteristic for event {}", event);
        } else {
            // If this is the characteristic we were reading, then send a read completion
            if (procedureProgress == BlueGigaProcedure.CHARACTERISTIC_READ && procedureCharacteristic != null && procedureCharacteristic.getHandle() == valueEvent.getAttHandle()) {
                procedureProgress = BlueGigaProcedure.NONE;
                procedureCharacteristic = null;
                notifyListeners(BluetoothEventType.CHARACTERISTIC_READ_COMPLETE, characteristic, BluetoothCompletionStatus.SUCCESS);
            }
            // Notify the user of the updated value
            notifyListeners(BluetoothEventType.CHARACTERISTIC_UPDATED, procedureCharacteristic);
        }
    }
}
Also used : BlueGigaFindInformationFoundEvent(org.eclipse.smarthome.binding.bluetooth.bluegiga.internal.command.attributeclient.BlueGigaFindInformationFoundEvent) BluetoothAddress(org.eclipse.smarthome.binding.bluetooth.BluetoothAddress) BluetoothCharacteristic(org.eclipse.smarthome.binding.bluetooth.BluetoothCharacteristic) BluetoothConnectionStatusNotification(org.eclipse.smarthome.binding.bluetooth.notification.BluetoothConnectionStatusNotification) BluetoothCompletionStatus(org.eclipse.smarthome.binding.bluetooth.BluetoothCompletionStatus) EirDataType(org.eclipse.smarthome.binding.bluetooth.bluegiga.internal.eir.EirDataType) EirPacket(org.eclipse.smarthome.binding.bluetooth.bluegiga.internal.eir.EirPacket) BlueGigaProcedureCompletedEvent(org.eclipse.smarthome.binding.bluetooth.bluegiga.internal.command.attributeclient.BlueGigaProcedureCompletedEvent) BluetoothService(org.eclipse.smarthome.binding.bluetooth.BluetoothService) BluetoothScanNotification(org.eclipse.smarthome.binding.bluetooth.notification.BluetoothScanNotification) BlueGigaGroupFoundEvent(org.eclipse.smarthome.binding.bluetooth.bluegiga.internal.command.attributeclient.BlueGigaGroupFoundEvent) BlueGigaAttributeValueEvent(org.eclipse.smarthome.binding.bluetooth.bluegiga.internal.command.attributeclient.BlueGigaAttributeValueEvent) BlueGigaDisconnectedEvent(org.eclipse.smarthome.binding.bluetooth.bluegiga.internal.command.connection.BlueGigaDisconnectedEvent) BlueGigaConnectionStatusEvent(org.eclipse.smarthome.binding.bluetooth.bluegiga.internal.command.connection.BlueGigaConnectionStatusEvent) BlueGigaScanResponseEvent(org.eclipse.smarthome.binding.bluetooth.bluegiga.internal.command.gap.BlueGigaScanResponseEvent)

Aggregations

BluetoothCharacteristic (org.eclipse.smarthome.binding.bluetooth.BluetoothCharacteristic)2 BluetoothService (org.eclipse.smarthome.binding.bluetooth.BluetoothService)2 BluetoothAddress (org.eclipse.smarthome.binding.bluetooth.BluetoothAddress)1 BluetoothCompletionStatus (org.eclipse.smarthome.binding.bluetooth.BluetoothCompletionStatus)1 BluetoothDescriptor (org.eclipse.smarthome.binding.bluetooth.BluetoothDescriptor)1 BlueGigaAttributeValueEvent (org.eclipse.smarthome.binding.bluetooth.bluegiga.internal.command.attributeclient.BlueGigaAttributeValueEvent)1 BlueGigaFindInformationFoundEvent (org.eclipse.smarthome.binding.bluetooth.bluegiga.internal.command.attributeclient.BlueGigaFindInformationFoundEvent)1 BlueGigaGroupFoundEvent (org.eclipse.smarthome.binding.bluetooth.bluegiga.internal.command.attributeclient.BlueGigaGroupFoundEvent)1 BlueGigaProcedureCompletedEvent (org.eclipse.smarthome.binding.bluetooth.bluegiga.internal.command.attributeclient.BlueGigaProcedureCompletedEvent)1 BlueGigaConnectionStatusEvent (org.eclipse.smarthome.binding.bluetooth.bluegiga.internal.command.connection.BlueGigaConnectionStatusEvent)1 BlueGigaDisconnectedEvent (org.eclipse.smarthome.binding.bluetooth.bluegiga.internal.command.connection.BlueGigaDisconnectedEvent)1 BlueGigaScanResponseEvent (org.eclipse.smarthome.binding.bluetooth.bluegiga.internal.command.gap.BlueGigaScanResponseEvent)1 EirDataType (org.eclipse.smarthome.binding.bluetooth.bluegiga.internal.eir.EirDataType)1 EirPacket (org.eclipse.smarthome.binding.bluetooth.bluegiga.internal.eir.EirPacket)1 BluetoothConnectionStatusNotification (org.eclipse.smarthome.binding.bluetooth.notification.BluetoothConnectionStatusNotification)1 BluetoothScanNotification (org.eclipse.smarthome.binding.bluetooth.notification.BluetoothScanNotification)1 BluetoothGattCharacteristic (tinyb.BluetoothGattCharacteristic)1 BluetoothGattDescriptor (tinyb.BluetoothGattDescriptor)1 BluetoothGattService (tinyb.BluetoothGattService)1