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

com.github.hypfvieh.bluetooth.wrapper.AbstractBluetoothObject Maven / Gradle / Ivy

The newest version!
package com.github.hypfvieh.bluetooth.wrapper;

import com.github.hypfvieh.DbusHelper;
import org.freedesktop.dbus.connections.impl.DBusConnection;
import org.freedesktop.dbus.exceptions.DBusException;
import org.freedesktop.dbus.exceptions.DBusExecutionException;
import org.freedesktop.dbus.interfaces.DBusInterface;
import org.freedesktop.dbus.interfaces.Properties;
import org.freedesktop.dbus.types.Variant;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.*;
import java.util.Map.Entry;

/**
 * Base class of all bluetooth wrapper object classes.
 *
 * @author hypfvieh
 *
 */
public abstract class AbstractBluetoothObject {

    private final Logger logger = LoggerFactory.getLogger(getClass());

    private final BluetoothDeviceType bluetoothType;
    private DBusConnection dbusConnection;
    private final String dbusPath;

    public AbstractBluetoothObject(BluetoothDeviceType _bluetoothType, DBusConnection _dbusConnection, String _dbusPath) {
        bluetoothType = _bluetoothType;
        dbusConnection = _dbusConnection;
        dbusPath = _dbusPath;
    }

    /**
     * DBus-Interface class used in this wrapper object.
     * @return class which implements the interface
     */
    protected abstract Class getInterfaceClass();

    public BluetoothDeviceType getBluetoothType() {
        return bluetoothType;
    }

    public String getDbusPath() {
        return dbusPath;
    }

    public DBusConnection getDbusConnection() {
        return dbusConnection;
    }

    /**
     * Helper to get remote objects from DBus.
     * @param _objectNames Set of object names to retrieve [e.g service0000, service0001]
     * @param _parentPath DBus parent path (objectName will be appended) [e.g. /org/bluez/hci0]
     * @param _type Expected DBusInterface type [e.g. Device1]
     * @param  class/interface extending {@link DBusInterface}
     * @return Map of string key and the given interface
     */
    protected  Map getRemoteObjects(Set _objectNames, String _parentPath, Class _type) {
        Map map = new LinkedHashMap<>();
        String path = _parentPath;
        // append slash to parent path if missing
        if (!_parentPath.endsWith("/")) {
            path += "/";
        }
        // iterate all object names
        for (String string : _objectNames) {
            T remoteObject = DbusHelper.getRemoteObject(getDbusConnection(), path + string, _type);
            map.put(path + string, remoteObject);
        }
        return map;
    }

    /**
     * Helper to get a value of a DBus property.
     * @param _field DBus property key
     * @param _type expected return type of DBus property
     * @param  class of the expected result
     * @return value of _field as _type class or null
     */
    protected  T getTyped(String _field, Class _type) {
        Objects.requireNonNull(_type, "Class required");
        Objects.requireNonNull(_field, "Property name required");

        try {
            Properties remoteObject = dbusConnection.getRemoteObject("org.bluez", dbusPath, Properties.class);
            Object obj = remoteObject.Get(getInterfaceClass().getName(), _field);
            if (_type.isAssignableFrom(obj.getClass())) {
                return _type.cast(obj);
            }

        } catch (DBusException | DBusExecutionException _ex) {
            logger.trace("Error while receiving data from DBUS (Field: {}, Type: {}).", _field, _type, _ex);
        }
        return null;
    }

    /**
     * Helper to set a value on a DBus property.
     *
     * @param _field DBus property key
     * @param _value value to set
     */
    protected void setTyped(String _field, Object _value) {
        try {
            Properties remoteObject = dbusConnection.getRemoteObject("org.bluez", dbusPath, Properties.class);
            remoteObject.Set(getInterfaceClass().getName(), _field, _value);
        } catch (DBusException _ex) {
            logger.trace("Error while setting data for DBUS (Field: {}, Value: {}).", _field, _value, _ex);
        }
    }

    /**
     * Convert options for read/write commands to the correct Map-type.
* DBus library uses a custom object class names 'variant' which is some sort of wrapper
* for any object. As the variant class 'allows' specifying the underlying object type, it produces
* lots of compiler warnings (rawtype).
*
* To get around that ugly behavior, this library uses Maps with object value.
* This method will convert the object values to variant values. * @param _options options map * @return map of variant, maybe empty but never null */ protected Map> optionsToVariantMap(Map _options) { Map> optionMap = new LinkedHashMap<>(); if (_options != null) { for (Entry entry : _options.entrySet()) { if (entry.getValue() == null) { // null values cannot be wrapped continue; } optionMap.put(entry.getKey(), new Variant<>(entry.getValue())); } } return optionMap; } protected byte[] byteListToByteArray(List _list) { if (_list == null) { return null; } if (_list.isEmpty()) { return new byte[] {}; } if (!Byte.class.isAssignableFrom(_list.get(0).getClass()) && !byte.class.isAssignableFrom(_list.get(0).getClass())) { return null; } byte[] result = new byte[_list.size()]; for (int i = 0; i < _list.size(); i++) { Object x = _list.get(i); result[i] = (byte) x; } return result; } /** * Convert Byte[] to byte[] array. * @param oBytes the array to convert * @return primitive byte array */ protected byte[] toPrimitives(Byte[] oBytes) { byte[] bytes = new byte[oBytes.length]; for (int i = 0; i < oBytes.length; i++) { bytes[i] = oBytes[i]; } return bytes; } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy