struct hfp_gw *hfp_gw_new(int fd) { struct hfp_gw *hfp; if (fd < 0) return NULL; hfp = new0(struct hfp_gw, 1); if (!hfp) return NULL; hfp->fd = fd; hfp->close_on_unref = false; hfp->read_buf = ringbuf_new(4096); if (!hfp->read_buf) { free(hfp); return NULL; } hfp->write_buf = ringbuf_new(4096); if (!hfp->write_buf) { ringbuf_free(hfp->read_buf); free(hfp); return NULL; } hfp->io = io_new(fd); if (!hfp->io) { ringbuf_free(hfp->write_buf); ringbuf_free(hfp->read_buf); free(hfp); return NULL; } hfp->cmd_handlers = queue_new(); if (!hfp->cmd_handlers) { io_destroy(hfp->io); ringbuf_free(hfp->write_buf); ringbuf_free(hfp->read_buf); free(hfp); return NULL; } if (!io_set_read_handler(hfp->io, can_read_data, hfp, read_watch_destroy)) { queue_destroy(hfp->cmd_handlers, destroy_cmd_handler); io_destroy(hfp->io); ringbuf_free(hfp->write_buf); ringbuf_free(hfp->read_buf); free(hfp); return NULL; } hfp->writer_active = false; hfp->result_pending = false; return hfp_gw_ref(hfp); }
static struct bt_hci *create_hci(int fd) { struct bt_hci *hci; if (fd < 0) return NULL; hci = new0(struct bt_hci, 1); if (!hci) return NULL; hci->io = io_new(fd); if (!hci->io) { free(hci); return NULL; } hci->is_stream = true; hci->writer_active = false; hci->num_cmds = 1; hci->next_cmd_id = 1; hci->next_evt_id = 1; hci->cmd_queue = queue_new(); if (!hci->cmd_queue) { io_destroy(hci->io); free(hci); return NULL; } hci->rsp_queue = queue_new(); if (!hci->rsp_queue) { queue_destroy(hci->cmd_queue, NULL); io_destroy(hci->io); free(hci); return NULL; } hci->evt_list = queue_new(); if (!hci->evt_list) { queue_destroy(hci->rsp_queue, NULL); queue_destroy(hci->cmd_queue, NULL); io_destroy(hci->io); free(hci); return NULL; } if (!io_set_read_handler(hci->io, io_read_callback, hci, NULL)) { queue_destroy(hci->evt_list, NULL); queue_destroy(hci->rsp_queue, NULL); queue_destroy(hci->cmd_queue, NULL); io_destroy(hci->io); free(hci); return NULL; } return bt_hci_ref(hci); }
struct bt_att *bt_att_new(int fd) { struct bt_att *att; if (fd < 0) return NULL; att = new0(struct bt_att, 1); if (!att) return NULL; att->fd = fd; att->mtu = ATT_DEFAULT_LE_MTU; att->buf = malloc(att->mtu); if (!att->buf) goto fail; att->io = io_new(fd); if (!att->io) goto fail; att->req_queue = queue_new(); if (!att->req_queue) goto fail; att->ind_queue = queue_new(); if (!att->ind_queue) goto fail; att->write_queue = queue_new(); if (!att->write_queue) goto fail; att->notify_list = queue_new(); if (!att->notify_list) goto fail; if (!io_set_read_handler(att->io, can_read_data, att, NULL)) goto fail; return bt_att_ref(att); fail: queue_destroy(att->req_queue, NULL); queue_destroy(att->ind_queue, NULL); queue_destroy(att->write_queue, NULL); io_destroy(att->io); free(att->buf); free(att); return NULL; }
struct bt_uhid *bt_uhid_new(int fd) { struct bt_uhid *uhid; uhid = new0(struct bt_uhid, 1); uhid->io = io_new(fd); if (!uhid->io) goto failed; uhid->notify_list = queue_new(); if (!io_set_read_handler(uhid->io, uhid_read_handler, uhid, NULL)) goto failed; return bt_uhid_ref(uhid); failed: uhid_free(uhid); return NULL; }
void bt_att_unref(struct bt_att *att) { if (!att) return; if (__sync_sub_and_fetch(&att->ref_count, 1)) return; bt_att_unregister_all(att); bt_att_cancel_all(att); io_set_write_handler(att->io, NULL, NULL, NULL); io_set_read_handler(att->io, NULL, NULL, NULL); queue_destroy(att->req_queue, NULL); queue_destroy(att->ind_queue, NULL); queue_destroy(att->write_queue, NULL); queue_destroy(att->notify_list, NULL); att->req_queue = NULL; att->ind_queue = NULL; att->write_queue = NULL; att->notify_list = NULL; io_destroy(att->io); att->io = NULL; if (att->close_on_unref) close(att->fd); if (att->timeout_destroy) att->timeout_destroy(att->timeout_data); if (att->debug_destroy) att->debug_destroy(att->debug_data); free(att->buf); att->buf = NULL; free(att); }
void hfp_hf_unref(struct hfp_hf *hfp) { if (!hfp) return; if (__sync_sub_and_fetch(&hfp->ref_count, 1)) return; io_set_write_handler(hfp->io, NULL, NULL, NULL); io_set_read_handler(hfp->io, NULL, NULL, NULL); io_set_disconnect_handler(hfp->io, NULL, NULL, NULL); io_destroy(hfp->io); hfp->io = NULL; if (hfp->close_on_unref) close(hfp->fd); hfp_hf_set_debug(hfp, NULL, NULL, NULL); ringbuf_free(hfp->read_buf); hfp->read_buf = NULL; ringbuf_free(hfp->write_buf); hfp->write_buf = NULL; queue_destroy(hfp->event_handlers, destroy_event_handler); hfp->event_handlers = NULL; queue_destroy(hfp->cmd_queue, free); hfp->cmd_queue = NULL; if (!hfp->in_disconnect) { free(hfp); return; } hfp->destroyed = true; }
void mgmt_unref(struct mgmt *mgmt) { if (!mgmt) return; if (__sync_sub_and_fetch(&mgmt->ref_count, 1)) return; mgmt_unregister_all(mgmt); mgmt_cancel_all(mgmt); queue_destroy(mgmt->reply_queue, NULL); queue_destroy(mgmt->request_queue, NULL); io_set_write_handler(mgmt->io, NULL, NULL, NULL); io_set_read_handler(mgmt->io, NULL, NULL, NULL); io_destroy(mgmt->io); mgmt->io = NULL; if (mgmt->close_on_unref) close(mgmt->fd); if (mgmt->debug_destroy) mgmt->debug_destroy(mgmt->debug_data); free(mgmt->buf); mgmt->buf = NULL; if (!mgmt->in_notify) { queue_destroy(mgmt->notify_list, NULL); queue_destroy(mgmt->pending_list, NULL); free(mgmt); return; } mgmt->destroyed = true; }
struct bt_att *bt_att_new(int fd, bool ext_signed) { struct bt_att *att; if (fd < 0) return NULL; att = new0(struct bt_att, 1); if (!att) return NULL; att->fd = fd; att->mtu = BT_ATT_DEFAULT_LE_MTU; att->buf = malloc(att->mtu); if (!att->buf) goto fail; att->io = io_new(fd); if (!att->io) goto fail; /* crypto is optional, if not available leave it NULL */ if (!ext_signed) att->crypto = bt_crypto_new(); att->req_queue = queue_new(); if (!att->req_queue) goto fail; att->ind_queue = queue_new(); if (!att->ind_queue) goto fail; att->write_queue = queue_new(); if (!att->write_queue) goto fail; att->notify_list = queue_new(); if (!att->notify_list) goto fail; att->disconn_list = queue_new(); if (!att->disconn_list) goto fail; if (!io_set_read_handler(att->io, can_read_data, att, NULL)) goto fail; if (!io_set_disconnect_handler(att->io, disconnect_cb, att, NULL)) goto fail; att->io_on_l2cap = is_io_l2cap_based(att->fd); if (!att->io_on_l2cap) att->io_sec_level = BT_SECURITY_LOW; return bt_att_ref(att); fail: bt_att_free(att); return NULL; }
struct mgmt *mgmt_new(int fd) { struct mgmt *mgmt; if (fd < 0) return NULL; mgmt = new0(struct mgmt, 1); if (!mgmt) return NULL; mgmt->fd = fd; mgmt->close_on_unref = false; mgmt->len = 512; mgmt->buf = malloc(mgmt->len); if (!mgmt->buf) { free(mgmt); return NULL; } mgmt->io = io_new(fd); if (!mgmt->io) { free(mgmt->buf); free(mgmt); return NULL; } mgmt->request_queue = queue_new(); if (!mgmt->request_queue) { io_destroy(mgmt->io); free(mgmt->buf); free(mgmt); return NULL; } mgmt->reply_queue = queue_new(); if (!mgmt->reply_queue) { queue_destroy(mgmt->request_queue, NULL); io_destroy(mgmt->io); free(mgmt->buf); free(mgmt); return NULL; } mgmt->pending_list = queue_new(); if (!mgmt->pending_list) { queue_destroy(mgmt->reply_queue, NULL); queue_destroy(mgmt->request_queue, NULL); io_destroy(mgmt->io); free(mgmt->buf); free(mgmt); return NULL; } mgmt->notify_list = queue_new(); if (!mgmt->notify_list) { queue_destroy(mgmt->pending_list, NULL); queue_destroy(mgmt->reply_queue, NULL); queue_destroy(mgmt->request_queue, NULL); io_destroy(mgmt->io); free(mgmt->buf); free(mgmt); return NULL; } if (!io_set_read_handler(mgmt->io, can_read_data, mgmt, read_watch_destroy)) { queue_destroy(mgmt->notify_list, NULL); queue_destroy(mgmt->pending_list, NULL); queue_destroy(mgmt->reply_queue, NULL); queue_destroy(mgmt->request_queue, NULL); io_destroy(mgmt->io); free(mgmt->buf); free(mgmt); return NULL; } mgmt->writer_active = false; return mgmt_ref(mgmt); }
struct hfp_hf *hfp_hf_new(int fd) { struct hfp_hf *hfp; if (fd < 0) return NULL; hfp = new0(struct hfp_hf, 1); if (!hfp) return NULL; hfp->fd = fd; hfp->close_on_unref = false; hfp->read_buf = ringbuf_new(4096); if (!hfp->read_buf) { free(hfp); return NULL; } hfp->write_buf = ringbuf_new(4096); if (!hfp->write_buf) { ringbuf_free(hfp->read_buf); free(hfp); return NULL; } hfp->io = io_new(fd); if (!hfp->io) { ringbuf_free(hfp->write_buf); ringbuf_free(hfp->read_buf); free(hfp); return NULL; } hfp->event_handlers = queue_new(); if (!hfp->event_handlers) { io_destroy(hfp->io); ringbuf_free(hfp->write_buf); ringbuf_free(hfp->read_buf); free(hfp); return NULL; } hfp->cmd_queue = queue_new(); if (!hfp->cmd_queue) { io_destroy(hfp->io); ringbuf_free(hfp->write_buf); ringbuf_free(hfp->read_buf); queue_destroy(hfp->event_handlers, NULL); free(hfp); return NULL; } hfp->writer_active = false; if (!io_set_read_handler(hfp->io, hf_can_read_data, hfp, read_watch_destroy)) { queue_destroy(hfp->event_handlers, destroy_event_handler); io_destroy(hfp->io); ringbuf_free(hfp->write_buf); ringbuf_free(hfp->read_buf); free(hfp); return NULL; } return hfp_hf_ref(hfp); }