All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.sputnikdev.bluetooth.manager.impl.CharacteristicGovernorImpl Maven / Gradle / Ivy

package org.sputnikdev.bluetooth.manager.impl;

/*-
 * #%L
 * org.sputnikdev:bluetooth-manager
 * %%
 * Copyright (C) 2017 Sputnik Dev
 * %%
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 * 
 *      http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 * #L%
 */

import java.util.Arrays;
import java.util.List;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.sputnikdev.bluetooth.URL;
import org.sputnikdev.bluetooth.manager.BluetoothGovernor;
import org.sputnikdev.bluetooth.manager.BluetoothObjectType;
import org.sputnikdev.bluetooth.manager.BluetoothObjectVisitor;
import org.sputnikdev.bluetooth.manager.CharacteristicGovernor;
import org.sputnikdev.bluetooth.manager.NotReadyException;
import org.sputnikdev.bluetooth.manager.ValueListener;
import tinyb.BluetoothException;

/**
 *
 * @author Vlad Kolotov
 */
class CharacteristicGovernorImpl extends BluetoothObjectGovernor implements CharacteristicGovernor {

    private Logger logger = LoggerFactory.getLogger(CharacteristicGovernorImpl.class);

    private ValueListener valueListener;
    private ValueNotification valueNotification;

    CharacteristicGovernorImpl(BluetoothManagerImpl bluetoothManager, URL url) {
        super(bluetoothManager, url);
    }

    @Override
    Characteristic findBluetoothObject() {
        return BluetoothObjectFactory.getDefault().getCharacteristic(getURL());
    }

    @Override
    void init(Characteristic characteristic) {
        enableNotification(characteristic);
    }

    @Override
    void update(Characteristic characteristic) { }

    @Override
    void reset(Characteristic characteristic) {
        logger.info("Disable characteristic notifications: " + getURL());
        if (characteristic.isNotifying()) {
            characteristic.disableValueNotifications();
            valueNotification = null;
        }
    }

    @Override
    public void addValueListener(ValueListener valueListener) {
        this.valueListener = valueListener;
    }

    @Override
    public void removeValueListener(ValueListener valueListener) {
        this.valueListener = null;
    }

    @Override
    public String[] getFlags() throws NotReadyException {
        return getBluetoothObject().getFlags();
    }

    @Override
    public boolean isNotifiable() throws NotReadyException {
        List flgs = Arrays.asList(getFlags());
        return flgs.contains(NOTIFY_FLAG) || flgs.contains(INDICATE_FLAG);
    }

    @Override
    public boolean isWritable() throws NotReadyException {
        return Arrays.asList(getFlags()).contains(WRITE_FLAG);
    }

    @Override
    public boolean isReadable() throws NotReadyException {
        return Arrays.asList(getFlags()).contains(READ_FLAG);
    }

    @Override
    public byte[] read() throws NotReadyException {
        Characteristic characteristic = getBluetoothObject();
        if (characteristic == null) {
            throw new IllegalStateException("Characteristic governor is not initialized");
        }
        byte[] result = characteristic.readValue();
        updateLastChanged();
        return result;
    }

    @Override
    public boolean write(byte[] data) throws NotReadyException {
        Characteristic characteristic = getBluetoothObject();
        if (characteristic == null) {
            throw new IllegalStateException("Characteristic governor is not initialized");
        }
        boolean result = characteristic.writeValue(data);
        updateLastChanged();
        return result;
    }

    @Override
    public String toString() {
        return "[Characteristic] " + getURL();
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) {
            return true;
        }
        if (o == null || getClass() != o.getClass()) {
            return false;
        }

        BluetoothGovernor that = (BluetoothGovernor) o;
        return url.equals(that.getURL());
    }

    @Override
    public int hashCode() {
        int result = url.hashCode();
        result = 31 * result + url.hashCode();
        return result;
    }

    @Override
    public BluetoothObjectType getType() {
        return BluetoothObjectType.CHARACTERISTIC;
    }

    @Override
    public void accept(BluetoothObjectVisitor visitor) throws Exception {
        visitor.visit(this);
    }

    private void enableNotification(Characteristic characteristic) {
        logger.info("Enable characteristic notifications: " + getURL());
        this.valueNotification = new ValueNotification();
        if (canNotify(characteristic) && !characteristic.isNotifying()) {
            characteristic.enableValueNotifications(valueNotification);
        }
    }

    private static boolean canNotify(Characteristic characteristic) {
        List flgs = Arrays.asList(characteristic.getFlags());
        return flgs.contains(NOTIFY_FLAG) || flgs.contains(INDICATE_FLAG);
    }

    private class ValueNotification implements Notification {
        @Override
        public void notify(byte[] data) {
            try {
                ValueListener listener = valueListener;
                if (listener != null) {
                    listener.changed(data);
                }
            } catch (BluetoothException ex) {
                logger.error("Execution error of a characteristic listener", ex);
            }
        }
    }

}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy