public interface Device1 extends DBusInterface {

    /**
     * <b>From bluez documentation:</b><br>
     * <br>
     * This is a generic method to connect any profiles<br>
     * the remote device supports that can be connected<br>
     * to and have been flagged as auto-connectable on<br>
     * our side. If only subset of profiles is already<br>
     * connected it will try to connect currently disconnected<br>
     * ones.<br>
     * <br>
     * If at least one profile was connected successfully this<br>
     * method will indicate success.<br>
     * <br>
     * For dual-mode devices only one bearer is connected at<br>
     * time, the conditions are in the following order:<br>
     * <br>
     * 	1. Connect the disconnected bearer if already<br>
     * 	connected.<br>
     * <br>
     * 	2. Connect first the bonded bearer. If no<br>
     * 	bearers are bonded or both are skip and check<br>
     * 	latest seen bearer.<br>
     * <br>
     * 	3. Connect last seen bearer, in case the<br>
     * 	timestamps are the same BR/EDR takes<br>
     * 	precedence.<br>
     * <br>
     * 
     * @throws BluezNotReadyException when bluez not ready
     * @throws BluezFailedException on failure
     * @throws BluezInProgressException when operation already in progress
     * @throws BluezAlreadyConnectedException when already connected
     */
    void Connect() throws BluezNotReadyException, BluezFailedException, BluezInProgressException, BluezAlreadyConnectedException;

    /**
     * <b>From bluez documentation:</b><br>
     * <br>
     * This method gracefully disconnects all connected<br>
     * profiles and then terminates low-level ACL connection.<br>
     * <br>
     * ACL connection will be terminated even if some profiles<br>
     * were not disconnected properly e.g. due to misbehaving<br>
     * device.<br>
     * <br>
     * This method can be also used to cancel a preceding<br>
     * Connect call before a reply to it has been received.<br>
     * <br>
     * For non-trusted devices connected over LE bearer calling<br>
     * this method will disable incoming connections until<br>
     * Connect method is called again.<br>
     * <br>
     * 
     * @throws BluezNotConnectedException when bluez not connected
     */
    void Disconnect() throws BluezNotConnectedException;

    /**
     * <b>From bluez documentation:</b><br>
     * <br>
     * This method connects a specific profile of this<br>
     * device. The UUID provided is the remote service<br>
     * UUID for the profile.<br>
     * <br>
     * 
     * @param _uuid uuid
     * 
     * @throws BluezFailedException on failure
     * @throws BluezInProgressException when operation already in progress
     * @throws BluezInvalidArgumentsException when argument is invalid
     * @throws BluezNotAvailableException when not available
     * @throws BluezNotReadyException when bluez not ready
     */
    void ConnectProfile(String _uuid) throws BluezFailedException, BluezInProgressException, BluezInvalidArgumentsException, BluezNotAvailableException, BluezNotReadyException;

    /**
     * <b>From bluez documentation:</b><br>
     * <br>
     * This method disconnects a specific profile of<br>
     * this device. The profile needs to be registered<br>
     * client profile.<br>
     * <br>
     * There is no connection tracking for a profile, so<br>
     * as long as the profile is registered this will always<br>
     * succeed.<br>
     * <br>
     * 
     * @param _uuid uuid
     * 
     * @throws BluezFailedException on failure
     * @throws BluezInProgressException when operation already in progress
     * @throws BluezInvalidArgumentsException when argument is invalid
     * @throws BluezNotSupportedException when operation not supported
     */
    void DisconnectProfile(String _uuid) throws BluezFailedException, BluezInProgressException, BluezInvalidArgumentsException, BluezNotSupportedException;

    /**
     * <b>From bluez documentation:</b><br>
     * <br>
     * This method will connect to the remote device,<br>
     * initiate pairing and then retrieve all SDP records<br>
     * (or GATT primary services).<br>
     * <br>
     * If the application has registered its own agent,<br>
     * then that specific agent will be used. Otherwise<br>
     * it will use the default agent.<br>
     * <br>
     * Only for applications like a pairing wizard it<br>
     * would make sense to have its own agent. In almost<br>
     * all other cases the default agent will handle<br>
     * this just fine.<br>
     * <br>
     * In case there is no application agent and also<br>
     * no default agent present, this method will fail.<br>
     * <br>
     * 
     * @throws BluezInvalidArgumentsException when argument is invalid
     * @throws BluezFailedException on failure
     * @throws BluezAlreadyExistsException when item already exists
     * @throws BluezAuthenticationCanceledException on BluezAuthenticationCanceledException
     * @throws BluezAuthenticationFailedException when authentication failed
     * @throws BluezAuthenticationRejectedException on BluezAuthenticationRejectedException
     * @throws BluezAuthenticationTimeoutException when authentication timed out
     * @throws BluezConnectionAttemptFailedException when connection attempt failed
     */
    void Pair() throws BluezInvalidArgumentsException, BluezFailedException, BluezAlreadyExistsException, BluezAuthenticationCanceledException, BluezAuthenticationFailedException, BluezAuthenticationRejectedException, BluezAuthenticationTimeoutException, BluezConnectionAttemptFailedException;

    /**
     * <b>From bluez documentation:</b><br>
     * <br>
     * This method can be used to cancel a pairing<br>
     * operation initiated by the Pair method.<br>
     * <br>
     * 
     * @throws BluezDoesNotExistException when item does not exist
     * @throws BluezFailedException on failure
     */
    void CancelPairing() throws BluezDoesNotExistException, BluezFailedException;

} public interface GattService1 extends DBusInterface {

} @SuppressWarnings("serial")
public class BluezAlreadyConnectedException extends DBusException {

    public BluezAlreadyConnectedException(String _message) {
        super(_message);
    }

} @SuppressWarnings("serial")
public class BluezAlreadyExistsException extends DBusException {

    public BluezAlreadyExistsException(String _message) {
        super(_message);
    }

} @SuppressWarnings("serial")
public class BluezAuthenticationCanceledException extends DBusException {

    public BluezAuthenticationCanceledException(String _message) {
        super(_message);
    }

} @SuppressWarnings("serial")
public class BluezAuthenticationFailedException extends DBusException {

    public BluezAuthenticationFailedException(String _message) {
        super(_message);
    }

} @SuppressWarnings("serial")
public class BluezAuthenticationRejectedException extends DBusException {

    public BluezAuthenticationRejectedException(String _message) {
        super(_message);
    }

} @SuppressWarnings("serial")
public class BluezAuthenticationTimeoutException extends DBusException {

    public BluezAuthenticationTimeoutException(String _message) {
        super(_message);
    }

} @SuppressWarnings("serial")
public class BluezConnectionAttemptFailedException extends DBusException {

    public BluezConnectionAttemptFailedException(String _message) {
        super(_message);
    }

} @SuppressWarnings("serial")
public class BluezDoesNotExistException extends DBusException {

    public BluezDoesNotExistException(String _message) {
        super(_message);
    }

} @SuppressWarnings("serial")
public class BluezFailedException extends DBusException {

    public BluezFailedException(String _message) {
        super(_message);
    }

} @SuppressWarnings("serial")
public class BluezInProgressException extends DBusException {

    public BluezInProgressException(String _message) {
        super(_message);
    }

} @SuppressWarnings("serial")
public class BluezInvalidArgumentsException extends DBusException {

    public BluezInvalidArgumentsException(String _message) {
        super(_message);
    }

} @SuppressWarnings("serial")
public class BluezNotAvailableException extends DBusException {

    public BluezNotAvailableException(String _message) {
        super(_message);
    }

} @SuppressWarnings("serial")
public class BluezNotConnectedException extends DBusException {

    public BluezNotConnectedException(String _message) {
        super(_message);
    }

} @SuppressWarnings("serial")
public class BluezNotReadyException extends DBusException {

    public BluezNotReadyException(String _message) {
        super(_message);
    }

} @SuppressWarnings("serial")
public class BluezNotSupportedException extends DBusException {

    public BluezNotSupportedException(String _message) {
        super(_message);
    }

} public final class DbusHelper {

    private static final Logger LOGGER = LoggerFactory.getLogger(DbusHelper.class);

    private DbusHelper() {

    }

    /**
     * Find all &lt;node&gt;-Elements in DBUS Introspection XML and extracts the value of the 'name' attribute.
     * @param _connection the dbus connection
     * @param _path dbus-path-to-introspect
     * @return Set of String, maybe empty but never null
     */
    public static Set<String> findNodes(DBusConnection _connection, String _path) {
        Set<String> foundNodes = new LinkedHashSet<>();
        if (_connection == null || _path == null || _path.trim().isEmpty()) {
            return foundNodes;
        }
        try {
            Introspectable remoteObject = _connection.getRemoteObject("org.bluez", _path, Introspectable.class);
            String introspect = remoteObject.Introspect();
            Document doc = XmlHelper.parseXmlString(introspect);
            NodeList nodes = XmlHelper.applyXpathExpressionToDocument("/node/node", doc);
            for (int i = 0; i < nodes.getLength(); i++) {
                if (nodes.item(i) instanceof Element) {
                    Element elem = (Element) nodes.item(i);
                    foundNodes.add(elem.getAttribute("name"));
                }
            }
            return foundNodes;
        } catch (DBusException _ex) {
            LOGGER.info("Exception while search DBus.", _ex);
        } catch (IOException _ex) {
            LOGGER.error("Exception while applying Xpath to introspection result", _ex);
        } catch (Exception _ex) {
            LOGGER.error("Critical error while reading DBUS response (maybe no bluetoothd daemon running?)", _ex);
        }
        return foundNodes;
    }

    /**
     * Creates an java object from a bluez dbus response.
     * @param _connection Dbus connection to use
     * @param _path dbus request path
     * @param _objClass interface class to use
     * @param <T> some class/interface implementing/extending {@link DBusInterface}
     * @return the created object or null on error
     */
    public static <T extends DBusInterface> T getRemoteObject(DBusConnection _connection, String _path, Class<T> _objClass) {
        try {
            return _connection.getRemoteObject("org.bluez", _path, _objClass);
        } catch (DBusException _ex) {
            LOGGER.warn("Error while converting dbus response to object.", _ex);
        }
        return null;
    }

}
import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
import org.bluez.Device1;
import org.bluez.GattService1;
import org.bluez.exceptions.BluezAlreadyConnectedException;
import org.bluez.exceptions.BluezAlreadyExistsException;
import org.bluez.exceptions.BluezAuthenticationCanceledException;
import org.bluez.exceptions.BluezAuthenticationFailedException;
import org.bluez.exceptions.BluezAuthenticationRejectedException;
import org.bluez.exceptions.BluezAuthenticationTimeoutException;
import org.bluez.exceptions.BluezConnectionAttemptFailedException;
import org.bluez.exceptions.BluezDoesNotExistException;
import org.bluez.exceptions.BluezFailedException;
import org.bluez.exceptions.BluezInProgressException;
import org.bluez.exceptions.BluezInvalidArgumentsException;
import org.bluez.exceptions.BluezNotAvailableException;
import org.bluez.exceptions.BluezNotConnectedException;
import org.bluez.exceptions.BluezNotReadyException;
import org.bluez.exceptions.BluezNotSupportedException;
import org.freedesktop.dbus.DBusMap;
import org.freedesktop.dbus.connections.impl.DBusConnection;
import org.freedesktop.dbus.exceptions.DBusExecutionException;
import org.freedesktop.dbus.interfaces.DBusInterface;
import org.freedesktop.dbus.types.UInt16;
import org.freedesktop.dbus.types.UInt32;
import com.github.hypfvieh.DbusHelper;
        try {
            rawdevice.Connect();
        } catch (BluezNotReadyException _ex) {
        } catch (BluezFailedException _ex) {
        } catch (BluezAlreadyConnectedException _ex) {
            return true;
        } catch (BluezInProgressException _ex) {
            return false;
        }
        return isConnected();
    }

    /**
     * <b>From bluez Documentation:</b>
     * <p>
     * This method gracefully disconnects all connected<br>
     * profiles and then terminates low-level ACL connection.<br>
     * ACL connection will be terminated even if some profiles<br>
     * were not disconnected properly e.g. due to misbehaving<br>
     * device.<br><br>
     * This method can be also used to cancel a preceding<br>
     * Connect call before a reply to it has been received.
     * </p>
     * @return true if disconnected false otherwise
     */
    public boolean disconnect() {
        try {
            rawdevice.Disconnect();
            return true;
        } catch (BluezNotConnectedException _ex) {
        }
        return !isConnected();
    }

    /**
     * <b>From bluez Documentation:</b>
     * <p>
     * This method connects a specific profile of this<br>
     * device. The UUID provided is the remote service<br>
     * UUID for the profile.
     * </p>
     *
     * @param _uuid profile uuid
     * @return true if connected to given profile, false otherwise
     */
    public boolean connectProfile(String _uuid) {
        try {
            rawdevice.ConnectProfile(_uuid);
            return true;
        } catch (BluezFailedException | BluezInProgressException | BluezInvalidArgumentsException
                | BluezNotAvailableException | BluezNotReadyException _ex) {
            return false;
        }
    }

    /**
     * <b>From bluez Documentation:</b>
     * <p>
     * This method disconnects a specific profile of<br>
     * this device. The profile needs to be registered<br>
     * client profile.<br><br>
     * There is no connection tracking for a profile, so<br>
     * as long as the profile is registered this will always<br>
     * succeed.
     * </p>
     *
     * @param _uuid profile uuid
     * @return true if profile disconnected, false otherwise
     */
    public boolean disconnectProfile(String _uuid) {
        try {
            rawdevice.DisconnectProfile(_uuid);
        } catch (BluezFailedException | BluezInProgressException | BluezInvalidArgumentsException
                | BluezNotSupportedException _ex) {
            return false;
        }

        return true;
    }

    /**
     * <b>From bluez Documentation:</b>
     * <p>
     * This method will connect to the remote device,<br>
     * initiate pairing and then retrieve all SDP records<br>
     * (or GATT primary services).<br><br>
     * If the application has registered its own agent,<br>
     * then that specific agent will be used. Otherwise<br>
     * it will use the default agent.<br><br>
     * Only for applications like a pairing wizard it<br>
     * would make sense to have its own agent. In almost<br>
     * all other cases the default agent will handle<br>
     * this just fine.<br><br>
     * In case there is no application agent and also<br>
     * no default agent present, this method will fail.
     * </p>
     * @return true on successful pair, false otherwise
     */
    public boolean pair() {
        try {
            rawdevice.Pair();
            return true;
        } catch (BluezInvalidArgumentsException | BluezFailedException | BluezAuthenticationFailedException | BluezAlreadyExistsException | BluezAuthenticationCanceledException | BluezAuthenticationRejectedException | BluezAuthenticationTimeoutException | BluezConnectionAttemptFailedException _ex) {
            return false;
        }
    }


    /**
     * <b>From bluez Documentation:</b>
     * <p>
     * This method can be used to cancel a pairing<br>
     * operation initiated by the Pair method.
     * </p>
     * @return true if cancel succeeds, false otherwise
     */
    public boolean cancelPairing() {
        try {
            rawdevice.CancelPairing();
            return true;
        } catch (BluezDoesNotExistException | BluezFailedException _ex) {