static void test_refcount(struct context *cxt, gconstpointer unused) { GAttrib *extra_ref; int destroy_canary = 0; g_attrib_set_destroy_function(cxt->att, destroy_canary_increment, &destroy_canary); extra_ref = g_attrib_ref(cxt->att); g_assert(extra_ref == cxt->att); g_assert(destroy_canary == 0); g_attrib_unref(extra_ref); g_assert(destroy_canary == 0); g_attrib_unref(cxt->att); g_assert(destroy_canary == 1); /* Avoid a double-free from the teardown function */ cxt->att = NULL; }
static void attio_disconnected(gpointer user_data) { struct gatt_service *gatt = user_data; if (gatt->query && gatt->query->msg) { DBusMessage *reply; reply = btd_error_failed(gatt->query->msg, "ATT IO channel was disconnected"); g_dbus_send_message(gatt->conn, reply); dbus_message_unref(gatt->query->msg); gatt->query->msg = NULL; } if (gatt->query) { g_slist_free_full(gatt->query->list, g_free); gatt->query = NULL; } if (gatt->attrib) { g_attrib_cancel_all(gatt->attrib); g_attrib_unref(gatt->attrib); gatt->attrib = NULL; } }
void bt_hog_detach(struct bt_hog *hog) { GSList *l; if (!hog->attrib) return; for (l = hog->instances; l; l = l->next) { struct bt_hog *instance = l->data; bt_hog_detach(instance); } for (l = hog->reports; l; l = l->next) { struct report *r = l->data; if (r->notifyid > 0) { g_attrib_unregister(hog->attrib, r->notifyid); r->notifyid = 0; } } if (hog->scpp) bt_scpp_detach(hog->scpp); if (hog->dis) bt_dis_detach(hog->dis); if (hog->bas) bt_bas_detach(hog->bas); g_attrib_unref(hog->attrib); hog->attrib = NULL; }
static void attio_disconnected_cb(gpointer user_data) { struct scan *scan = user_data; g_attrib_unref(scan->attrib); scan->attrib = NULL; }
static void destroy_sender(gpointer data) { struct _GAttrib *attrib = data; attrib->write_watch = 0; g_attrib_unref(attrib); }
static void attio_disconnected_cb(gpointer user_data) { struct deviceinfo *d = user_data; g_attrib_unref(d->attrib); d->attrib = NULL; }
static void discover_char_free(struct discover_char *dc) { g_slist_free_full(dc->characteristics, g_free); g_attrib_unref(dc->attrib); g_free(dc->uuid); g_free(dc); }
static void disconnect(GAttrib* attrib, GIOChannel* chan) { g_attrib_unref(attrib); g_io_channel_shutdown(chan, FALSE, NULL); g_io_channel_unref(chan); }
static gboolean disconnect_timeout(gpointer data) { struct _GAttrib *attrib = data; struct command *c; g_attrib_ref(attrib); c = g_queue_pop_head(attrib->requests); if (c == NULL) goto done; if (c->func) c->func(ATT_ECODE_TIMEOUT, NULL, 0, c->user_data); command_destroy(c); while ((c = g_queue_pop_head(attrib->requests))) { if (c->func) c->func(ATT_ECODE_ABORTED, NULL, 0, c->user_data); command_destroy(c); } done: attrib->stale = true; g_attrib_unref(attrib); return FALSE; }
guint gatt_read_char(GAttrib *attrib, uint16_t handle, GAttribResultFunc func, gpointer user_data) { uint8_t *buf; size_t buflen; guint16 plen; guint id; struct read_long_data *long_read; long_read = g_try_new0(struct read_long_data, 1); if (long_read == NULL) return 0; long_read->attrib = g_attrib_ref(attrib); long_read->func = func; long_read->user_data = user_data; long_read->handle = handle; buf = g_attrib_get_buffer(attrib, &buflen); plen = enc_read_req(handle, buf, buflen); id = g_attrib_send(attrib, 0, buf, plen, read_char_helper, long_read, read_long_destroy); if (id == 0) { g_attrib_unref(long_read->attrib); g_free(long_read); } else { __sync_fetch_and_add(&long_read->ref, 1); long_read->id = id; } return id; }
static void cleanup_monitor(struct monitor *monitor) { struct btd_device *device = monitor->device; const char *path = device_get_path(device); if (monitor->immediate != NULL || monitor->txpower != NULL) return; if (monitor->immediateto != 0) { g_source_remove(monitor->immediateto); monitor->immediateto = 0; } if (monitor->linkloss != NULL) return; if (monitor->attioid != 0) { btd_device_remove_attio_callback(device, monitor->attioid); monitor->attioid = 0; } if (monitor->attrib != NULL) { g_attrib_unref(monitor->attrib); monitor->attrib = NULL; } g_dbus_unregister_interface(btd_get_dbus_connection(), path, PROXIMITY_INTERFACE); }
static void discover_char_free(struct discover_char *dc) { g_slist_foreach(dc->characteristics, (GFunc) g_free, NULL); g_slist_free(dc->characteristics); g_attrib_unref(dc->attrib); g_free(dc->uuid); g_free(dc); }
static void cancel_discover(gpointer user_data) { struct query_data *qchr = user_data; struct gatt_service *gatt = qchr->gatt; g_attrib_unref(gatt->attrib); gatt->attrib = NULL; }
void bt_dis_detach(struct bt_dis *dis) { if (!dis->attrib) return; queue_foreach(dis->gatt_op, (void *) cancel_gatt_req, NULL); g_attrib_unref(dis->attrib); dis->attrib = NULL; }
int gattlib_disconnect(gatt_connection_t* connection) { // Stop the I/O Channel GIOStatus status = g_io_channel_shutdown(connection->io, FALSE, NULL); assert(status == G_IO_STATUS_NORMAL); g_io_channel_unref(connection->io); g_attrib_unref(connection->attrib); free(connection); task_dec(); return 0; }
static void read_destroy(gpointer user_data) { struct read_data *read = user_data; if (__sync_sub_and_fetch(&read->ref, 1) > 0) return; g_attrib_unref(read->attrib); g_free(read); }
static void teardown_context(struct context *cxt, gconstpointer data) { if (cxt->att) g_attrib_unref(cxt->att); g_io_channel_unref(cxt->server_io); g_io_channel_unref(cxt->att_io); g_main_loop_unref(cxt->main_loop); }
static void disconnect_io() { g_attrib_unref(attrib); attrib = NULL; opt_mtu = 0; g_io_channel_shutdown(iochannel, FALSE, NULL); g_io_channel_unref(iochannel); iochannel = NULL; printf("Disconnect_IO"); }
static void scan_param_remove(struct btd_service *service) { struct scan *scan = btd_service_get_user_data(service); if (scan->attrib != NULL && scan->refresh_cb_id > 0) g_attrib_unregister(scan->attrib, scan->refresh_cb_id); btd_device_remove_attio_callback(scan->device, scan->attioid); btd_device_unref(scan->device); g_attrib_unref(scan->attrib); g_free(scan); }
static void discover_primary_unref(void *data) { struct discover_primary *dp = data; dp->ref--; if (dp->ref > 0) return; g_slist_free_full(dp->primaries, g_free); g_attrib_unref(dp->attrib); g_free(dp); }
void bt_scpp_detach(struct bt_scpp *scan) { if (!scan || !scan->attrib) return; if (scan->refresh_cb_id > 0) { g_attrib_unregister(scan->attrib, scan->refresh_cb_id); scan->refresh_cb_id = 0; } queue_foreach(scan->gatt_op, (void *) cancel_gatt_req, NULL); g_attrib_unref(scan->attrib); scan->attrib = NULL; }
static void read_long_destroy(gpointer user_data) { struct read_long_data *long_read = user_data; if (__sync_sub_and_fetch(&long_read->ref, 1) > 0) return; g_attrib_unref(long_read->attrib); if (long_read->buffer != NULL) g_free(long_read->buffer); g_free(long_read); }
static void discover_desc_unref(void *data) { struct discover_desc *dd = data; dd->ref--; if (dd->ref > 0) return; g_slist_free_full(dd->descriptors, g_free); g_attrib_unref(dd->attrib); g_free(dd->uuid); g_free(dd); }
static void discover_char_unref(void *data) { struct discover_char *dc = data; dc->ref--; if (dc->ref > 0) return; g_slist_free_full(dc->characteristics, g_free); g_attrib_unref(dc->attrib); g_free(dc->uuid); g_free(dc); }
static void isd_unref(struct included_discovery *isd) { if (__sync_sub_and_fetch(&isd->refs, 1) > 0) return; if (isd->err) isd->cb(NULL, isd->err, isd->user_data); else isd->cb(isd->includes, isd->err, isd->user_data); g_slist_free_full(isd->includes, g_free); g_attrib_unref(isd->attrib); g_free(isd); }
void bt_bas_detach(struct bt_bas *bas) { if (!bas || !bas->attrib) return; if (bas->id > 0) { g_attrib_unregister(bas->attrib, bas->id); bas->id = 0; } queue_foreach(bas->gatt_op, (void *) cancel_gatt_req, NULL); g_attrib_unref(bas->attrib); bas->attrib = NULL; }
static void attio_disconnected_cb(gpointer user_data) { struct heartrate *hr = user_data; DBG(""); if (hr->attionotid > 0) { g_attrib_unregister(hr->attrib, hr->attionotid); hr->attionotid = 0; } g_attrib_unref(hr->attrib); hr->attrib = NULL; }
static void disconnect_io() { if (conn_state == STATE_DISCONNECTED) return; g_attrib_unref(attrib); attrib = NULL; opt_mtu = 0; g_io_channel_shutdown(iochannel, FALSE, NULL); g_io_channel_unref(iochannel); iochannel = NULL; set_state(STATE_DISCONNECTED); }
static void deviceinfo_driver_remove(struct btd_service *service) { struct deviceinfo *d = btd_service_get_user_data(service); if (d->attioid > 0) btd_device_remove_attio_callback(d->dev, d->attioid); if (d->attrib != NULL) g_attrib_unref(d->attrib); g_slist_free_full(d->chars, g_free); btd_device_unref(d->dev); g_free(d->svc_range); g_free(d); }
static void destroy_heartrate(gpointer user_data) { struct heartrate *hr = user_data; if (hr->attioid > 0) btd_device_remove_attio_callback(hr->dev, hr->attioid); if (hr->attrib != NULL) { g_attrib_unregister(hr->attrib, hr->attionotid); g_attrib_unref(hr->attrib); } btd_device_unref(hr->dev); g_free(hr->svc_range); g_free(hr); }