int avctp_register(const bdaddr_t *src, gboolean master) { struct avctp_server *server; server = g_new0(struct avctp_server, 1); if (!server) return -ENOMEM; server->io = avctp_server_socket(src, master); if (!server->io) { g_free(server); return -1; } bacpy(&server->src, src); servers = g_slist_append(servers, server); if (!passthrough_id) passthrough_id = avctp_register_pdu_handler(AVC_OP_PASSTHROUGH, handle_panel_passthrough, NULL); if (!unit_id) unit_id = avctp_register_pdu_handler(AVC_OP_UNITINFO, handle_unit_info, NULL); if (!subunit_id) subunit_id = avctp_register_pdu_handler(AVC_OP_SUBUNITINFO, handle_subunit_info, NULL); return 0; }
struct avctp *avctp_new(int fd, size_t imtu, size_t omtu, uint16_t version) { struct avctp *session; struct avctp_channel *control; GIOCondition cond = G_IO_IN | G_IO_ERR | G_IO_HUP | G_IO_NVAL; session = g_new0(struct avctp, 1); session->version = version; control = avctp_channel_create(session, fd, imtu, omtu, NULL); if (!control) { g_free(session); return NULL; } session->uinput = -1; session->control = control; session->passthrough_id = avctp_register_pdu_handler(session, AVC_OP_PASSTHROUGH, handle_panel_passthrough, NULL); session->unit_id = avctp_register_pdu_handler(session, AVC_OP_UNITINFO, handle_unit_info, NULL); session->subunit_id = avctp_register_pdu_handler(session, AVC_OP_SUBUNITINFO, handle_subunit_info, NULL); control->watch = g_io_add_watch(session->control->io, cond, (GIOFunc) session_cb, session); return session; }
static void avctp_connect_cb(GIOChannel *chan, GError *err, gpointer data) { struct avctp *session = data; char address[18]; uint16_t imtu, omtu; GError *gerr = NULL; if (err) { avctp_set_state(session, AVCTP_STATE_DISCONNECTED); error("%s", err->message); return; } bt_io_get(chan, &gerr, BT_IO_OPT_DEST, &address, BT_IO_OPT_IMTU, &imtu, BT_IO_OPT_IMTU, &omtu, BT_IO_OPT_INVALID); if (gerr) { avctp_set_state(session, AVCTP_STATE_DISCONNECTED); error("%s", gerr->message); g_error_free(gerr); return; } DBG("AVCTP: connected to %s", address); if (session->control == NULL) session->control = avctp_channel_create(session, chan, NULL); session->control->imtu = imtu; session->control->omtu = omtu; session->control->buffer = g_malloc0(MAX(imtu, omtu)); session->control->watch = g_io_add_watch(session->control->io, G_IO_IN | G_IO_ERR | G_IO_HUP | G_IO_NVAL, (GIOFunc) session_cb, session); session->passthrough_id = avctp_register_pdu_handler(session, AVC_OP_PASSTHROUGH, handle_panel_passthrough, NULL); session->unit_id = avctp_register_pdu_handler(session, AVC_OP_UNITINFO, handle_unit_info, NULL); session->subunit_id = avctp_register_pdu_handler(session, AVC_OP_SUBUNITINFO, handle_subunit_info, NULL); init_uinput(session); avctp_set_state(session, AVCTP_STATE_CONNECTED); }