mirror of
https://gitlab.freedesktop.org/monado/monado.git
synced 2025-01-19 21:28:50 +00:00
os/ble: Large refactor of code
This commit is contained in:
parent
5af976a510
commit
40c764a290
|
@ -22,12 +22,30 @@
|
||||||
#include <dbus/dbus.h>
|
#include <dbus/dbus.h>
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
*
|
||||||
|
* Defines.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define E(bch, ...) fprintf(stderr, __VA_ARGS__)
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
*
|
*
|
||||||
* Structs.
|
* Structs.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* Small helper that keeps track of a connection and a error.
|
||||||
|
*/
|
||||||
|
struct ble_conn_helper
|
||||||
|
{
|
||||||
|
DBusConnection *conn;
|
||||||
|
DBusError err;
|
||||||
|
};
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* An implementation of @ref os_ble_device using a DBus connection to BlueZ.
|
* An implementation of @ref os_ble_device using a DBus connection to BlueZ.
|
||||||
* @implements os_ble_device
|
* @implements os_ble_device
|
||||||
|
@ -35,8 +53,7 @@
|
||||||
struct ble_notify
|
struct ble_notify
|
||||||
{
|
{
|
||||||
struct os_ble_device base;
|
struct os_ble_device base;
|
||||||
DBusConnection *conn;
|
struct ble_conn_helper bch;
|
||||||
DBusError err;
|
|
||||||
int fd;
|
int fd;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -445,10 +462,119 @@ array_match_string_element(const DBusMessageIter *in_array, const char *key)
|
||||||
|
|
||||||
/*
|
/*
|
||||||
*
|
*
|
||||||
* Bluez helpers.
|
* D-BUS helpers.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
static int
|
||||||
|
dbus_has_name(DBusConnection *conn, const char *name)
|
||||||
|
{
|
||||||
|
DBusMessage *msg;
|
||||||
|
DBusError err;
|
||||||
|
|
||||||
|
msg = dbus_message_new_method_call(
|
||||||
|
"org.freedesktop.DBus", // target for the method call
|
||||||
|
"/org/freedesktop/DBus", // object to call on
|
||||||
|
"org.freedesktop.DBus", // interface to call on
|
||||||
|
"ListNames"); // method name
|
||||||
|
if (send_message(conn, &err, &msg) != 0) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
DBusMessageIter args;
|
||||||
|
dbus_message_iter_init(msg, &args);
|
||||||
|
|
||||||
|
// Check if this is a error message.
|
||||||
|
int type = dbus_message_iter_get_arg_type(&args);
|
||||||
|
if (type == DBUS_TYPE_STRING) {
|
||||||
|
char *response = NULL;
|
||||||
|
dbus_message_iter_get_basic(&args, &response);
|
||||||
|
fprintf(stderr, "Error getting calling ListNames:\n%s\n",
|
||||||
|
response);
|
||||||
|
response = NULL;
|
||||||
|
|
||||||
|
// free reply
|
||||||
|
dbus_message_unref(msg);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
DBusMessageIter first_elm;
|
||||||
|
int ret =
|
||||||
|
array_get_first_elem_of_type(&args, DBUS_TYPE_STRING, &first_elm);
|
||||||
|
if (ret < 0) {
|
||||||
|
// free reply
|
||||||
|
dbus_message_unref(msg);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
for_each(elm, first_elm)
|
||||||
|
{
|
||||||
|
char *response = NULL;
|
||||||
|
dbus_message_iter_get_basic(&elm, &response);
|
||||||
|
if (strcmp(response, name) == 0) {
|
||||||
|
// free reply
|
||||||
|
dbus_message_unref(msg);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// free reply
|
||||||
|
dbus_message_unref(msg);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
*
|
||||||
|
* Bluez helpers iterator helpers.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* Returns true if the object implements the `org.bluez.Device1` interface,
|
||||||
|
* and one of it's `UUIDs` matches the given @p uuid.
|
||||||
|
*/
|
||||||
|
static int
|
||||||
|
device_has_uuid(const DBusMessageIter *dict,
|
||||||
|
const char *uuid,
|
||||||
|
const char **out_path_str)
|
||||||
|
{
|
||||||
|
DBusMessageIter iface_elm, first_elm;
|
||||||
|
const char *iface_str;
|
||||||
|
const char *path_str;
|
||||||
|
|
||||||
|
int ret = dict_get_string_and_array_elm(dict, &path_str, &first_elm);
|
||||||
|
if (ret < 0) {
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
for_each(elm, first_elm)
|
||||||
|
{
|
||||||
|
dict_get_string_and_array_elm(&elm, &iface_str, &iface_elm);
|
||||||
|
|
||||||
|
if (strcmp(iface_str, "org.bluez.Device1") != 0) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
DBusMessageIter value;
|
||||||
|
int ret = array_find_variant_value(&iface_elm, "UUIDs", &value);
|
||||||
|
if (ret <= 0) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = array_match_string_element(&value, uuid);
|
||||||
|
if (ret <= 0) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
*out_path_str = path_str;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* On a gatt interface object get it's Flags property and check if notify is
|
* On a gatt interface object get it's Flags property and check if notify is
|
||||||
* set, returns positive if it found that Flags property, zero on not finding it
|
* set, returns positive if it found that Flags property, zero on not finding it
|
||||||
|
@ -549,52 +675,101 @@ gatt_char_has_uuid_and_notify(const DBusMessageIter *dict,
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*!
|
|
||||||
* Returns true if the object implements the `org.bluez.Device1` interface,
|
/*
|
||||||
* and one of it's `UUIDs` matches the given @p uuid.
|
*
|
||||||
|
* Bluez helpers..
|
||||||
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
static void
|
||||||
|
ble_close(struct ble_conn_helper *bch)
|
||||||
|
{
|
||||||
|
if (bch->conn == NULL) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
dbus_error_free(&bch->err);
|
||||||
|
dbus_connection_unref(bch->conn);
|
||||||
|
bch->conn = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
device_has_uuid(const DBusMessageIter *dict,
|
ble_init(struct ble_conn_helper *bch)
|
||||||
const char *uuid,
|
|
||||||
const char **out_path_str)
|
|
||||||
{
|
{
|
||||||
DBusMessageIter iface_elm, first_elm;
|
dbus_error_init(&bch->err);
|
||||||
const char *iface_str;
|
bch->conn = dbus_bus_get(DBUS_BUS_SYSTEM, &bch->err);
|
||||||
const char *path_str;
|
if (dbus_error_is_set(&bch->err)) {
|
||||||
|
E(bch, "DBUS Connection Error: %s\n", bch->err.message);
|
||||||
int ret = dict_get_string_and_array_elm(dict, &path_str, &first_elm);
|
dbus_error_free(&bch->err);
|
||||||
if (ret < 0) {
|
}
|
||||||
return ret;
|
if (bch->conn == NULL) {
|
||||||
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
for_each(elm, first_elm)
|
// Check if org.bluez is running.
|
||||||
{
|
int ret = dbus_has_name(bch->conn, "org.bluez");
|
||||||
dict_get_string_and_array_elm(&elm, &iface_str, &iface_elm);
|
if (ret != 0) {
|
||||||
|
ble_close(bch);
|
||||||
if (strcmp(iface_str, "org.bluez.Device1") != 0) {
|
return -1;
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
DBusMessageIter value;
|
|
||||||
int ret = array_find_variant_value(&iface_elm, "UUIDs", &value);
|
|
||||||
if (ret <= 0) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
ret = array_match_string_element(&value, uuid);
|
|
||||||
if (ret <= 0) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
*out_path_str = path_str;
|
|
||||||
return 1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
ble_connect(DBusConnection *conn, DBusError *err, const char *dbus_address)
|
ble_dbus_send(struct ble_conn_helper *bch, DBusMessage **out_msg)
|
||||||
|
{
|
||||||
|
return send_message(bch->conn, &bch->err, out_msg);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
ble_get_managed_objects(struct ble_conn_helper *bch, DBusMessage **out_msg)
|
||||||
|
{
|
||||||
|
DBusMessageIter args;
|
||||||
|
DBusMessage *msg;
|
||||||
|
int type;
|
||||||
|
|
||||||
|
msg = dbus_message_new_method_call(
|
||||||
|
"org.bluez", // target for the method call
|
||||||
|
"/", // object to call on
|
||||||
|
"org.freedesktop.DBus.ObjectManager", // interface to call on
|
||||||
|
"GetManagedObjects"); // method name
|
||||||
|
if (msg == NULL) {
|
||||||
|
E(bch, "Could not create new message!");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int ret = ble_dbus_send(bch, &msg);
|
||||||
|
if (ret != 0) {
|
||||||
|
E(bch, "Could send message '%i'!", ret);
|
||||||
|
dbus_message_unref(msg);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
dbus_message_iter_init(msg, &args);
|
||||||
|
|
||||||
|
// Check if this is a error message.
|
||||||
|
type = dbus_message_iter_get_arg_type(&args);
|
||||||
|
if (type == DBUS_TYPE_STRING) {
|
||||||
|
char *response = NULL;
|
||||||
|
dbus_message_iter_get_basic(&args, &response);
|
||||||
|
E(bch, "Error getting objects:\n%s\n", response);
|
||||||
|
response = NULL;
|
||||||
|
|
||||||
|
// free reply
|
||||||
|
dbus_message_unref(msg);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Message is verified.
|
||||||
|
*out_msg = msg;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
ble_connect(struct ble_conn_helper *bch, const char *dbus_address)
|
||||||
{
|
{
|
||||||
DBusMessage *msg = NULL;
|
DBusMessage *msg = NULL;
|
||||||
DBusMessageIter args;
|
DBusMessageIter args;
|
||||||
|
@ -613,7 +788,7 @@ ble_connect(DBusConnection *conn, DBusError *err, const char *dbus_address)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Send the message, consumes our message and returns what we received.
|
// Send the message, consumes our message and returns what we received.
|
||||||
ret = send_message(conn, err, &msg);
|
ret = ble_dbus_send(bch, &msg);
|
||||||
if (ret != 0) {
|
if (ret != 0) {
|
||||||
printf("Failed to send message '%i'\n", ret);
|
printf("Failed to send message '%i'\n", ret);
|
||||||
return -1;
|
return -1;
|
||||||
|
@ -638,8 +813,45 @@ ble_connect(DBusConnection *conn, DBusError *err, const char *dbus_address)
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
ble_write_value(DBusConnection *conn,
|
ble_connect_all_devices_with_service_uuid(struct ble_conn_helper *bch,
|
||||||
DBusError *err,
|
const char *service_uuid)
|
||||||
|
{
|
||||||
|
DBusMessageIter args, first_elm;
|
||||||
|
DBusMessage *msg = NULL;
|
||||||
|
|
||||||
|
int ret = ble_get_managed_objects(bch, &msg);
|
||||||
|
if (ret != 0) {
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
dbus_message_iter_init(msg, &args);
|
||||||
|
ret = array_get_first_elem_of_type(&args, DBUS_TYPE_DICT_ENTRY,
|
||||||
|
&first_elm);
|
||||||
|
if (ret < 0) {
|
||||||
|
// free reply
|
||||||
|
dbus_message_unref(msg);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
for_each(elm, first_elm)
|
||||||
|
{
|
||||||
|
const char *dev_path_str;
|
||||||
|
ret = device_has_uuid(&elm, service_uuid, &dev_path_str);
|
||||||
|
if (ret <= 0) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
ble_connect(bch, dev_path_str);
|
||||||
|
}
|
||||||
|
|
||||||
|
// free reply
|
||||||
|
dbus_message_unref(msg);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
ble_write_value(struct ble_conn_helper *bch,
|
||||||
const char *dbus_address,
|
const char *dbus_address,
|
||||||
uint8_t value)
|
uint8_t value)
|
||||||
{
|
{
|
||||||
|
@ -648,14 +860,13 @@ ble_write_value(DBusConnection *conn,
|
||||||
char *response = NULL;
|
char *response = NULL;
|
||||||
int ret, type;
|
int ret, type;
|
||||||
|
|
||||||
|
|
||||||
msg = dbus_message_new_method_call(
|
msg = dbus_message_new_method_call(
|
||||||
"org.bluez", // target for the method call
|
"org.bluez", // target for the method call
|
||||||
dbus_address, // object to call on
|
dbus_address, // object to call on
|
||||||
"org.bluez.GattCharacteristic1", // interface to call on
|
"org.bluez.GattCharacteristic1", // interface to call on
|
||||||
"WriteValue"); // method name
|
"WriteValue"); // method name
|
||||||
if (msg == NULL) {
|
if (msg == NULL) {
|
||||||
fprintf(stderr, "Message NULL after construction\n");
|
E(bch, "Message NULL after construction\n");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -664,9 +875,9 @@ ble_write_value(DBusConnection *conn,
|
||||||
add_empty_dict_sv(msg);
|
add_empty_dict_sv(msg);
|
||||||
|
|
||||||
// Send the message, consumes our message and returns what we received.
|
// Send the message, consumes our message and returns what we received.
|
||||||
ret = send_message(conn, err, &msg);
|
ret = ble_dbus_send(bch, &msg);
|
||||||
if (ret != 0) {
|
if (ret != 0) {
|
||||||
printf("Failed to send message '%i'\n", ret);
|
E(bch, "Failed to send message '%i'\n", ret);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -675,7 +886,7 @@ ble_write_value(DBusConnection *conn,
|
||||||
type = dbus_message_iter_get_arg_type(&args);
|
type = dbus_message_iter_get_arg_type(&args);
|
||||||
if (type == DBUS_TYPE_STRING) {
|
if (type == DBUS_TYPE_STRING) {
|
||||||
dbus_message_iter_get_basic(&args, &response);
|
dbus_message_iter_get_basic(&args, &response);
|
||||||
printf("DBus call returned message: %s\n", response);
|
E(bch, "DBus call returned message: %s\n", response);
|
||||||
|
|
||||||
// Free reply.
|
// Free reply.
|
||||||
dbus_message_unref(msg);
|
dbus_message_unref(msg);
|
||||||
|
@ -689,42 +900,22 @@ ble_write_value(DBusConnection *conn,
|
||||||
}
|
}
|
||||||
|
|
||||||
static ssize_t
|
static ssize_t
|
||||||
get_path_to_notify_char(DBusConnection *conn,
|
get_path_to_notify_char(struct ble_conn_helper *bch,
|
||||||
const char *dev_uuid,
|
const char *dev_uuid,
|
||||||
const char *char_uuid,
|
const char *char_uuid,
|
||||||
char *output,
|
char *output,
|
||||||
size_t output_len)
|
size_t output_len)
|
||||||
{
|
{
|
||||||
|
DBusMessageIter args, first_elm;
|
||||||
DBusMessage *msg;
|
DBusMessage *msg;
|
||||||
DBusError err;
|
|
||||||
|
|
||||||
msg = dbus_message_new_method_call(
|
int ret = ble_get_managed_objects(bch, &msg);
|
||||||
"org.bluez", // target for the method call
|
if (ret != 0) {
|
||||||
"/", // object to call on
|
return ret;
|
||||||
"org.freedesktop.DBus.ObjectManager", // interface to call on
|
|
||||||
"GetManagedObjects"); // method name
|
|
||||||
if (send_message(conn, &err, &msg) != 0) {
|
|
||||||
return -1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
DBusMessageIter args;
|
|
||||||
dbus_message_iter_init(msg, &args);
|
dbus_message_iter_init(msg, &args);
|
||||||
|
ret = array_get_first_elem_of_type(&args, DBUS_TYPE_DICT_ENTRY,
|
||||||
// Check if this is a error message.
|
|
||||||
int type = dbus_message_iter_get_arg_type(&args);
|
|
||||||
if (type == DBUS_TYPE_STRING) {
|
|
||||||
char *response = NULL;
|
|
||||||
dbus_message_iter_get_basic(&args, &response);
|
|
||||||
fprintf(stderr, "Error getting objects:\n%s\n", response);
|
|
||||||
response = NULL;
|
|
||||||
|
|
||||||
// free reply
|
|
||||||
dbus_message_unref(msg);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
DBusMessageIter first_elm;
|
|
||||||
int ret = array_get_first_elem_of_type(&args, DBUS_TYPE_DICT_ENTRY,
|
|
||||||
&first_elm);
|
&first_elm);
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
// free reply
|
// free reply
|
||||||
|
@ -755,74 +946,20 @@ get_path_to_notify_char(DBusConnection *conn,
|
||||||
|
|
||||||
ssize_t written =
|
ssize_t written =
|
||||||
snprintf(output, output_len, "%s", char_path_str);
|
snprintf(output, output_len, "%s", char_path_str);
|
||||||
|
|
||||||
// free reply
|
// free reply
|
||||||
dbus_message_unref(msg);
|
dbus_message_unref(msg);
|
||||||
|
|
||||||
return written;
|
return written;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// free reply
|
// free reply
|
||||||
dbus_message_unref(msg);
|
dbus_message_unref(msg);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
|
||||||
has_dbus_name(DBusConnection *conn, const char *name)
|
|
||||||
{
|
|
||||||
DBusMessage *msg;
|
|
||||||
DBusError err;
|
|
||||||
|
|
||||||
msg = dbus_message_new_method_call(
|
|
||||||
"org.freedesktop.DBus", // target for the method call
|
|
||||||
"/org/freedesktop/DBus", // object to call on
|
|
||||||
"org.freedesktop.DBus", // interface to call on
|
|
||||||
"ListNames"); // method name
|
|
||||||
if (send_message(conn, &err, &msg) != 0) {
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
DBusMessageIter args;
|
|
||||||
dbus_message_iter_init(msg, &args);
|
|
||||||
|
|
||||||
// Check if this is a error message.
|
|
||||||
int type = dbus_message_iter_get_arg_type(&args);
|
|
||||||
if (type == DBUS_TYPE_STRING) {
|
|
||||||
char *response = NULL;
|
|
||||||
dbus_message_iter_get_basic(&args, &response);
|
|
||||||
fprintf(stderr, "Error getting calling ListNames:\n%s\n",
|
|
||||||
response);
|
|
||||||
response = NULL;
|
|
||||||
|
|
||||||
// free reply
|
|
||||||
dbus_message_unref(msg);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
DBusMessageIter first_elm;
|
|
||||||
int ret =
|
|
||||||
array_get_first_elem_of_type(&args, DBUS_TYPE_STRING, &first_elm);
|
|
||||||
if (ret < 0) {
|
|
||||||
// free reply
|
|
||||||
dbus_message_unref(msg);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
for_each(elm, first_elm)
|
|
||||||
{
|
|
||||||
char *response = NULL;
|
|
||||||
dbus_message_iter_get_basic(&elm, &response);
|
|
||||||
if (strcmp(response, name) == 0) {
|
|
||||||
// free reply
|
|
||||||
dbus_message_unref(msg);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// free reply
|
|
||||||
dbus_message_unref(msg);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int
|
static int
|
||||||
init_ble_notify(const char *dev_uuid,
|
init_ble_notify(const char *dev_uuid,
|
||||||
const char *char_uuid,
|
const char *char_uuid,
|
||||||
|
@ -831,26 +968,14 @@ init_ble_notify(const char *dev_uuid,
|
||||||
DBusMessage *msg;
|
DBusMessage *msg;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
dbus_error_init(&bledev->err);
|
ret = ble_init(&bledev->bch);
|
||||||
bledev->conn = dbus_bus_get(DBUS_BUS_SYSTEM, &bledev->err);
|
|
||||||
if (dbus_error_is_set(&bledev->err)) {
|
|
||||||
fprintf(stderr, "DBUS Connection Error: %s\n",
|
|
||||||
bledev->err.message);
|
|
||||||
dbus_error_free(&bledev->err);
|
|
||||||
}
|
|
||||||
if (bledev->conn == NULL) {
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Check if org.bluez is running.
|
|
||||||
ret = has_dbus_name(bledev->conn, "org.bluez");
|
|
||||||
if (ret != 0) {
|
if (ret != 0) {
|
||||||
return -1;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
char dbus_address[256]; // should be long enough
|
char dbus_address[256]; // should be long enough
|
||||||
XRT_MAYBE_UNUSED ssize_t written =
|
XRT_MAYBE_UNUSED ssize_t written =
|
||||||
get_path_to_notify_char(bledev->conn, dev_uuid, char_uuid,
|
get_path_to_notify_char(&bledev->bch, dev_uuid, char_uuid,
|
||||||
dbus_address, sizeof(dbus_address));
|
dbus_address, sizeof(dbus_address));
|
||||||
if (written == 0) {
|
if (written == 0) {
|
||||||
return -1;
|
return -1;
|
||||||
|
@ -865,7 +990,7 @@ init_ble_notify(const char *dev_uuid,
|
||||||
"org.bluez.GattCharacteristic1", // interface to call on
|
"org.bluez.GattCharacteristic1", // interface to call on
|
||||||
"AcquireNotify"); // method name
|
"AcquireNotify"); // method name
|
||||||
if (msg == NULL) {
|
if (msg == NULL) {
|
||||||
fprintf(stderr, "Message Null after construction\n");
|
E(&bledev->bch, "Message Null after construction\n");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -873,7 +998,7 @@ init_ble_notify(const char *dev_uuid,
|
||||||
add_empty_dict_sv(msg);
|
add_empty_dict_sv(msg);
|
||||||
|
|
||||||
// Send the message, consumes our message and returns what we received.
|
// Send the message, consumes our message and returns what we received.
|
||||||
if (send_message(bledev->conn, &bledev->err, &msg) != 0) {
|
if (ble_dbus_send(&bledev->bch, &msg) != 0) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -958,11 +1083,7 @@ os_ble_notify_destroy(struct os_ble_device *bdev)
|
||||||
dev->fd = -1;
|
dev->fd = -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (dev->conn != NULL) {
|
ble_close(&dev->bch);
|
||||||
dbus_error_free(&dev->err);
|
|
||||||
dbus_connection_unref(dev->conn);
|
|
||||||
dev->conn = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
free(dev);
|
free(dev);
|
||||||
}
|
}
|
||||||
|
@ -996,72 +1117,54 @@ os_ble_notify_open(const char *dev_uuid,
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
os_ble_broadcast_write_value(const char *dev_uuid,
|
os_ble_broadcast_write_value(const char *service_uuid,
|
||||||
const char *char_uuid,
|
const char *char_uuid,
|
||||||
uint8_t value)
|
uint8_t value)
|
||||||
{
|
{
|
||||||
DBusConnection *conn = NULL;
|
struct ble_conn_helper bch = {0};
|
||||||
|
DBusMessageIter args, first_elm;
|
||||||
DBusMessage *msg = NULL;
|
DBusMessage *msg = NULL;
|
||||||
DBusError err;
|
int ret = 0;
|
||||||
int ret = 0, type = 0;
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Connect
|
* Init dbus
|
||||||
*/
|
*/
|
||||||
|
|
||||||
dbus_error_init(&err);
|
ret = ble_init(&bch);
|
||||||
conn = dbus_bus_get(DBUS_BUS_SYSTEM, &err);
|
|
||||||
if (dbus_error_is_set(&err)) {
|
|
||||||
fprintf(stderr, "DBUS Connection Error: %s\n", err.message);
|
|
||||||
dbus_error_free(&err);
|
|
||||||
}
|
|
||||||
if (conn == NULL) {
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Check if org.bluez is running.
|
|
||||||
ret = has_dbus_name(conn, "org.bluez");
|
|
||||||
if (ret != 0) {
|
if (ret != 0) {
|
||||||
return -1;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Connect devices
|
||||||
|
*/
|
||||||
|
|
||||||
|
// Connect all of the devices so we can write to them.
|
||||||
|
ble_connect_all_devices_with_service_uuid(&bch, service_uuid);
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* List
|
* Write to all connected devices.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
msg = dbus_message_new_method_call(
|
/*
|
||||||
"org.bluez", // target for the method call
|
* We get the objects again, because their services and characteristics
|
||||||
"/", // object to call on
|
* might not have been created before.
|
||||||
"org.freedesktop.DBus.ObjectManager", // interface to call on
|
*/
|
||||||
"GetManagedObjects"); // method name
|
ret = ble_get_managed_objects(&bch, &msg);
|
||||||
if (send_message(conn, &err, &msg) != 0) {
|
if (ret != 0) {
|
||||||
return -1;
|
ble_close(&bch);
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
DBusMessageIter args;
|
|
||||||
dbus_message_iter_init(msg, &args);
|
dbus_message_iter_init(msg, &args);
|
||||||
|
|
||||||
// Check if this is a error message.
|
|
||||||
type = dbus_message_iter_get_arg_type(&args);
|
|
||||||
if (type == DBUS_TYPE_STRING) {
|
|
||||||
char *response = NULL;
|
|
||||||
dbus_message_iter_get_basic(&args, &response);
|
|
||||||
fprintf(stderr, "Error getting objects:\n%s\n", response);
|
|
||||||
response = NULL;
|
|
||||||
|
|
||||||
// free reply
|
|
||||||
dbus_message_unref(msg);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
DBusMessageIter first_elm;
|
|
||||||
ret = array_get_first_elem_of_type(&args, DBUS_TYPE_DICT_ENTRY,
|
ret = array_get_first_elem_of_type(&args, DBUS_TYPE_DICT_ENTRY,
|
||||||
&first_elm);
|
&first_elm);
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
// free reply
|
// free reply
|
||||||
dbus_message_unref(msg);
|
dbus_message_unref(msg);
|
||||||
|
ble_close(&bch);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1069,13 +1172,11 @@ os_ble_broadcast_write_value(const char *dev_uuid,
|
||||||
{
|
{
|
||||||
const char *dev_path_str;
|
const char *dev_path_str;
|
||||||
const char *char_path_str;
|
const char *char_path_str;
|
||||||
ret = device_has_uuid(&elm, dev_uuid, &dev_path_str);
|
ret = device_has_uuid(&elm, service_uuid, &dev_path_str);
|
||||||
if (ret <= 0) {
|
if (ret <= 0) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
ble_connect(conn, &err, dev_path_str);
|
|
||||||
|
|
||||||
for_each(c, first_elm)
|
for_each(c, first_elm)
|
||||||
{
|
{
|
||||||
ret = gatt_char_has_uuid_and_notify(&c, char_uuid,
|
ret = gatt_char_has_uuid_and_notify(&c, char_uuid,
|
||||||
|
@ -1088,12 +1189,13 @@ os_ble_broadcast_write_value(const char *dev_uuid,
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
ble_write_value(conn, &err, char_path_str, value);
|
ble_write_value(&bch, char_path_str, value);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// free reply
|
// free reply
|
||||||
dbus_message_unref(msg);
|
dbus_message_unref(msg);
|
||||||
|
ble_close(&bch);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue