static DBusMessage *add_sap_service_record(DBusConnection *conn, DBusMessage *msg, void *data) { DBG(""); sdp_record_t *record = NULL; GError *gerr = NULL; record = create_sap_record(SAP_SERVER_CHANNEL); if (!record) { error("Creating SAP SDP record failed."); goto sdp_err; } if (add_record_to_server(&server->src, record) < 0) { error("Adding SAP SDP record to the SDP server failed."); sdp_record_free(record); goto sdp_err; } server->record_id = record->handle; DBG("EXIT"); return dbus_message_new_method_return(msg); sdp_err: server_free(server); sap_exit(); return dbus_message_new_method_return(msg); }
static DBusMessage *update_record(DBusConnection *conn, DBusMessage *msg, struct service_adapter *serv_adapter, dbus_uint32_t handle, sdp_record_t *sdp_record) { bdaddr_t src; int err; if (remove_record_from_server(handle) < 0) { sdp_record_free(sdp_record); return btd_error_not_available(msg); } if (serv_adapter->adapter) adapter_get_address(serv_adapter->adapter, &src); else bacpy(&src, BDADDR_ANY); sdp_record->handle = handle; err = add_record_to_server(&src, sdp_record); if (err < 0) { sdp_record_free(sdp_record); error("Failed to update the service record"); return btd_error_failed(msg, strerror(-err)); } return dbus_message_new_method_return(msg); }
static struct a2dp_sep *a2dp_add_sep(DBusConnection *conn, uint8_t type, uint8_t codec) { struct a2dp_sep *sep; GSList **l; sdp_record_t *(*create_record)(void); uint32_t *record_id; sdp_record_t *record; struct avdtp_sep_ind *ind; sep = g_new0(struct a2dp_sep, 1); ind = (codec == A2DP_CODEC_MPEG12) ? &mpeg_ind : &sbc_ind; sep->sep = avdtp_register_sep(type, AVDTP_MEDIA_TYPE_AUDIO, codec, ind, &cfm, sep); if (sep->sep == NULL) { g_free(sep); return NULL; } sep->codec = codec; sep->type = type; if (type == AVDTP_SEP_TYPE_SOURCE) { l = &sources; create_record = a2dp_source_record; record_id = &source_record_id; } else { l = &sinks; create_record = a2dp_sink_record; record_id = &sink_record_id; } if (*record_id != 0) goto add; record = create_record(); if (!record) { error("Unable to allocate new service record"); avdtp_unregister_sep(sep->sep); g_free(sep); return NULL; } if (add_record_to_server(BDADDR_ANY, record) < 0) { error("Unable to register A2DP service record");\ sdp_record_free(record); avdtp_unregister_sep(sep->sep); g_free(sep); return NULL; } *record_id = record->handle; add: *l = g_slist_append(*l, sep); return sep; }
static struct a2dp_sep *a2dp_add_sep(struct a2dp_server *server, uint8_t type, uint8_t codec, gboolean delay_reporting) { struct a2dp_sep *sep; GSList **l; uint32_t *record_id; sdp_record_t *record; struct avdtp_sep_ind *ind; sep = g_new0(struct a2dp_sep, 1); ind = (codec == A2DP_CODEC_MPEG12) ? &mpeg_ind : &sbc_ind; sep->sep = avdtp_register_sep(&server->src, type, AVDTP_MEDIA_TYPE_AUDIO, codec, delay_reporting, ind, &cfm, sep); if (sep->sep == NULL) { g_free(sep); return NULL; } sep->codec = codec; sep->type = type; sep->delay_reporting = delay_reporting; if (type == AVDTP_SEP_TYPE_SOURCE) { l = &server->sources; record_id = &server->source_record_id; } else { l = &server->sinks; record_id = &server->sink_record_id; } if (*record_id != 0) goto add; record = a2dp_record(type, server->version); if (!record) { error("Unable to allocate new service record"); avdtp_unregister_sep(sep->sep); g_free(sep); return NULL; } if (add_record_to_server(&server->src, record) < 0) { error("Unable to register A2DP service record"); \ sdp_record_free(record); avdtp_unregister_sep(sep->sep); g_free(sep); return NULL; } *record_id = record->handle; add: *l = g_slist_append(*l, sep); return sep; }
gboolean hdp_update_sdp_record(struct hdp_adapter *adapter, GSList *app_list) { sdp_record_t *sdp_record; bdaddr_t addr; if (adapter->sdp_handler) remove_record_from_server(adapter->sdp_handler); if (!app_list) { adapter->sdp_handler = 0; return TRUE; } sdp_record = sdp_record_alloc(); if (!sdp_record) return FALSE; if (adapter->sdp_handler) sdp_record->handle = adapter->sdp_handler; else sdp_record->handle = 0xffffffff; /* Set automatically */ if (is_app_role(app_list, HDP_SINK)) set_sdp_services_uuid(sdp_record, HDP_SINK); if (is_app_role(app_list, HDP_SOURCE)) set_sdp_services_uuid(sdp_record, HDP_SOURCE); if (!register_service_protocols(adapter, sdp_record)) goto fail; if (!register_service_profiles(sdp_record)) goto fail; if (!register_service_additional_protocols(adapter, sdp_record)) goto fail; sdp_set_info_attr(sdp_record, HDP_SERVICE_NAME, HDP_SERVICE_PROVIDER, HDP_SERVICE_DSC); if (!register_service_sup_features(app_list, sdp_record)) goto fail; if (!register_data_exchange_spec(sdp_record)) goto fail; register_mcap_features(sdp_record); if (sdp_set_record_state(sdp_record, adapter->record_state++)) goto fail; adapter_get_address(adapter->btd_adapter, &addr); if (add_record_to_server(&addr, sdp_record) < 0) goto fail; adapter->sdp_handler = sdp_record->handle; return TRUE; fail: if (sdp_record) sdp_record_free(sdp_record); return FALSE; }
static int pnat_probe(struct btd_adapter *adapter) { struct dun_server *server; GIOChannel *io; GError *err = NULL; sdp_record_t *record; bdaddr_t src; adapter_get_address(adapter, &src); server = g_new0(struct dun_server, 1); io = bt_io_listen(BT_IO_RFCOMM, NULL, confirm_cb, server, NULL, &err, BT_IO_OPT_SOURCE_BDADDR, &src, BT_IO_OPT_CHANNEL, DUN_CHANNEL, BT_IO_OPT_INVALID); if (err != NULL) { error("Failed to start DUN server: %s", err->message); g_error_free(err); goto fail; } record = dun_record(DUN_CHANNEL); if (!record) { error("Unable to allocate new service record"); goto fail; } if (add_record_to_server(&src, record) < 0) { error("Unable to register DUN service record"); goto fail; } server->rfcomm_ctl = socket(AF_BLUETOOTH, SOCK_RAW, BTPROTO_RFCOMM); if (server->rfcomm_ctl < 0) { error("Unable to create RFCOMM control socket: %s (%d)", strerror(errno), errno); goto fail; } server->server = io; server->record_handle = record->handle; bacpy(&server->bda, &src); servers = g_slist_append(servers, server); return 0; fail: if (io != NULL) g_io_channel_unref(io); g_free(server); return -EIO; }
static int gateway_server_init(struct audio_adapter *adapter) { uint8_t chan = DEFAULT_HFP_HS_CHANNEL; sdp_record_t *record; gboolean master = TRUE; GError *err = NULL; GIOChannel *io; bdaddr_t src; if (config) { gboolean tmp; tmp = g_key_file_get_boolean(config, "General", "Master", &err); if (err) { DBG("audio.conf: %s", err->message); g_clear_error(&err); } else master = tmp; } adapter_get_address(adapter->btd_adapter, &src); io = bt_io_listen(BT_IO_RFCOMM, NULL, hf_io_cb, adapter, NULL, &err, BT_IO_OPT_SOURCE_BDADDR, &src, BT_IO_OPT_CHANNEL, chan, BT_IO_OPT_SEC_LEVEL, BT_IO_SEC_MEDIUM, BT_IO_OPT_MASTER, master, BT_IO_OPT_INVALID); if (!io) { error("%s", err->message); g_error_free(err); return -1; } adapter->hfp_hs_server = io; record = hfp_hs_record(chan); if (!record) { error("Unable to allocate new service record"); return -1; } if (add_record_to_server(&src, record) < 0) { error("Unable to register HFP HS service record"); sdp_record_free(record); g_io_channel_unref(adapter->hfp_hs_server); adapter->hfp_hs_server = NULL; return -1; } adapter->hfp_hs_record_id = record->handle; return 0; }
static DBusMessage *proxy_enable(DBusConnection *conn, DBusMessage *msg, void *data) { struct serial_proxy *prx = data; sdp_record_t *record; GError *err = NULL; DBusMessage *reply; if (prx->io) return failed(msg, "Already enabled"); /* Listen */ prx->io = bt_io_listen(BT_IO_RFCOMM, NULL, confirm_event_cb, prx, NULL, &err, BT_IO_OPT_SOURCE_BDADDR, &prx->src, BT_IO_OPT_INVALID); if (!prx->io) goto failed; bt_io_get(prx->io, BT_IO_RFCOMM, &err, BT_IO_OPT_CHANNEL, &prx->channel, BT_IO_OPT_INVALID); if (err) { g_io_channel_unref(prx->io); prx->io = NULL; goto failed; } debug("Allocated channel %d", prx->channel); g_io_channel_set_close_on_unref(prx->io, TRUE); record = proxy_record_new(prx->uuid128, prx->channel); if (!record) { g_io_channel_unref(prx->io); return failed(msg, "Unable to allocate new service record"); } if (add_record_to_server(&prx->src, record) < 0) { sdp_record_free(record); g_io_channel_unref(prx->io); return failed(msg, "Service registration failed"); } prx->record_id = record->handle; return dbus_message_new_method_return(msg); failed: error("%s", err->message); reply = failed(msg, err->message); g_error_free(err); return reply; }
static int enable_proxy(struct serial_proxy *prx) { sdp_record_t *record; GError *gerr = NULL; int err; if (prx->io) return -EALREADY; /* Listen */ prx->io = bt_io_listen(BT_IO_RFCOMM, NULL, confirm_event_cb, prx, NULL, &gerr, BT_IO_OPT_SOURCE_BDADDR, &prx->src, BT_IO_OPT_INVALID); if (!prx->io) goto failed; bt_io_get(prx->io, BT_IO_RFCOMM, &gerr, BT_IO_OPT_CHANNEL, &prx->channel, BT_IO_OPT_INVALID); if (gerr) { g_io_channel_unref(prx->io); prx->io = NULL; goto failed; } debug("Allocated channel %d", prx->channel); g_io_channel_set_close_on_unref(prx->io, TRUE); record = proxy_record_new(prx->uuid128, prx->channel); if (!record) { g_io_channel_unref(prx->io); return -ENOMEM; } err = add_record_to_server(&prx->src, record); if (err < 0) { sdp_record_free(record); g_io_channel_unref(prx->io); return err; } prx->record_id = record->handle; return 0; failed: error("%s", gerr->message); g_error_free(gerr); return -EIO; }
static uint32_t register_server_record(struct network_server *ns) { sdp_record_t *record; record = server_record_new(ns->name, ns->id); if (!record) { error("Unable to allocate new service record"); return 0; } if (add_record_to_server(&ns->src, record) < 0) { error("Failed to register service record"); sdp_record_free(record); return 0; } DBG("got record id 0x%x", record->handle); return record->handle; }
static int add_xml_record(DBusConnection *conn, const char *sender, struct service_adapter *serv_adapter, const char *record, dbus_uint32_t *handle) { struct record_data *user_record; sdp_record_t *sdp_record; bdaddr_t src; sdp_record = sdp_xml_parse_record(record, strlen(record)); if (!sdp_record) { error("Parsing of XML service record failed"); return -EIO; } if (serv_adapter->adapter) adapter_get_address(serv_adapter->adapter, &src); else bacpy(&src, BDADDR_ANY); if (add_record_to_server(&src, sdp_record) < 0) { error("Failed to register service record"); sdp_record_free(sdp_record); return -EIO; } user_record = g_new0(struct record_data, 1); user_record->handle = sdp_record->handle; user_record->sender = g_strdup(sender); user_record->serv_adapter = serv_adapter; user_record->listener_id = g_dbus_add_disconnect_watch(conn, sender, exit_callback, user_record, NULL); serv_adapter->records = g_slist_append(serv_adapter->records, user_record); DBG("listener_id %d", user_record->listener_id); *handle = user_record->handle; return 0; }
static DBusMessage *update_record(DBusMessage *msg, struct service_adapter *serv_adapter, dbus_uint32_t handle, sdp_record_t *sdp_record) { int err; if (remove_record_from_server(handle) < 0) { sdp_record_free(sdp_record); return btd_error_not_available(msg); } sdp_record->handle = handle; err = add_record_to_server(get_address(serv_adapter), sdp_record); if (err < 0) { sdp_record_free(sdp_record); error("Failed to update the service record"); return btd_error_failed(msg, strerror(-err)); } return dbus_message_new_method_return(msg); }
static uint16_t ext_register_record(struct ext_profile *ext, const bdaddr_t *src) { sdp_record_t *rec; if (ext->record) rec = sdp_xml_parse_record(ext->record, strlen(ext->record)); else rec = ext_get_record(ext); if (!rec) return 0; if (add_record_to_server(src, rec) < 0) { error("Failed to register service record"); sdp_record_free(rec); return 0; } return rec->handle; }
int avrcp_init(DBusConnection *conn, GKeyFile *config) { sdp_record_t *record; gboolean tmp, master = TRUE; GError *err = NULL; if (avctp_server) return 0; if (config) { tmp = g_key_file_get_boolean(config, "General", "Master", &err); if (err) { debug("audio.conf: %s", err->message); g_error_free(err); err = NULL; } else master = tmp; input_device_name = g_key_file_get_string(config, "AVRCP", "InputDeviceName", &err); if (err) { debug("InputDeviceName not specified in audio.conf"); input_device_name = NULL; g_error_free(err); } } connection = dbus_connection_ref(conn); record = avrcp_tg_record(); if (!record) { error("Unable to allocate new service record"); return -1; } if (add_record_to_server(BDADDR_ANY, record) < 0) { error("Unable to register AVRCP target service record"); sdp_record_free(record); return -1; } tg_record_id = record->handle; #ifndef ANDROID record = avrcp_ct_record(); if (!record) { error("Unable to allocate new service record"); return -1; } if (add_record_to_server(BDADDR_ANY, record) < 0) { error("Unable to register AVRCP controller service record"); sdp_record_free(record); return -1; } ct_record_id = record->handle; #endif avctp_server = avctp_server_socket(master); if (!avctp_server) return -1; return 0; }
static int headset_server_init(struct audio_adapter *adapter) { uint8_t chan = DEFAULT_HS_AG_CHANNEL; sdp_record_t *record; gboolean master = TRUE; GError *err = NULL; uint32_t features; GIOChannel *io; bdaddr_t src; if (config) { gboolean tmp; tmp = g_key_file_get_boolean(config, "General", "Master", &err); if (err) { DBG("audio.conf: %s", err->message); g_clear_error(&err); } else master = tmp; } adapter_get_address(adapter->btd_adapter, &src); io = bt_io_listen(BT_IO_RFCOMM, NULL, ag_confirm, adapter, NULL, &err, BT_IO_OPT_SOURCE_BDADDR, &src, BT_IO_OPT_CHANNEL, chan, BT_IO_OPT_SEC_LEVEL, BT_IO_SEC_MEDIUM, BT_IO_OPT_MASTER, master, BT_IO_OPT_INVALID); if (!io) goto failed; adapter->hsp_ag_server = io; record = hsp_ag_record(chan); if (!record) { error("Unable to allocate new service record"); goto failed; } if (add_record_to_server(&src, record) < 0) { error("Unable to register HS AG service record"); sdp_record_free(record); goto failed; } adapter->hsp_ag_record_id = record->handle; features = headset_config_init(config); if (!enabled.hfp) return 0; chan = DEFAULT_HF_AG_CHANNEL; io = bt_io_listen(BT_IO_RFCOMM, NULL, ag_confirm, adapter, NULL, &err, BT_IO_OPT_SOURCE_BDADDR, &src, BT_IO_OPT_CHANNEL, chan, BT_IO_OPT_SEC_LEVEL, BT_IO_SEC_MEDIUM, BT_IO_OPT_MASTER, master, BT_IO_OPT_INVALID); if (!io) goto failed; adapter->hfp_ag_server = io; record = hfp_ag_record(chan, features); if (!record) { error("Unable to allocate new service record"); goto failed; } if (add_record_to_server(&src, record) < 0) { error("Unable to register HF AG service record"); sdp_record_free(record); goto failed; } adapter->hfp_ag_record_id = record->handle; return 0; failed: if (err) { error("%s", err->message); g_error_free(err); } if (adapter->hsp_ag_server) { g_io_channel_shutdown(adapter->hsp_ag_server, TRUE, NULL); g_io_channel_unref(adapter->hsp_ag_server); adapter->hsp_ag_server = NULL; } if (adapter->hfp_ag_server) { g_io_channel_shutdown(adapter->hfp_ag_server, TRUE, NULL); g_io_channel_unref(adapter->hfp_ag_server); adapter->hfp_ag_server = NULL; } return -1; }
int sap_server_register(const char *path, bdaddr_t *src) { sdp_record_t *record = NULL; GError *gerr = NULL; GIOChannel *io; if (sap_init() < 0) { error("Sap driver initialization failed."); return -1; } server = g_try_new0(struct sap_server, 1); if (!server) { sap_exit(); return -ENOMEM; } server->path = g_strdup(path); record = create_sap_record(SAP_SERVER_CHANNEL); if (!record) { error("Creating SAP SDP record failed."); goto sdp_err; } if (add_record_to_server(src, record) < 0) { error("Adding SAP SDP record to the SDP server failed."); sdp_record_free(record); goto sdp_err; } server->record_id = record->handle; io = bt_io_listen(BT_IO_RFCOMM, NULL, connect_confirm_cb, server, NULL, &gerr, BT_IO_OPT_SOURCE_BDADDR, src, BT_IO_OPT_CHANNEL, SAP_SERVER_CHANNEL, BT_IO_OPT_SEC_LEVEL, BT_IO_SEC_HIGH, BT_IO_OPT_MASTER, TRUE, BT_IO_OPT_INVALID); if (!io) { error("Can't listen at channel %d.", SAP_SERVER_CHANNEL); g_error_free(gerr); goto server_err; } DBG("Listen socket 0x%02x", g_io_channel_unix_get_fd(io)); server->listen_io = io; server->conn = NULL; if (!g_dbus_register_interface(connection, path, SAP_SERVER_INTERFACE, server_methods, server_signals, NULL, server, destroy_sap_interface)) { error("D-Bus failed to register %s interface", SAP_SERVER_INTERFACE); goto server_err; } return 0; server_err: remove_record_from_server(server->record_id); sdp_err: server_free(server); sap_exit(); return -1; }
gboolean mcap_update_sdp_record(struct mcap_adapter *adapter, GSList *app_list) { DBG(""); DBG("1"); sdp_record_t *sdp_record; bdaddr_t addr; if (adapter->sdp_handler) remove_record_from_server(adapter->sdp_handler); if (!app_list) { adapter->sdp_handler = 0; return TRUE; } DBG("3"); sdp_record = sdp_record_alloc(); if (!sdp_record) return FALSE; if (adapter->sdp_handler) sdp_record->handle = adapter->sdp_handler; else sdp_record->handle = 0xffffffff; DBG("4"); if (is_app_role(app_list, MCAP_SINK)) set_sdp_services_uuid(sdp_record, MCAP_SINK); if (is_app_role(app_list, MCAP_SOURCE)) set_sdp_services_uuid(sdp_record, MCAP_SOURCE); DBG("52"); if (!register_service_protocols(adapter, sdp_record)) DBG("eq"); if (!register_service_profiles(sdp_record)) DBG("e2"); if (!register_service_additional_protocols(adapter, sdp_record)) DBG("e3"); DBG("5"); sdp_set_info_attr(sdp_record, MCAP_SERVICE_NAME, MCAP_SERVICE_PROVIDER, MCAP_SERVICE_DSC); if (!register_service_sup_features(app_list, sdp_record)) DBG("e4"); if (!register_data_exchange_spec(sdp_record)) DBG("45"); DBG("6"); register_mcap_features(sdp_record); if (sdp_set_record_state(sdp_record, adapter->record_state++)) DBG("5"); adapter_get_address(adapter->btd_adapter, &addr); DBG("8"); if (add_record_to_server(&addr, sdp_record) < 0) DBG("5"); DBG("7"); adapter->sdp_handler = sdp_record->handle; return TRUE; fail: if (sdp_record) sdp_record_free(sdp_record); return TRUE; }
int avrcp_register(DBusConnection *conn, const bdaddr_t *src, GKeyFile *config) { sdp_record_t *record; gboolean tmp, master = TRUE; GError *err = NULL; struct avctp_server *server; if (config) { tmp = g_key_file_get_boolean(config, "General", "Master", &err); if (err) { DBG("audio.conf: %s", err->message); g_error_free(err); } else master = tmp; err = NULL; input_device_name = g_key_file_get_string(config, "AVRCP", "InputDeviceName", &err); if (err) { DBG("audio.conf: %s", err->message); input_device_name = NULL; g_error_free(err); } } server = g_new0(struct avctp_server, 1); if (!server) return -ENOMEM; if (!connection) connection = dbus_connection_ref(conn); record = avrcp_tg_record(); if (!record) { error("Unable to allocate new service record"); g_free(server); return -1; } if (add_record_to_server(src, record) < 0) { error("Unable to register AVRCP target service record"); g_free(server); sdp_record_free(record); return -1; } server->tg_record_id = record->handle; #ifndef ANDROID record = avrcp_ct_record(); if (!record) { error("Unable to allocate new service record"); g_free(server); return -1; } if (add_record_to_server(src, record) < 0) { error("Unable to register AVRCP controller service record"); sdp_record_free(record); g_free(server); return -1; } server->ct_record_id = record->handle; #endif server->io = avctp_server_socket(src, master); if (!server->io) { #ifndef ANDROID remove_record_from_server(server->ct_record_id); #endif remove_record_from_server(server->tg_record_id); g_free(server); return -1; } bacpy(&server->src, src); servers = g_slist_append(servers, server); return 0; }