mirror of
https://git.kernel.org/pub/scm/bluetooth/bluez.git
synced 2024-11-25 21:24:16 +08:00
Cleanup of primary service structs
Get rid of local structure to store all GATT primary services of a given device. "primary" struct has been renamed to "gatt_service" to avoid misinterpretation or confusion with "att_primary".
This commit is contained in:
parent
27347f58bd
commit
3b010c0a14
336
attrib/client.c
336
attrib/client.c
@ -53,15 +53,6 @@
|
||||
|
||||
#define CHAR_INTERFACE "org.bluez.Characteristic"
|
||||
|
||||
struct gatt_service {
|
||||
struct btd_device *dev;
|
||||
DBusConnection *conn;
|
||||
GSList *primary;
|
||||
GAttrib *attrib;
|
||||
int psm;
|
||||
gboolean listen;
|
||||
};
|
||||
|
||||
struct format {
|
||||
guint8 format;
|
||||
guint8 exponent;
|
||||
@ -70,16 +61,20 @@ struct format {
|
||||
guint16 desc;
|
||||
} __attribute__ ((packed));
|
||||
|
||||
struct primary {
|
||||
struct gatt_service *gatt;
|
||||
struct att_primary *att;
|
||||
struct gatt_service {
|
||||
struct btd_device *dev;
|
||||
struct att_primary *prim;
|
||||
DBusConnection *conn;
|
||||
GAttrib *attrib;
|
||||
int psm;
|
||||
char *path;
|
||||
GSList *chars;
|
||||
GSList *watchers;
|
||||
gboolean listen;
|
||||
};
|
||||
|
||||
struct characteristic {
|
||||
struct primary *prim;
|
||||
struct gatt_service *gatt;
|
||||
char *path;
|
||||
uint16_t handle;
|
||||
uint16_t end;
|
||||
@ -93,7 +88,7 @@ struct characteristic {
|
||||
};
|
||||
|
||||
struct query_data {
|
||||
struct primary *prim;
|
||||
struct gatt_service *gatt;
|
||||
struct characteristic *chr;
|
||||
DBusMessage *msg;
|
||||
uint16_t handle;
|
||||
@ -103,7 +98,7 @@ struct watcher {
|
||||
guint id;
|
||||
char *name;
|
||||
char *path;
|
||||
struct primary *prim;
|
||||
struct gatt_service *gatt;
|
||||
};
|
||||
|
||||
static GSList *gatt_services = NULL;
|
||||
@ -129,26 +124,11 @@ static void watcher_free(void *user_data)
|
||||
g_free(watcher);
|
||||
}
|
||||
|
||||
static void primary_free(void *user_data)
|
||||
static void gatt_service_free(struct gatt_service *gatt)
|
||||
{
|
||||
struct primary *prim = user_data;
|
||||
GSList *l;
|
||||
|
||||
for (l = prim->watchers; l; l = l->next) {
|
||||
struct watcher *watcher = l->data;
|
||||
g_dbus_remove_watch(prim->gatt->conn, watcher->id);
|
||||
}
|
||||
|
||||
g_slist_free_full(prim->chars, characteristic_free);
|
||||
g_free(prim->path);
|
||||
g_free(prim);
|
||||
}
|
||||
|
||||
static void gatt_service_free(void *user_data)
|
||||
{
|
||||
struct gatt_service *gatt = user_data;
|
||||
|
||||
g_slist_free_full(gatt->primary, primary_free);
|
||||
g_slist_free_full(gatt->watchers, watcher_free);
|
||||
g_slist_free_full(gatt->chars, characteristic_free);
|
||||
g_free(gatt->path);
|
||||
g_attrib_unref(gatt->attrib);
|
||||
btd_device_unref(gatt->dev);
|
||||
dbus_connection_unref(gatt->conn);
|
||||
@ -166,14 +146,6 @@ static void gatt_get_address(struct gatt_service *gatt,
|
||||
device_get_address(device, dba);
|
||||
}
|
||||
|
||||
static int gatt_dev_cmp(gconstpointer a, gconstpointer b)
|
||||
{
|
||||
const struct gatt_service *gatt = a;
|
||||
const struct btd_device *dev = b;
|
||||
|
||||
return gatt->dev != dev;
|
||||
}
|
||||
|
||||
static int characteristic_handle_cmp(gconstpointer a, gconstpointer b)
|
||||
{
|
||||
const struct characteristic *chr = a;
|
||||
@ -229,12 +201,11 @@ static void append_char_dict(DBusMessageIter *iter, struct characteristic *chr)
|
||||
static void watcher_exit(DBusConnection *conn, void *user_data)
|
||||
{
|
||||
struct watcher *watcher = user_data;
|
||||
struct primary *prim = watcher->prim;
|
||||
struct gatt_service *gatt = prim->gatt;
|
||||
struct gatt_service *gatt = watcher->gatt;
|
||||
|
||||
DBG("%s watcher %s exited", prim->path, watcher->name);
|
||||
DBG("%s watcher %s exited", gatt->path, watcher->name);
|
||||
|
||||
prim->watchers = g_slist_remove(prim->watchers, watcher);
|
||||
gatt->watchers = g_slist_remove(gatt->watchers, watcher);
|
||||
|
||||
g_attrib_unref(gatt->attrib);
|
||||
}
|
||||
@ -256,7 +227,7 @@ static void update_watchers(gpointer data, gpointer user_data)
|
||||
{
|
||||
struct watcher *w = data;
|
||||
struct characteristic *chr = user_data;
|
||||
DBusConnection *conn = w->prim->gatt->conn;
|
||||
DBusConnection *conn = w->gatt->conn;
|
||||
DBusMessage *msg;
|
||||
|
||||
msg = dbus_message_new_method_call(w->name, w->path,
|
||||
@ -277,8 +248,7 @@ static void events_handler(const uint8_t *pdu, uint16_t len,
|
||||
{
|
||||
struct gatt_service *gatt = user_data;
|
||||
struct characteristic *chr;
|
||||
struct primary *prim;
|
||||
GSList *lprim, *lchr;
|
||||
GSList *l;
|
||||
uint8_t opdu[ATT_MAX_MTU];
|
||||
guint handle;
|
||||
uint16_t olen;
|
||||
@ -291,17 +261,12 @@ static void events_handler(const uint8_t *pdu, uint16_t len,
|
||||
|
||||
handle = att_get_u16(&pdu[1]);
|
||||
|
||||
for (lprim = gatt->primary, prim = NULL, chr = NULL; lprim;
|
||||
lprim = lprim->next) {
|
||||
prim = lprim->data;
|
||||
l = g_slist_find_custom(gatt->chars, GUINT_TO_POINTER(handle),
|
||||
characteristic_handle_cmp);
|
||||
if (!l)
|
||||
return;
|
||||
|
||||
lchr = g_slist_find_custom(prim->chars,
|
||||
GUINT_TO_POINTER(handle), characteristic_handle_cmp);
|
||||
if (lchr) {
|
||||
chr = lchr->data;
|
||||
break;
|
||||
}
|
||||
}
|
||||
chr = l->data;
|
||||
|
||||
if (chr == NULL) {
|
||||
DBG("Attribute handle 0x%02x not found", handle);
|
||||
@ -317,7 +282,7 @@ static void events_handler(const uint8_t *pdu, uint16_t len,
|
||||
if (characteristic_set_value(chr, &pdu[3], len - 3) < 0)
|
||||
DBG("Can't change Characteristic 0x%02x", handle);
|
||||
|
||||
g_slist_foreach(prim->watchers, update_watchers, chr);
|
||||
g_slist_foreach(gatt->watchers, update_watchers, chr);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -415,7 +380,7 @@ static DBusMessage *register_watcher(DBusConnection *conn,
|
||||
DBusMessage *msg, void *data)
|
||||
{
|
||||
const char *sender = dbus_message_get_sender(msg);
|
||||
struct primary *prim = data;
|
||||
struct gatt_service *gatt = data;
|
||||
struct watcher *watcher;
|
||||
GError *gerr = NULL;
|
||||
char *path;
|
||||
@ -424,7 +389,7 @@ static DBusMessage *register_watcher(DBusConnection *conn,
|
||||
DBUS_TYPE_INVALID))
|
||||
return btd_error_invalid_args(msg);
|
||||
|
||||
if (l2cap_connect(prim->gatt, &gerr, TRUE) < 0) {
|
||||
if (l2cap_connect(gatt, &gerr, TRUE) < 0) {
|
||||
DBusMessage *reply = btd_error_failed(msg, gerr->message);
|
||||
g_error_free(gerr);
|
||||
return reply;
|
||||
@ -432,12 +397,12 @@ static DBusMessage *register_watcher(DBusConnection *conn,
|
||||
|
||||
watcher = g_new0(struct watcher, 1);
|
||||
watcher->name = g_strdup(sender);
|
||||
watcher->prim = prim;
|
||||
watcher->gatt = gatt;
|
||||
watcher->path = g_strdup(path);
|
||||
watcher->id = g_dbus_add_disconnect_watch(conn, sender, watcher_exit,
|
||||
watcher, watcher_free);
|
||||
|
||||
prim->watchers = g_slist_append(prim->watchers, watcher);
|
||||
gatt->watchers = g_slist_append(gatt->watchers, watcher);
|
||||
|
||||
return dbus_message_new_method_return(msg);
|
||||
}
|
||||
@ -446,7 +411,7 @@ static DBusMessage *unregister_watcher(DBusConnection *conn,
|
||||
DBusMessage *msg, void *data)
|
||||
{
|
||||
const char *sender = dbus_message_get_sender(msg);
|
||||
struct primary *prim = data;
|
||||
struct gatt_service *gatt = data;
|
||||
struct watcher *watcher, *match;
|
||||
GSList *l;
|
||||
char *path;
|
||||
@ -458,14 +423,14 @@ static DBusMessage *unregister_watcher(DBusConnection *conn,
|
||||
match = g_new0(struct watcher, 1);
|
||||
match->name = g_strdup(sender);
|
||||
match->path = g_strdup(path);
|
||||
l = g_slist_find_custom(prim->watchers, match, watcher_cmp);
|
||||
l = g_slist_find_custom(gatt->watchers, match, watcher_cmp);
|
||||
watcher_free(match);
|
||||
if (!l)
|
||||
return btd_error_not_authorized(msg);
|
||||
|
||||
watcher = l->data;
|
||||
g_dbus_remove_watch(conn, watcher->id);
|
||||
prim->watchers = g_slist_remove(prim->watchers, watcher);
|
||||
gatt->watchers = g_slist_remove(gatt->watchers, watcher);
|
||||
watcher_free(watcher);
|
||||
|
||||
return dbus_message_new_method_return(msg);
|
||||
@ -474,7 +439,7 @@ static DBusMessage *unregister_watcher(DBusConnection *conn,
|
||||
static DBusMessage *set_value(DBusConnection *conn, DBusMessage *msg,
|
||||
DBusMessageIter *iter, struct characteristic *chr)
|
||||
{
|
||||
struct gatt_service *gatt = chr->prim->gatt;
|
||||
struct gatt_service *gatt = chr->gatt;
|
||||
DBusMessageIter sub;
|
||||
GError *gerr = NULL;
|
||||
uint8_t *value;
|
||||
@ -576,36 +541,34 @@ static char *characteristic_list_to_string(GSList *chars)
|
||||
return g_string_free(characteristics, FALSE);
|
||||
}
|
||||
|
||||
static void store_characteristics(struct gatt_service *gatt,
|
||||
struct primary *prim)
|
||||
static void store_characteristics(const bdaddr_t *sba, const bdaddr_t *dba,
|
||||
uint16_t start, GSList *chars)
|
||||
{
|
||||
char *characteristics;
|
||||
struct att_primary *att = prim->att;
|
||||
bdaddr_t sba, dba;
|
||||
|
||||
characteristics = characteristic_list_to_string(prim->chars);
|
||||
characteristics = characteristic_list_to_string(chars);
|
||||
|
||||
gatt_get_address(gatt, &sba, &dba);
|
||||
|
||||
write_device_characteristics(&sba, &dba, att->start, characteristics);
|
||||
write_device_characteristics(sba, dba, start, characteristics);
|
||||
|
||||
g_free(characteristics);
|
||||
}
|
||||
|
||||
static void register_characteristics(struct primary *prim)
|
||||
static void register_characteristic(gpointer data, gpointer user_data)
|
||||
{
|
||||
GSList *lc;
|
||||
struct characteristic *chr = data;
|
||||
DBusConnection *conn = chr->gatt->conn;
|
||||
const char *gatt_path = user_data;
|
||||
|
||||
for (lc = prim->chars; lc; lc = lc->next) {
|
||||
struct characteristic *chr = lc->data;
|
||||
g_dbus_register_interface(prim->gatt->conn, chr->path,
|
||||
CHAR_INTERFACE, char_methods,
|
||||
NULL, NULL, chr, NULL);
|
||||
DBG("Registered: %s", chr->path);
|
||||
}
|
||||
chr->path = g_strdup_printf("%s/characteristic%04x", gatt_path,
|
||||
chr->handle);
|
||||
|
||||
g_dbus_register_interface(conn, chr->path, CHAR_INTERFACE,
|
||||
char_methods, NULL, NULL, chr, NULL);
|
||||
|
||||
DBG("Registered: %s", chr->path);
|
||||
}
|
||||
|
||||
static GSList *string_to_characteristic_list(struct primary *prim,
|
||||
static GSList *string_to_characteristic_list(struct gatt_service *gatt,
|
||||
const char *str)
|
||||
{
|
||||
GSList *l = NULL;
|
||||
@ -632,10 +595,7 @@ static GSList *string_to_characteristic_list(struct primary *prim,
|
||||
continue;
|
||||
}
|
||||
|
||||
chr->prim = prim;
|
||||
chr->path = g_strdup_printf("%s/characteristic%04x",
|
||||
prim->path, chr->handle);
|
||||
|
||||
chr->gatt = gatt;
|
||||
l = g_slist_append(l, chr);
|
||||
}
|
||||
|
||||
@ -644,37 +604,23 @@ static GSList *string_to_characteristic_list(struct primary *prim,
|
||||
return l;
|
||||
}
|
||||
|
||||
static void load_characteristics(gpointer data, gpointer user_data)
|
||||
static GSList *load_characteristics(struct gatt_service *gatt, uint16_t start)
|
||||
{
|
||||
struct primary *prim = data;
|
||||
struct att_primary *att = prim->att;
|
||||
struct gatt_service *gatt = user_data;
|
||||
bdaddr_t sba, dba;
|
||||
GSList *chrs_list;
|
||||
bdaddr_t sba, dba;
|
||||
char *str;
|
||||
|
||||
if (prim->chars) {
|
||||
DBG("Characteristics already loaded");
|
||||
return;
|
||||
}
|
||||
|
||||
gatt_get_address(gatt, &sba, &dba);
|
||||
|
||||
str = read_device_characteristics(&sba, &dba, att->start);
|
||||
str = read_device_characteristics(&sba, &dba, start);
|
||||
if (str == NULL)
|
||||
return;
|
||||
return NULL;
|
||||
|
||||
chrs_list = string_to_characteristic_list(prim, str);
|
||||
chrs_list = string_to_characteristic_list(gatt, str);
|
||||
|
||||
free(str);
|
||||
|
||||
if (chrs_list == NULL)
|
||||
return;
|
||||
|
||||
prim->chars = chrs_list;
|
||||
register_characteristics(prim);
|
||||
|
||||
return;
|
||||
return chrs_list;
|
||||
}
|
||||
|
||||
static void store_attribute(struct gatt_service *gatt, uint16_t handle,
|
||||
@ -706,7 +652,7 @@ static void update_char_desc(guint8 status, const guint8 *pdu, guint16 len,
|
||||
gpointer user_data)
|
||||
{
|
||||
struct query_data *current = user_data;
|
||||
struct gatt_service *gatt = current->prim->gatt;
|
||||
struct gatt_service *gatt = current->gatt;
|
||||
struct characteristic *chr = current->chr;
|
||||
|
||||
if (status == 0) {
|
||||
@ -740,7 +686,7 @@ static void update_char_format(guint8 status, const guint8 *pdu, guint16 len,
|
||||
gpointer user_data)
|
||||
{
|
||||
struct query_data *current = user_data;
|
||||
struct gatt_service *gatt = current->prim->gatt;
|
||||
struct gatt_service *gatt = current->gatt;
|
||||
struct characteristic *chr = current->chr;
|
||||
|
||||
if (status != 0)
|
||||
@ -766,7 +712,7 @@ static void update_char_value(guint8 status, const guint8 *pdu,
|
||||
guint16 len, gpointer user_data)
|
||||
{
|
||||
struct query_data *current = user_data;
|
||||
struct gatt_service *gatt = current->prim->gatt;
|
||||
struct gatt_service *gatt = current->gatt;
|
||||
struct characteristic *chr = current->chr;
|
||||
|
||||
if (status == 0)
|
||||
@ -800,7 +746,7 @@ static void descriptor_cb(guint8 status, const guint8 *pdu, guint16 plen,
|
||||
gpointer user_data)
|
||||
{
|
||||
struct query_data *current = user_data;
|
||||
struct gatt_service *gatt = current->prim->gatt;
|
||||
struct gatt_service *gatt = current->gatt;
|
||||
struct att_data_list *list;
|
||||
guint8 format;
|
||||
int i;
|
||||
@ -832,7 +778,7 @@ static void descriptor_cb(guint8 status, const guint8 *pdu, guint16 plen,
|
||||
continue;
|
||||
}
|
||||
qfmt = g_new0(struct query_data, 1);
|
||||
qfmt->prim = current->prim;
|
||||
qfmt->gatt = current->gatt;
|
||||
qfmt->chr = current->chr;
|
||||
qfmt->handle = handle;
|
||||
|
||||
@ -858,11 +804,10 @@ static void update_all_chars(gpointer data, gpointer user_data)
|
||||
{
|
||||
struct query_data *qdesc, *qvalue;
|
||||
struct characteristic *chr = data;
|
||||
struct primary *prim = user_data;
|
||||
struct gatt_service *gatt = prim->gatt;
|
||||
struct gatt_service *gatt = user_data;
|
||||
|
||||
qdesc = g_new0(struct query_data, 1);
|
||||
qdesc->prim = prim;
|
||||
qdesc->gatt = gatt;
|
||||
qdesc->chr = chr;
|
||||
|
||||
gatt->attrib = g_attrib_ref(gatt->attrib);
|
||||
@ -870,7 +815,7 @@ static void update_all_chars(gpointer data, gpointer user_data)
|
||||
qdesc);
|
||||
|
||||
qvalue = g_new0(struct query_data, 1);
|
||||
qvalue->prim = prim;
|
||||
qvalue->gatt = gatt;
|
||||
qvalue->chr = chr;
|
||||
|
||||
gatt->attrib = g_attrib_ref(gatt->attrib);
|
||||
@ -883,11 +828,11 @@ static void char_discovered_cb(GSList *characteristics, guint8 status,
|
||||
DBusMessage *reply;
|
||||
DBusMessageIter iter, array_iter;
|
||||
struct query_data *current = user_data;
|
||||
struct primary *prim = current->prim;
|
||||
struct att_primary *att = prim->att;
|
||||
struct gatt_service *gatt = prim->gatt;
|
||||
struct gatt_service *gatt = current->gatt;
|
||||
struct att_primary *prim = gatt->prim;
|
||||
uint16_t *previous_end = NULL;
|
||||
GSList *l;
|
||||
bdaddr_t sba, dba;
|
||||
|
||||
if (status != 0) {
|
||||
const char *str = att_ecode2str(status);
|
||||
@ -903,17 +848,15 @@ static void char_discovered_cb(GSList *characteristics, guint8 status,
|
||||
guint handle = current_chr->value_handle;
|
||||
GSList *lchr;
|
||||
|
||||
lchr = g_slist_find_custom(prim->chars,
|
||||
lchr = g_slist_find_custom(gatt->chars,
|
||||
GUINT_TO_POINTER(handle), characteristic_handle_cmp);
|
||||
if (lchr)
|
||||
continue;
|
||||
|
||||
chr = g_new0(struct characteristic, 1);
|
||||
chr->prim = prim;
|
||||
chr->gatt = gatt;
|
||||
chr->perm = current_chr->properties;
|
||||
chr->handle = current_chr->value_handle;
|
||||
chr->path = g_strdup_printf("%s/characteristic%04x",
|
||||
prim->path, chr->handle);
|
||||
strncpy(chr->type, current_chr->uuid, sizeof(chr->type));
|
||||
|
||||
if (previous_end)
|
||||
@ -921,14 +864,16 @@ static void char_discovered_cb(GSList *characteristics, guint8 status,
|
||||
|
||||
previous_end = &chr->end;
|
||||
|
||||
prim->chars = g_slist_append(prim->chars, chr);
|
||||
gatt->chars = g_slist_append(gatt->chars, chr);
|
||||
}
|
||||
|
||||
if (previous_end)
|
||||
*previous_end = att->end;
|
||||
*previous_end = prim->end;
|
||||
|
||||
store_characteristics(gatt, prim);
|
||||
register_characteristics(prim);
|
||||
gatt_get_address(gatt, &sba, &dba);
|
||||
store_characteristics(&sba, &dba, prim->start, gatt->chars);
|
||||
|
||||
g_slist_foreach(gatt->chars, register_characteristic, gatt->path);
|
||||
|
||||
reply = dbus_message_new_method_return(current->msg);
|
||||
|
||||
@ -937,7 +882,7 @@ static void char_discovered_cb(GSList *characteristics, guint8 status,
|
||||
dbus_message_iter_open_container(&iter, DBUS_TYPE_ARRAY,
|
||||
DBUS_TYPE_OBJECT_PATH_AS_STRING, &array_iter);
|
||||
|
||||
for (l = prim->chars; l; l = l->next) {
|
||||
for (l = gatt->chars; l; l = l->next) {
|
||||
struct characteristic *chr = l->data;
|
||||
|
||||
dbus_message_iter_append_basic(&array_iter,
|
||||
@ -946,7 +891,7 @@ static void char_discovered_cb(GSList *characteristics, guint8 status,
|
||||
|
||||
dbus_message_iter_close_container(&iter, &array_iter);
|
||||
|
||||
g_slist_foreach(prim->chars, update_all_chars, prim);
|
||||
g_slist_foreach(gatt->chars, update_all_chars, gatt);
|
||||
|
||||
fail:
|
||||
g_dbus_send_message(gatt->conn, reply);
|
||||
@ -957,23 +902,22 @@ fail:
|
||||
static DBusMessage *discover_char(DBusConnection *conn, DBusMessage *msg,
|
||||
void *data)
|
||||
{
|
||||
struct primary *prim = data;
|
||||
struct att_primary *att = prim->att;
|
||||
struct gatt_service *gatt = prim->gatt;
|
||||
struct gatt_service *gatt = data;
|
||||
struct att_primary *prim = gatt->prim;
|
||||
struct query_data *qchr;
|
||||
GError *gerr = NULL;
|
||||
|
||||
if (l2cap_connect(prim->gatt, &gerr, FALSE) < 0) {
|
||||
if (l2cap_connect(gatt, &gerr, FALSE) < 0) {
|
||||
DBusMessage *reply = btd_error_failed(msg, gerr->message);
|
||||
g_error_free(gerr);
|
||||
return reply;
|
||||
}
|
||||
|
||||
qchr = g_new0(struct query_data, 1);
|
||||
qchr->prim = prim;
|
||||
qchr->gatt = gatt;
|
||||
qchr->msg = dbus_message_ref(msg);
|
||||
|
||||
gatt_discover_char(gatt->attrib, att->start, att->end, NULL,
|
||||
gatt_discover_char(gatt->attrib, prim->start, prim->end, NULL,
|
||||
char_discovered_cb, qchr);
|
||||
|
||||
return NULL;
|
||||
@ -982,7 +926,7 @@ static DBusMessage *discover_char(DBusConnection *conn, DBusMessage *msg,
|
||||
static DBusMessage *prim_get_properties(DBusConnection *conn, DBusMessage *msg,
|
||||
void *data)
|
||||
{
|
||||
struct primary *prim = data;
|
||||
struct gatt_service *gatt = data;
|
||||
DBusMessage *reply;
|
||||
DBusMessageIter iter;
|
||||
DBusMessageIter dict;
|
||||
@ -1002,16 +946,16 @@ static DBusMessage *prim_get_properties(DBusConnection *conn, DBusMessage *msg,
|
||||
DBUS_TYPE_STRING_AS_STRING DBUS_TYPE_VARIANT_AS_STRING
|
||||
DBUS_DICT_ENTRY_END_CHAR_AS_STRING, &dict);
|
||||
|
||||
chars = g_new0(char *, g_slist_length(prim->chars) + 1);
|
||||
chars = g_new0(char *, g_slist_length(gatt->chars) + 1);
|
||||
|
||||
for (i = 0, l = prim->chars; l; l = l->next, i++) {
|
||||
for (i = 0, l = gatt->chars; l; l = l->next, i++) {
|
||||
struct characteristic *chr = l->data;
|
||||
chars[i] = chr->path;
|
||||
}
|
||||
|
||||
dict_append_array(&dict, "Characteristics", DBUS_TYPE_OBJECT_PATH,
|
||||
&chars, i);
|
||||
uuid = prim->att->uuid;
|
||||
uuid = gatt->prim->uuid;
|
||||
dict_append_entry(&dict, "UUID", DBUS_TYPE_STRING, &uuid);
|
||||
|
||||
g_free(chars);
|
||||
@ -1032,80 +976,92 @@ static GDBusMethodTable prim_methods[] = {
|
||||
{ }
|
||||
};
|
||||
|
||||
static struct primary *primary_register(struct gatt_service *gatt,
|
||||
struct att_primary *prim)
|
||||
static struct gatt_service *primary_register(DBusConnection *conn,
|
||||
struct btd_device *device,
|
||||
struct att_primary *prim,
|
||||
int psm)
|
||||
{
|
||||
struct btd_device *device = gatt->dev;
|
||||
struct gatt_service *gatt;
|
||||
const char *device_path;
|
||||
struct primary *data;
|
||||
|
||||
device_path = device_get_path(device);
|
||||
|
||||
data = g_new0(struct primary, 1);
|
||||
data->att = prim;
|
||||
data->gatt = gatt;
|
||||
data->path = g_strdup_printf("%s/service%04x", device_path,
|
||||
gatt = g_new0(struct gatt_service, 1);
|
||||
gatt->dev = btd_device_ref(device);
|
||||
gatt->prim = prim;
|
||||
gatt->psm = psm;
|
||||
gatt->listen = FALSE;
|
||||
gatt->conn = dbus_connection_ref(conn);
|
||||
gatt->path = g_strdup_printf("%s/service%04x", device_path,
|
||||
prim->start);
|
||||
|
||||
g_dbus_register_interface(gatt->conn, data->path,
|
||||
g_dbus_register_interface(gatt->conn, gatt->path,
|
||||
CHAR_INTERFACE, prim_methods,
|
||||
NULL, NULL, data, NULL);
|
||||
NULL, NULL, gatt, NULL);
|
||||
gatt->chars = load_characteristics(gatt, prim->start);
|
||||
g_slist_foreach(gatt->chars, register_characteristic, gatt->path);
|
||||
|
||||
load_characteristics(data, gatt);
|
||||
|
||||
return data;
|
||||
return gatt;
|
||||
}
|
||||
|
||||
GSList *attrib_client_register(DBusConnection *connection,
|
||||
struct btd_device *device, int psm,
|
||||
GAttrib *attrib, GSList *primaries)
|
||||
{
|
||||
struct gatt_service *gatt;
|
||||
GSList *l, *services;
|
||||
|
||||
for (l = primaries, services = NULL; l; l = l->next) {
|
||||
struct att_primary *prim = l->data;
|
||||
struct gatt_service *gatt;
|
||||
|
||||
gatt = primary_register(connection, device, prim, psm);
|
||||
|
||||
DBG("Registered: %s", gatt->path);
|
||||
|
||||
services = g_slist_append(services, g_strdup(gatt->path));
|
||||
gatt_services = g_slist_append(gatt_services, gatt);
|
||||
}
|
||||
|
||||
return services;
|
||||
}
|
||||
|
||||
static void primary_unregister(struct gatt_service *gatt)
|
||||
{
|
||||
GSList *l;
|
||||
|
||||
gatt = g_new0(struct gatt_service, 1);
|
||||
gatt->dev = btd_device_ref(device);
|
||||
gatt->conn = dbus_connection_ref(connection);
|
||||
gatt->listen = FALSE;
|
||||
gatt->psm = psm;
|
||||
|
||||
for (l = primaries; l; l = l->next) {
|
||||
struct att_primary *prim = l->data;
|
||||
struct primary *data;
|
||||
|
||||
data = primary_register(gatt, prim);
|
||||
gatt->primary = g_slist_append(gatt->primary, data);
|
||||
|
||||
DBG("Registered: %s", data->path);
|
||||
for (l = gatt->chars; l; l = l->next) {
|
||||
struct characteristic *chr = l->data;
|
||||
g_dbus_unregister_interface(gatt->conn, chr->path,
|
||||
CHAR_INTERFACE);
|
||||
}
|
||||
|
||||
gatt_services = g_slist_append(gatt_services, gatt);
|
||||
|
||||
return gatt_services;
|
||||
g_dbus_unregister_interface(gatt->conn, gatt->path, CHAR_INTERFACE);
|
||||
}
|
||||
|
||||
void attrib_client_unregister(struct btd_device *device)
|
||||
static int path_cmp(gconstpointer data, gconstpointer user_data)
|
||||
{
|
||||
struct gatt_service *gatt;
|
||||
GSList *l, *lp, *lc;
|
||||
const char *path = data;
|
||||
const char *gatt_path = user_data;
|
||||
|
||||
l = g_slist_find_custom(gatt_services, device, gatt_dev_cmp);
|
||||
if (!l)
|
||||
return;
|
||||
return g_strcmp0(path, gatt_path);
|
||||
}
|
||||
|
||||
gatt = l->data;
|
||||
gatt_services = g_slist_remove(gatt_services, gatt);
|
||||
void attrib_client_unregister(GSList *services)
|
||||
{
|
||||
GSList *l, *left;
|
||||
|
||||
for (lp = gatt->primary; lp; lp = lp->next) {
|
||||
struct primary *prim = lp->data;
|
||||
for (lc = prim->chars; lc; lc = lc->next) {
|
||||
struct characteristic *chr = lc->data;
|
||||
g_dbus_unregister_interface(gatt->conn, chr->path,
|
||||
CHAR_INTERFACE);
|
||||
for (l = gatt_services, left = NULL; l; l = l->next) {
|
||||
struct gatt_service *gatt = l->data;
|
||||
|
||||
if (!g_slist_find_custom(services, gatt->path, path_cmp)) {
|
||||
left = g_slist_append(left, gatt);
|
||||
continue;
|
||||
}
|
||||
g_dbus_unregister_interface(gatt->conn, prim->path,
|
||||
CHAR_INTERFACE);
|
||||
|
||||
primary_unregister(gatt);
|
||||
gatt_service_free(gatt);
|
||||
}
|
||||
|
||||
gatt_service_free(gatt);
|
||||
g_slist_free(gatt_services);
|
||||
gatt_services = left;
|
||||
}
|
||||
|
@ -25,4 +25,4 @@
|
||||
GSList *attrib_client_register(DBusConnection *connection,
|
||||
struct btd_device *device, int psm,
|
||||
GAttrib *attrib, GSList *primaries);
|
||||
void attrib_client_unregister(struct btd_device *device);
|
||||
void attrib_client_unregister(GSList *services);
|
||||
|
@ -1035,7 +1035,7 @@ void device_remove(struct btd_device *device, gboolean remove_stored)
|
||||
g_slist_free(device->drivers);
|
||||
device->drivers = NULL;
|
||||
|
||||
attrib_client_unregister(device);
|
||||
attrib_client_unregister(device->services);
|
||||
|
||||
btd_device_unref(device);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user