Search in sources :

Example 1 with BluetoothAddress

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

the class BlueGigaBridgeHandler method bluegigaEventReceived.

@SuppressWarnings({ "unused", "null" })
@Override
public void bluegigaEventReceived(@Nullable BlueGigaResponse event) {
    if (event instanceof BlueGigaScanResponseEvent) {
        BlueGigaScanResponseEvent scanEvent = (BlueGigaScanResponseEvent) event;
        // We use the scan event to add any devices we hear to the devices list
        // The device gets created, and then manages itself for discovery etc.
        BluetoothAddress sender = new BluetoothAddress(scanEvent.getSender());
        BlueGigaBluetoothDevice device;
        if (devices.get(sender) == null) {
            logger.debug("BlueGiga adding new device to adaptor {}: {}", address, sender);
            device = new BlueGigaBluetoothDevice(this, new BluetoothAddress(scanEvent.getSender()), scanEvent.getAddressType());
            devices.put(sender, device);
            deviceDiscovered(device);
        }
        return;
    }
    if (event instanceof BlueGigaConnectionStatusEvent) {
        BlueGigaConnectionStatusEvent connectionEvent = (BlueGigaConnectionStatusEvent) event;
        connections.put(connectionEvent.getConnection(), new BluetoothAddress(connectionEvent.getAddress()));
    }
    if (event instanceof BlueGigaDisconnectedEvent) {
        BlueGigaDisconnectedEvent disconnectedEvent = (BlueGigaDisconnectedEvent) event;
        connections.remove(disconnectedEvent.getConnection());
    }
}
Also used : BluetoothAddress(org.eclipse.smarthome.binding.bluetooth.BluetoothAddress) BlueGigaBluetoothDevice(org.eclipse.smarthome.binding.bluetooth.bluegiga.BlueGigaBluetoothDevice) 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)

Example 2 with BluetoothAddress

use of org.eclipse.smarthome.binding.bluetooth.BluetoothAddress 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)

Example 3 with BluetoothAddress

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

the class BlueGigaBridgeHandler method initialize.

@Override
public void initialize() {
    Object discovery = getConfig().get(BlueGigaAdapterConstants.PROPERTY_DISCOVERY);
    if (discovery != null && discovery.toString().equalsIgnoreCase(Boolean.FALSE.toString())) {
        discoveryActive = false;
        logger.debug("Deactivated discovery participation.");
    }
    final String portId = (String) getConfig().get(BlueGigaAdapterConstants.CONFIGURATION_PORT);
    if (portId == null) {
        updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.CONFIGURATION_ERROR, "Serial port must be configured!");
        return;
    }
    if (openSerialPort(portId, 115200)) {
        BlueGigaSerialHandler bgh = new BlueGigaSerialHandler(inputStream, outputStream);
        // Create and send the reset command to the dongle
        bgh.addEventListener(this);
        bgh.addHandlerListener(this);
        this.setBgHandler(bgh);
        updateStatus(ThingStatus.UNKNOWN);
        scheduler.submit(() -> {
            // Stop any procedures that are running
            bgStopProcedure();
            // Close all transactions
            BlueGigaCommand command = new BlueGigaGetConnectionsCommand();
            BlueGigaGetConnectionsResponse connectionsResponse = (BlueGigaGetConnectionsResponse) bgh.sendTransaction(command);
            if (connectionsResponse != null) {
                maxConnections = connectionsResponse.getMaxconn();
            }
            // Close all connections so we start from a known position
            for (int connection = 0; connection < maxConnections; connection++) {
                bgDisconnect(connection);
            }
            // Get our Bluetooth address
            command = new BlueGigaAddressGetCommand();
            BlueGigaAddressGetResponse addressResponse = (BlueGigaAddressGetResponse) bgh.sendTransaction(command);
            if (addressResponse != null) {
                address = new BluetoothAddress(addressResponse.getAddress());
                updateStatus(ThingStatus.ONLINE);
            } else {
                updateStatus(ThingStatus.OFFLINE);
            }
            command = new BlueGigaGetInfoCommand();
            BlueGigaGetInfoResponse infoResponse = (BlueGigaGetInfoResponse) bgh.sendTransaction(command);
            // Set mode to non-discoverable etc.
            // Not doing this will cause connection failures later
            bgSetMode();
            // Start passive scan
            bgStartScanning(false, passiveScanInterval, passiveScanWindow);
            Map<String, String> properties = editProperties();
            properties.put(BluetoothBindingConstants.PROPERTY_MAXCONNECTIONS, Integer.toString(maxConnections));
            properties.put(Thing.PROPERTY_FIRMWARE_VERSION, String.format("%d.%d", infoResponse.getMajor(), infoResponse.getMinor()));
            properties.put(Thing.PROPERTY_HARDWARE_VERSION, Integer.toString(infoResponse.getHardware()));
            properties.put(BlueGigaAdapterConstants.PROPERTY_PROTOCOL, Integer.toString(infoResponse.getProtocolVersion()));
            properties.put(BlueGigaAdapterConstants.PROPERTY_LINKLAYER, Integer.toString(infoResponse.getLlVersion()));
            updateProperties(properties);
        });
    } else {
        updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.OFFLINE.COMMUNICATION_ERROR, "Failed opening serial port.");
    }
}
Also used : BluetoothAddress(org.eclipse.smarthome.binding.bluetooth.BluetoothAddress) BlueGigaGetConnectionsResponse(org.eclipse.smarthome.binding.bluetooth.bluegiga.internal.command.system.BlueGigaGetConnectionsResponse) BlueGigaGetConnectionsCommand(org.eclipse.smarthome.binding.bluetooth.bluegiga.internal.command.system.BlueGigaGetConnectionsCommand) BlueGigaAddressGetResponse(org.eclipse.smarthome.binding.bluetooth.bluegiga.internal.command.system.BlueGigaAddressGetResponse) BlueGigaAddressGetCommand(org.eclipse.smarthome.binding.bluetooth.bluegiga.internal.command.system.BlueGigaAddressGetCommand) BlueGigaCommand(org.eclipse.smarthome.binding.bluetooth.bluegiga.internal.BlueGigaCommand) BlueGigaGetInfoCommand(org.eclipse.smarthome.binding.bluetooth.bluegiga.internal.command.system.BlueGigaGetInfoCommand) BlueGigaSerialHandler(org.eclipse.smarthome.binding.bluetooth.bluegiga.internal.BlueGigaSerialHandler) BlueGigaGetInfoResponse(org.eclipse.smarthome.binding.bluetooth.bluegiga.internal.command.system.BlueGigaGetInfoResponse)

Example 4 with BluetoothAddress

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

the class BlueZBridgeHandler method initialize.

@Override
public void initialize() {
    try {
        BluetoothManager.getBluetoothManager();
    } catch (UnsatisfiedLinkError e) {
        throw new IllegalStateException("BlueZ JNI connection cannot be established.", e);
    } catch (RuntimeException e) {
        // we do not get anything more specific from TinyB here
        if (e.getMessage().contains("AccessDenied")) {
            throw new IllegalStateException("Cannot access BlueZ stack due to permission problems. Make sure that your OS user is part of the 'bluetooth' group of BlueZ.");
        } else {
            throw new IllegalStateException("Cannot access BlueZ layer.", e);
        }
    }
    Object cfgAddress = getConfig().get(BlueZAdapterConstants.PROPERTY_ADDRESS);
    if (cfgAddress != null) {
        address = new BluetoothAddress(cfgAddress.toString());
    } else {
        updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.CONFIGURATION_ERROR, "address not set");
        return;
    }
    Object discovery = getConfig().get(BlueZAdapterConstants.PROPERTY_DISCOVERY);
    if (discovery != null && discovery.toString().equalsIgnoreCase(Boolean.FALSE.toString())) {
        discoveryActive = false;
        logger.debug("Deactivated discovery participation.");
    }
    logger.debug("Creating BlueZ adapter with address '{}'", address);
    for (tinyb.BluetoothAdapter a : BluetoothManager.getBluetoothManager().getAdapters()) {
        if (a.getAddress().equals(address.toString())) {
            adapter = a;
            updateStatus(ThingStatus.ONLINE);
            if (!adapter.getDiscovering()) {
                adapter.startDiscovery();
            }
            discoveryJob = scheduler.scheduleWithFixedDelay(() -> {
                checkForNewDevices();
            }, 0, 10, TimeUnit.SECONDS);
            return;
        }
    }
    updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.CONFIGURATION_ERROR, "No adapter for this address found.");
}
Also used : BluetoothAddress(org.eclipse.smarthome.binding.bluetooth.BluetoothAddress)

Aggregations

BluetoothAddress (org.eclipse.smarthome.binding.bluetooth.BluetoothAddress)4 BlueGigaConnectionStatusEvent (org.eclipse.smarthome.binding.bluetooth.bluegiga.internal.command.connection.BlueGigaConnectionStatusEvent)2 BlueGigaDisconnectedEvent (org.eclipse.smarthome.binding.bluetooth.bluegiga.internal.command.connection.BlueGigaDisconnectedEvent)2 BlueGigaScanResponseEvent (org.eclipse.smarthome.binding.bluetooth.bluegiga.internal.command.gap.BlueGigaScanResponseEvent)2 BluetoothCharacteristic (org.eclipse.smarthome.binding.bluetooth.BluetoothCharacteristic)1 BluetoothCompletionStatus (org.eclipse.smarthome.binding.bluetooth.BluetoothCompletionStatus)1 BluetoothService (org.eclipse.smarthome.binding.bluetooth.BluetoothService)1 BlueGigaBluetoothDevice (org.eclipse.smarthome.binding.bluetooth.bluegiga.BlueGigaBluetoothDevice)1 BlueGigaCommand (org.eclipse.smarthome.binding.bluetooth.bluegiga.internal.BlueGigaCommand)1 BlueGigaSerialHandler (org.eclipse.smarthome.binding.bluetooth.bluegiga.internal.BlueGigaSerialHandler)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 BlueGigaAddressGetCommand (org.eclipse.smarthome.binding.bluetooth.bluegiga.internal.command.system.BlueGigaAddressGetCommand)1 BlueGigaAddressGetResponse (org.eclipse.smarthome.binding.bluetooth.bluegiga.internal.command.system.BlueGigaAddressGetResponse)1 BlueGigaGetConnectionsCommand (org.eclipse.smarthome.binding.bluetooth.bluegiga.internal.command.system.BlueGigaGetConnectionsCommand)1 BlueGigaGetConnectionsResponse (org.eclipse.smarthome.binding.bluetooth.bluegiga.internal.command.system.BlueGigaGetConnectionsResponse)1 BlueGigaGetInfoCommand (org.eclipse.smarthome.binding.bluetooth.bluegiga.internal.command.system.BlueGigaGetInfoCommand)1 BlueGigaGetInfoResponse (org.eclipse.smarthome.binding.bluetooth.bluegiga.internal.command.system.BlueGigaGetInfoResponse)1