📄 manager.c
字号:
if (!adapter->hfp_ag_server) goto failed; record = hfp_ag_record(chan, features); if (!record) { error("Unable to allocate new service record"); goto failed; } if (add_record_to_server(&adapter->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 (adapter->hsp_ag_server) { g_io_channel_unref(adapter->hsp_ag_server); adapter->hsp_ag_server = NULL; } if (adapter->hfp_ag_server) { g_io_channel_unref(adapter->hfp_ag_server); adapter->hfp_ag_server = NULL; } return -1;}static int gateway_server_init(struct audio_adapter *adapter){ uint8_t chan = DEFAULT_HSP_HS_CHANNEL; sdp_record_t *record; gboolean master = TRUE; GError *err = NULL; uint32_t flags; if (config) { gboolean tmp; tmp = g_key_file_get_boolean(config, "General", "Master", &err); if (err) { debug("audio.conf: %s", err->message); g_clear_error(&err); } else master = tmp; } flags = RFCOMM_LM_AUTH | RFCOMM_LM_ENCRYPT; if (master) flags |= RFCOMM_LM_MASTER; adapter->hsp_hs_server = bt_rfcomm_listen(&adapter->src, chan, flags, hs_io_cb, adapter); if (!adapter->hsp_hs_server) return -1; record = hsp_hs_record(chan); if (!record) { error("Unable to allocate new service record"); return -1; } if (add_record_to_server(&adapter->src, record) < 0) { error("Unable to register HSP HS service record"); sdp_record_free(record); g_io_channel_unref(adapter->hsp_hs_server); adapter->hsp_hs_server = NULL; return -1; } adapter->hsp_hs_record_id = record->handle; return 0;}static int audio_probe(struct btd_device *device, GSList *uuids){ struct btd_adapter *adapter = device_get_adapter(device); bdaddr_t src, dst; struct audio_device *audio_dev; adapter_get_address(adapter, &src); device_get_address(device, &dst); audio_dev = manager_get_device(&src, &dst); if (!audio_dev) { debug("audio_probe: unable to get a device object"); return -1; } g_slist_foreach(uuids, (GFunc) handle_uuid, audio_dev); return 0;}static void audio_remove(struct btd_device *device){ struct audio_device *dev; bdaddr_t bdaddr; device_get_address(device, &bdaddr); dev = manager_find_device(&bdaddr, NULL, FALSE); if (!dev) return; devices = g_slist_remove(devices, dev); device_unregister(dev);}static struct audio_adapter *create_audio_adapter(const char *path, bdaddr_t *src){ struct audio_adapter *adp; adp = g_new0(struct audio_adapter, 1); adp->path = g_strdup(path); bacpy(&adp->src, src); return adp;}static struct audio_adapter *get_audio_adapter(struct btd_adapter *adapter){ struct audio_adapter *adp; const gchar *path = adapter_get_path(adapter); bdaddr_t src; adapter_get_address(adapter, &src); adp = find_adapter(adapters, path); if (!adp) { adp = create_audio_adapter(path, &src); if (!adp) return NULL; adapters = g_slist_append(adapters, adp); } return adp;}static int headset_server_probe(struct btd_adapter *adapter){ struct audio_adapter *adp; const gchar *path = adapter_get_path(adapter); DBG("path %s", path); adp = get_audio_adapter(adapter); if (!adp) return -EINVAL; return headset_server_init(adp);}static void headset_server_remove(struct btd_adapter *adapter){ struct audio_adapter *adp; const gchar *path = adapter_get_path(adapter); DBG("path %s", path); adp = find_adapter(adapters, path); if (!adp) return; if (adp->hsp_ag_record_id) { remove_record_from_server(adp->hsp_ag_record_id); adp->hsp_ag_record_id = 0; } if (adp->hsp_ag_server) { g_io_channel_unref(adp->hsp_ag_server); adp->hsp_ag_server = NULL; } if (adp->hfp_ag_record_id) { remove_record_from_server(adp->hfp_ag_record_id); adp->hfp_ag_record_id = 0; } if (adp->hfp_ag_server) { g_io_channel_unref(adp->hfp_ag_server); adp->hfp_ag_server = NULL; }}static int gateway_server_probe(struct btd_adapter *adapter){ struct audio_adapter *adp; const gchar *path = adapter_get_path(adapter); DBG("path %s", path); adp = get_audio_adapter(adapter); if (!adp) return -EINVAL; return gateway_server_init(adp);}static void gateway_server_remove(struct btd_adapter *adapter){ struct audio_adapter *adp; const gchar *path = adapter_get_path(adapter); DBG("path %s", path); adp = find_adapter(adapters, path); if (!adp) return; if (adp->hsp_hs_record_id) { remove_record_from_server(adp->hsp_hs_record_id); adp->hsp_hs_record_id = 0; } if (adp->hsp_hs_server) { g_io_channel_unref(adp->hsp_hs_server); adp->hsp_hs_server = NULL; }}static int a2dp_server_probe(struct btd_adapter *adapter){ struct audio_adapter *adp; const gchar *path = adapter_get_path(adapter); DBG("path %s", path); adp = get_audio_adapter(adapter); if (!adp) return -EINVAL; return a2dp_register(connection, &adp->src, config);}static void a2dp_server_remove(struct btd_adapter *adapter){ struct audio_adapter *adp; const gchar *path = adapter_get_path(adapter); DBG("path %s", path); adp = find_adapter(adapters, path); if (!adp) return; return a2dp_unregister(&adp->src);}static int avrcp_server_probe(struct btd_adapter *adapter){ struct audio_adapter *adp; const gchar *path = adapter_get_path(adapter); DBG("path %s", path); adp = get_audio_adapter(adapter); if (!adp) return -EINVAL; return avrcp_register(connection, &adp->src, config);}static void avrcp_server_remove(struct btd_adapter *adapter){ struct audio_adapter *adp; const gchar *path = adapter_get_path(adapter); DBG("path %s", path); adp = find_adapter(adapters, path); if (!adp) return; return avrcp_unregister(&adp->src);}static struct btd_device_driver audio_driver = { .name = "audio", .uuids = BTD_UUIDS(HSP_HS_UUID, HFP_HS_UUID, HSP_AG_UUID, HFP_AG_UUID, ADVANCED_AUDIO_UUID, A2DP_SOURCE_UUID, A2DP_SINK_UUID, AVRCP_TARGET_UUID, AVRCP_REMOTE_UUID), .probe = audio_probe, .remove = audio_remove,};static struct btd_adapter_driver headset_server_driver = { .name = "audio-headset", .probe = headset_server_probe, .remove = headset_server_remove,};static struct btd_adapter_driver gateway_server_driver = { .name = "audio-gateway", .probe = gateway_server_probe, .remove = gateway_server_remove,};static struct btd_adapter_driver a2dp_server_driver = { .name = "audio-a2dp", .probe = a2dp_server_probe, .remove = a2dp_server_remove,};static struct btd_adapter_driver avrcp_server_driver = { .name = "audio-control", .probe = avrcp_server_probe, .remove = avrcp_server_remove,};int audio_manager_init(DBusConnection *conn, GKeyFile *conf){ char **list; int i; gboolean b; GError *err; connection = dbus_connection_ref(conn); if (!conf) goto proceed; config = conf; list = g_key_file_get_string_list(config, "General", "Enable", NULL, NULL); for (i = 0; list && list[i] != NULL; i++) { if (g_str_equal(list[i], "Headset")) enabled.headset = TRUE; else if (g_str_equal(list[i], "Gateway")) enabled.gateway = TRUE; else if (g_str_equal(list[i], "Sink")) enabled.sink = TRUE; else if (g_str_equal(list[i], "Source")) enabled.source = TRUE; else if (g_str_equal(list[i], "Control")) enabled.control = TRUE; } g_strfreev(list); list = g_key_file_get_string_list(config, "General", "Disable", NULL, NULL); for (i = 0; list && list[i] != NULL; i++) { if (g_str_equal(list[i], "Headset")) enabled.headset = FALSE; else if (g_str_equal(list[i], "Gateway")) enabled.gateway = FALSE; else if (g_str_equal(list[i], "Sink")) enabled.sink = FALSE; else if (g_str_equal(list[i], "Source")) enabled.source = FALSE; else if (g_str_equal(list[i], "Control")) enabled.control = FALSE; } g_strfreev(list); err = NULL; b = g_key_file_get_boolean(config, "Headset", "HFP", &err); if (err) { debug("audio.conf: %s", err->message); g_clear_error(&err); } else enabled.hfp = b; err = NULL; i = g_key_file_get_integer(config, "Headset", "MaxConnected", &err); if (err) { debug("audio.conf: %s", err->message); g_clear_error(&err); } else max_connected_headsets = i;proceed: if (enabled.headset) { telephony_init(); btd_register_adapter_driver(&headset_server_driver); } if (enabled.gateway) btd_register_adapter_driver(&gateway_server_driver); if (enabled.source || enabled.sink) btd_register_adapter_driver(&a2dp_server_driver); if (enabled.control) btd_register_adapter_driver(&avrcp_server_driver); btd_register_device_driver(&audio_driver); return 0;}void audio_manager_exit(void){ dbus_connection_unref(connection); if (config) g_key_file_free(config); if (enabled.headset) { btd_unregister_adapter_driver(&headset_server_driver); telephony_exit(); } if (enabled.gateway) btd_unregister_adapter_driver(&gateway_server_driver); if (enabled.source || enabled.sink) btd_unregister_adapter_driver(&a2dp_server_driver); if (enabled.control) btd_unregister_adapter_driver(&avrcp_server_driver); btd_unregister_device_driver(&audio_driver); connection = NULL;}struct audio_device *manager_get_connected_device(void){ GSList *l; for (l = devices; l != NULL; l = g_slist_next(l)) { struct audio_device *device = l->data; if ((device->sink || device->source) && avdtp_is_connected(&device->src, &device->dst)) return device; if (device->headset && headset_is_active(device)) return device; } return NULL;}struct audio_device *manager_find_device(const bdaddr_t *bda, const char *interface, gboolean connected){ GSList *l; for (l = devices; l != NULL; l = l->next) { struct audio_device *dev = l->data; if (bacmp(bda, BDADDR_ANY) && bacmp(&dev->dst, bda)) continue; if (interface && !strcmp(AUDIO_HEADSET_INTERFACE, interface) && !dev->headset) continue; if (interface && !strcmp(AUDIO_SINK_INTERFACE, interface) && !dev->sink) continue; if (interface && !strcmp(AUDIO_SOURCE_INTERFACE, interface) && !dev->source) continue; if (interface && !strcmp(AUDIO_CONTROL_INTERFACE, interface) && !dev->control) continue; if (connected && !device_is_connected(dev, interface)) continue; return dev; } return NULL;}struct audio_device *manager_get_device(const bdaddr_t *src, const bdaddr_t *dst){ struct audio_device *dev; struct btd_adapter *adapter; struct btd_device *device; char addr[18]; const char *path; dev = manager_find_device(dst, NULL, FALSE); if (dev) return dev; ba2str(src, addr); adapter = manager_find_adapter(src); if (!adapter) { error("Unable to get a btd_adapter object for %s", addr); return NULL; } ba2str(dst, addr); device = adapter_get_device(connection, adapter, addr); if (!device) { error("Unable to get btd_device object for %s", addr); return NULL; } path = device_get_path(device); dev = device_register(connection, path, src, dst); if (!dev) return NULL; dev->btd_dev = device; devices = g_slist_append(devices, dev); return dev;}gboolean manager_allow_headset_connection(bdaddr_t *src){ GSList *l; int connected = 0; for (l = devices; l != NULL; l = l->next) { struct audio_device *dev = l->data; struct headset *hs = dev->headset; if (bacmp(&dev->src, src)) continue; if (!hs) continue; if (headset_get_state(dev) > HEADSET_STATE_DISCONNECTED) connected++; if (connected >= max_connected_headsets) return FALSE; } return TRUE;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -