summaryrefslogtreecommitdiffstats
path: root/bluetooth/bluetooth.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'bluetooth/bluetooth.cpp')
-rw-r--r--bluetooth/bluetooth.cpp369
1 files changed, 158 insertions, 211 deletions
diff --git a/bluetooth/bluetooth.cpp b/bluetooth/bluetooth.cpp
index 82ef2f1..c58b64b 100644
--- a/bluetooth/bluetooth.cpp
+++ b/bluetooth/bluetooth.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2018-2020 Konsulko Group
+ * Copyright (C) 2018-2021 Konsulko Group
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -16,301 +16,248 @@
#include <QDebug>
-#include "callmessage.h"
-#include "eventmessage.h"
-#include "responsemessage.h"
-#include "messagefactory.h"
-#include "messageengine.h"
-#include "messageenginefactory.h"
+#include <bluez-glib.h>
+
#include "bluetooth.h"
#include "bluetoothmodel.h"
+#include "bluetootheventhandler.h"
-Bluetooth::Bluetooth (QUrl &url, QQmlContext *context, QObject * parent) :
- QObject(parent),
- m_context(context)
+Bluetooth::Bluetooth (bool register_agent, QQmlContext *context, QObject * parent) :
+ QObject(parent),
+ m_context(context),
+ m_agent(register_agent)
{
- m_mloop = MessageEngineFactory::getInstance().getMessageEngine(url);
- m_bluetooth = new BluetoothModel();
- QObject::connect(m_mloop.get(), &MessageEngine::connected, this, &Bluetooth::onConnected);
- QObject::connect(m_mloop.get(), &MessageEngine::disconnected, this, &Bluetooth::onDisconnected);
- QObject::connect(m_mloop.get(), &MessageEngine::messageReceived, this, &Bluetooth::onMessageReceived);
-
- BluetoothModelFilter *m_model = new BluetoothModelFilter();
- m_model->setSourceModel(m_bluetooth);
- m_model->setFilterFixedString("true");
- context->setContextProperty("BluetoothPairedModel", m_model);
-
- m_model = new BluetoothModelFilter();
- m_model->setSourceModel(m_bluetooth);
- m_model->setFilterFixedString("false");
- context->setContextProperty("BluetoothDiscoveryModel", m_model);
-
- uuids.insert("a2dp", "0000110a-0000-1000-8000-00805f9b34fb");
- uuids.insert("avrcp", "0000110e-0000-1000-8000-00805f9b34fb");
- uuids.insert("hfp", "0000111f-0000-1000-8000-00805f9b34fb");
+ m_bluetooth = new BluetoothModel();
+ BluetoothModelFilter *m_model = new BluetoothModelFilter();
+ m_model->setSourceModel(m_bluetooth);
+ m_model->setFilterFixedString("true");
+ context->setContextProperty("BluetoothPairedModel", m_model);
+
+ m_model = new BluetoothModelFilter();
+ m_model->setSourceModel(m_bluetooth);
+ m_model->setFilterFixedString("false");
+ context->setContextProperty("BluetoothDiscoveryModel", m_model);
+
+ m_event_handler = new BluetoothEventHandler(this, register_agent);
+
+ uuids.insert("a2dp", "0000110a-0000-1000-8000-00805f9b34fb");
+ uuids.insert("avrcp", "0000110e-0000-1000-8000-00805f9b34fb");
+ uuids.insert("hfp", "0000111f-0000-1000-8000-00805f9b34fb");
}
Bluetooth::~Bluetooth()
{
}
-void Bluetooth::send_command(QString verb, QJsonObject parameter)
-{
- std::unique_ptr<Message> msg = MessageFactory::getInstance().createOutboundMessage(MessageId::Call);
- if (!msg)
- return;
-
- CallMessage* btmsg = static_cast<CallMessage*>(msg.get());
- btmsg->createRequest("Bluetooth-Manager", verb, parameter);
- m_mloop->sendMessage(std::move(msg));
-}
-
void Bluetooth::setPower(bool state)
{
- QJsonObject parameter;
- parameter.insert("powered", state ? "true" : "false");
- send_command("adapter_state", parameter);
+ bluez_adapter_set_powered(NULL, state ? TRUE : FALSE);
}
void Bluetooth::setDiscoverable(bool state)
{
- QJsonObject parameter;
- parameter.insert("discoverable", state ? "true" : "false");
- send_command("adapter_state", parameter);
+ bluez_adapter_set_discoverable(NULL, state);
- m_discoverable = state;
+ m_discoverable = state;
- emit discoverableChanged();
+ emit discoverableChanged();
}
-void Bluetooth::discovery_command(bool state)
+void Bluetooth::start()
{
- QJsonObject parameter;
- parameter.insert("discovery", state ? "true" : "false");
+ bluez_init(m_agent, m_agent, m_event_handler->init_cb, m_event_handler);
+}
- set_discovery_filter();
+void Bluetooth::discovery_command(bool state)
+{
+ set_discovery_filter();
- send_command("adapter_state", parameter);
+ bluez_adapter_set_discovery(NULL, state ? TRUE : FALSE);
}
void Bluetooth::start_discovery()
{
- discovery_command(true);
-
- // temp workaround to list already discovered devices
- send_command("managed_objects", QJsonObject());
+ discovery_command(true);
}
void Bluetooth::stop_discovery()
{
- discovery_command(false);
+ discovery_command(false);
}
void Bluetooth::remove_device(QString device)
{
- QJsonObject parameter;
- parameter.insert("device", device);
+ QByteArray device_ba = device.toLocal8Bit();
+ const char *device_cstr = device_ba.data();
- send_command("remove_device", parameter);
+ bluez_device_remove(device_cstr);
}
void Bluetooth::pair(QString device)
{
- QJsonObject parameter;
- parameter.insert("device", device);
+ QByteArray device_ba = device.toLocal8Bit();
+ const char *device_cstr = device_ba.data();
- send_command("pair", parameter);
+ bluez_device_pair(device_cstr, m_event_handler->device_pair_cb, m_event_handler);
}
-void Bluetooth::cancel_pair(QString device)
+void Bluetooth::cancel_pair(void)
{
- send_command("cancel_pairing", QJsonObject());
+ bluez_cancel_pairing();
}
void Bluetooth::connect(QString device, QString uuid)
{
- QJsonObject parameter;
- uuid = process_uuid(uuid);
- parameter.insert("device", device);
- parameter.insert("uuid", uuid);
- send_command("connect", parameter);
+ QByteArray device_ba = device.toLocal8Bit();
+ const char *device_cstr = device_ba.data();
+
+ uuid = process_uuid(uuid);
+ QByteArray uuid_ba = uuid.toLocal8Bit();
+ const char *uuid_cstr = uuid_ba.data();
+
+ bluez_device_connect(device_cstr,
+ uuid_cstr,
+ m_event_handler->device_connect_cb,
+ m_event_handler);
}
void Bluetooth::connect(QString device)
{
- QJsonObject parameter;
- parameter.insert("device", device);
- send_command("connect", parameter);
+ QByteArray device_ba = device.toLocal8Bit();
+ const char *device_cstr = device_ba.data();
+
+ bluez_device_connect(device_cstr,
+ NULL,
+ m_event_handler->device_connect_cb,
+ m_event_handler);
}
void Bluetooth::disconnect(QString device, QString uuid)
{
- QJsonObject parameter;
- uuid = process_uuid(uuid);
- parameter.insert("device", device);
- parameter.insert("uuid", uuid);
- send_command("disconnect", parameter);
-}
+ QByteArray device_ba = device.toLocal8Bit();
+ const char *device_cstr = device_ba.data();
-void Bluetooth::disconnect(QString device)
-{
- QJsonObject parameter;
- parameter.insert("device", device);
- send_command("disconnect", parameter);
-}
+ uuid = process_uuid(uuid);
+ QByteArray uuid_ba = uuid.toLocal8Bit();
+ const char *uuid_cstr = uuid_ba.data();
-void Bluetooth::send_confirmation(int pincode)
-{
- QJsonObject parameter;
- parameter.insert("pincode", pincode);
- send_command("confirm_pairing", parameter);
+ bluez_device_disconnect(device_cstr, uuid_cstr);
}
-
-void Bluetooth::set_discovery_filter()
+void Bluetooth::disconnect(QString device)
{
- QStringListIterator eventIterator(uuids.values());
- QJsonObject parameter;
- QJsonArray array;
-
- while (eventIterator.hasNext())
- array.push_back(eventIterator.next());
+ QByteArray device_ba = device.toLocal8Bit();
+ const char *device_cstr = device_ba.data();
- // send inital adapter state + discovery filter
- parameter.insert("filter", array);
- parameter.insert("transport", "bredr");
- send_command("adapter_state", parameter);
+ bluez_device_disconnect(device_cstr, NULL);
}
-void Bluetooth::onConnected()
+void Bluetooth::send_confirmation(int pincode)
{
- QStringListIterator eventIterator(events);
-
- while (eventIterator.hasNext()) {
- QJsonObject parameter;
- parameter.insert("value", eventIterator.next());
- send_command("subscribe", parameter);
- }
+ QString pincode_str;
+ pincode_str.setNum(pincode);
+ QByteArray pincode_ba = pincode_str.toLocal8Bit();
+ const char *pincode_cstr = pincode_ba.data();
- // send initial list
- send_command("managed_objects", QJsonObject());
-
- // get initial power state
- send_command("adapter_state", QJsonObject());
+ bluez_confirm_pairing(pincode_cstr);
}
-void Bluetooth::onDisconnected()
+void Bluetooth::init_adapter_state(QString adapter)
{
- QStringListIterator eventIterator(events);
+ // Get initial power state
+ GVariant *reply = NULL;
+ gboolean rc = bluez_adapter_get_state(NULL, &reply);
+ if (rc && reply) {
+ GVariantDict *props_dict = g_variant_dict_new(reply);
+ gboolean powered = FALSE;
+ if (g_variant_dict_lookup(props_dict, "Powered", "b", &powered)) {
+ if (m_power != powered) {
+ m_power = powered;
+ emit powerChanged(m_power);
+ }
+ }
+ g_variant_dict_unref(props_dict);
+ g_variant_unref(reply);
+ }
- while (eventIterator.hasNext()) {
- QJsonObject parameter;
- parameter.insert("value", eventIterator.next());
- send_command("unsubscribe", parameter);
- }
+ // Get initial device list
+ refresh_device_list();
}
-void Bluetooth::populateDeviceList(QJsonObject data)
+void Bluetooth::refresh_device_list(void)
{
- QJsonArray devices = data.value("devices").toArray();
-
- m_bluetooth->removeAllDevices();
-
- for (auto value : devices) {
- BluetoothDevice *device = m_bluetooth->updateDeviceProperties(nullptr, value.toObject());
- m_bluetooth->addDevice(device);
- }
+ gboolean rc;
+ GVariant *reply = NULL;
+
+ rc = bluez_adapter_get_devices(NULL, &reply);
+ if(!rc)
+ return;
+
+ m_bluetooth->removeAllDevices();
+
+ GVariantIter *array = NULL;
+ g_variant_get(reply, "a{sv}", &array);
+ const gchar *key = NULL;
+ GVariant *var = NULL;
+ while (g_variant_iter_next(array, "{&sv}", &key, &var)) {
+ BluetoothDevice *device = m_bluetooth->updateDeviceProperties(nullptr, key, var);
+ if (device)
+ m_bluetooth->addDevice(device);
+
+ g_variant_unref(var);
+ }
+ g_variant_iter_free(array);
+ g_variant_unref(reply);
}
-void Bluetooth::processDeviceChangesEvent(QJsonObject data)
+void Bluetooth::set_discovery_filter(void)
{
- QString action = data.value("action").toString();
- QString id = data.value("device").toString();
-
- if (id.isEmpty())
- return;
-
- BluetoothDevice *device = m_bluetooth->getDevice(id);
- if (action == "removed") {
- if (device != nullptr)
- m_bluetooth->removeDevice(device);
- return;
- }
-
- BluetoothDevice *ndevice = m_bluetooth->updateDeviceProperties(device, data);
- if (ndevice == nullptr) {
- qDebug() << "bt - failed to create device object with id: " << id;
- return;
- }
- if (device == nullptr) //device not previously in model
- m_bluetooth->addDevice(ndevice);
+ QList<QString> values = uuids.values();
+ QStringListIterator eventIterator(values);
+
+ gchar **uuids_array = (gchar**) g_malloc0((values.count() + 1) * sizeof(gchar*));
+ int i = 0;
+ while (eventIterator.hasNext()) {
+ QByteArray uuid_ba = eventIterator.next().toLocal8Bit();
+ gchar *uuid_cstr = g_strdup(uuid_ba.data());
+ uuids_array[i++] = uuid_cstr;
+ }
+
+ gchar *transport = g_strdup("bredr");
+ bluez_adapter_set_discovery_filter(NULL, uuids_array, transport);
+
+ for (i = 0; i < values.count(); i++)
+ g_free(uuids_array[i]);
+ g_free(uuids_array);
+ g_free(transport);
}
-void Bluetooth::processAdapterChangesEvent(QJsonObject data)
+void Bluetooth::update_adapter_power(bool powered)
{
- QString action = data.value("action").toString();
- if (action != "changed")
- return;
+ if (!powered)
+ m_bluetooth->removeAllDevices();
- QJsonObject properties = data.value("properties").toObject();
- if (!properties.contains("powered"))
- return;
+ if (m_power != powered) {
+ m_power = powered;
+ emit powerChanged(powered);
- bool powered = properties.find("powered").value().toBool();
- if (!powered)
- m_bluetooth->removeAllDevices();
+ if (powered)
+ refresh_device_list();
+ }
- if (m_power != powered) {
- m_power = powered;
- emit powerChanged(powered);
- }
- if (!m_power)
- m_discoverable = false;
+ if (!m_power) {
+ bool discoverable = m_discoverable;
+ m_discoverable = false;
+ if (discoverable != m_discoverable)
+ emit discoverableChanged();
+ }
}
-void Bluetooth::onMessageReceived(std::shared_ptr<Message> msg)
+void Bluetooth::request_confirmation(int pincode)
{
- if (!msg)
- return;
-
- if (msg->isEvent()) {
- std::shared_ptr<EventMessage> emsg = std::static_pointer_cast<EventMessage>(msg);
- QString ename = emsg->eventName();
- QString eapi = emsg->eventApi();
- QJsonObject data = emsg->eventData();
- if (eapi != "Bluetooth-Manager")
- return;
- if (ename == "device_changes") {
- processDeviceChangesEvent(data);
- } else if (ename == "adapter_changes") {
- processAdapterChangesEvent(data);
- } else if (ename == "agent") {
- emit requestConfirmationEvent(data);
- }
- } else if (msg->isReply()) {
- std::shared_ptr<ResponseMessage> rmsg = std::static_pointer_cast<ResponseMessage>(msg);
- QString verb = rmsg->requestVerb();
- QJsonObject data = rmsg->replyData();
- if (rmsg->requestApi() != "Bluetooth-Manager")
- return;
-
- if (rmsg->replyStatus() == "failed") {
- qDebug() << "failed bt verb:" << verb;
- if (rmsg->replyInfo().contains("No adapter")) {
- m_power = false;
- emit powerChanged(m_power);
- }
- }
- else if (verb == "managed_objects") {
- populateDeviceList(data);
- } else if (verb == "adapter_state") {
- bool powered = data.value("powered").toBool();
- if (m_power != powered) {
- m_power = powered;
- emit powerChanged(m_power);
- }
- }
- }
+ QString pincode_str;
+ pincode_str.setNum(pincode);
+ emit requestConfirmationEvent(pincode_str);
}