void manager_set_default_adapter(int id) { struct btd_adapter *adapter; const gchar *path; default_adapter_id = id; adapter = manager_find_adapter_by_id(id); if (!adapter) return; path = adapter_get_path(adapter); g_dbus_emit_signal(connection, "/", MANAGER_INTERFACE, "DefaultAdapterChanged", DBUS_TYPE_OBJECT_PATH, &path, DBUS_TYPE_INVALID); }
int server_unregister(struct btd_adapter *adapter) { struct network_adapter *na; struct network_server *ns; uint16_t id = BNEP_SVC_NAP; na = find_adapter(adapters, adapter); if (!na) return -EINVAL; ns = find_server(na->servers, id); if (!ns) return -EINVAL; g_dbus_unregister_interface(connection, adapter_get_path(adapter), ns->iface); return 0; }
static void state_changed(struct btd_adapter *adapter, gboolean powered) { struct audio_adapter *adp; static gboolean telephony = FALSE; GSList *l; DBG("%s powered %s", adapter_get_path(adapter), powered ? "on" : "off"); /* ignore powered change, adapter is powering down */ if (powered && adapter_powering_down(adapter)) return; adp = find_adapter(adapters, adapter); if (!adp) return; adp->powered = powered; if (powered) { /* telephony driver already initialized*/ if (telephony == TRUE) return; telephony_init(); telephony = TRUE; return; } /* telephony not initialized just ignore power down */ if (telephony == FALSE) return; for (l = adapters; l; l = l->next) { adp = l->data; if (adp->powered == TRUE) return; } telephony_exit(); telephony = FALSE; }
static void manager_update_adapters(void) { GSList *list; char **array; int i; array = g_new0(char *, g_slist_length(adapters) + 1); for (i = 0, list = adapters; list; list = list->next) { struct btd_adapter *adapter = list->data; array[i] = (char *) adapter_get_path(adapter); i++; } emit_array_property_changed(connection, "/", MANAGER_INTERFACE, "Adapters", DBUS_TYPE_OBJECT_PATH, &array, i); g_free(array); }
static DBusMessage *find_adapter(DBusConnection *conn, DBusMessage *msg, void *data) { DBusMessage *reply; struct btd_adapter *adapter; const char *pattern; int dev_id; const gchar *path; if (!dbus_message_get_args(msg, NULL, DBUS_TYPE_STRING, &pattern, DBUS_TYPE_INVALID)) return NULL; /* hci_devid() would make sense to use here, except it is restricted to devices which are up */ if (!strcmp(pattern, "any") || !strcmp(pattern, "00:00:00:00:00:00")) { path = adapter_any_get_path(); if (path != NULL) goto done; return no_such_adapter(msg); } else if (!strncmp(pattern, "hci", 3) && strlen(pattern) >= 4) { dev_id = atoi(pattern + 3); adapter = manager_find_adapter_by_id(dev_id); } else adapter = manager_find_adapter_by_address(pattern); if (!adapter) return no_such_adapter(msg); path = adapter_get_path(adapter); done: reply = dbus_message_new_method_return(msg); if (!reply) return NULL; dbus_message_append_args(reply, DBUS_TYPE_OBJECT_PATH, &path, DBUS_TYPE_INVALID); return reply; }
static int register_proxy(struct serial_adapter *adapter, const char *uuid_str, const char *address, struct serial_proxy **proxy) { proxy_type_t type; int err; type = addr2type(address); if (type == UNKNOWN_PROXY_TYPE) return -EINVAL; /* Only one proxy per address(TTY or unix socket) is allowed */ if (g_slist_find_custom(adapter->proxies, address, proxy_addrcmp)) return -EALREADY; switch (type) { case UNIX_SOCKET_PROXY: err = proxy_socket_register(adapter, uuid_str, address, proxy); break; case TTY_PROXY: err = proxy_tty_register(adapter, uuid_str, address, NULL, proxy); break; case TCP_SOCKET_PROXY: err = proxy_tcp_register(adapter, uuid_str, address, proxy); break; default: err = -EINVAL; } if (err < 0) return err; g_dbus_emit_signal(adapter->conn, adapter_get_path(adapter->btd_adapter), SERIAL_MANAGER_INTERFACE, "ProxyCreated", DBUS_TYPE_STRING, &(*proxy)->path, DBUS_TYPE_INVALID); return 0; }
static void unregister_proxy(struct serial_proxy *proxy) { struct serial_adapter *adapter = proxy->adapter; char *path = g_strdup(proxy->path); if (proxy->watch > 0) g_dbus_remove_watch(adapter->conn, proxy->watch); g_dbus_emit_signal(adapter->conn, adapter_get_path(adapter->btd_adapter), SERIAL_MANAGER_INTERFACE, "ProxyRemoved", DBUS_TYPE_STRING, &path, DBUS_TYPE_INVALID); adapter->proxies = g_slist_remove(adapter->proxies, proxy); g_dbus_unregister_interface(adapter->conn, path, SERIAL_PROXY_INTERFACE); g_free(path); }
static int a2dp_server_probe(struct btd_adapter *adapter) { struct audio_adapter *adp; const gchar *path = adapter_get_path(adapter); bdaddr_t src; int err; DBG("path %s", path); adp = audio_adapter_get(adapter); if (!adp) return -EINVAL; adapter_get_address(adapter, &src); err = a2dp_register(connection, &src, config); if (err < 0) audio_adapter_unref(adp); return err; }
struct btd_adapter *btd_manager_register_adapter(int id) { struct btd_adapter *adapter; const char *path; adapter = manager_find_adapter_by_id(id); if (adapter) { error("Unable to register adapter: hci%d already exist", id); return NULL; } adapter = adapter_create(connection, id); if (!adapter) return NULL; adapters = g_slist_append(adapters, adapter); if (!adapter_init(adapter)) { adapters = g_slist_remove(adapters, adapter); btd_adapter_unref(adapter); return NULL; } path = adapter_get_path(adapter); g_dbus_emit_signal(connection, "/", MANAGER_INTERFACE, "AdapterAdded", DBUS_TYPE_OBJECT_PATH, &path, DBUS_TYPE_INVALID); manager_update_adapters(); btd_stop_exit_timer(); if (default_adapter_id < 0) manager_set_default_adapter(id); DBG("Adapter %s registered", path); return btd_adapter_ref(adapter); }
static void bnep_watchdog_cb(GIOChannel *chan, GIOCondition cond, gpointer data) { struct network_server *ns = data; struct network_session *session; char address[18]; const char *paddr = address; session = find_session(ns->sessions, chan); if (!connection || !session) return; ba2str(&session->dst, address); g_dbus_emit_signal(connection, adapter_get_path(ns->na->adapter), ns->iface, "DeviceDisconnected", DBUS_TYPE_STRING, &paddr, DBUS_TYPE_INVALID); g_io_channel_shutdown(chan, TRUE, NULL); g_io_channel_unref(session->io); session->io = NULL; session_free(session); }
static void link_loss_emit_alert_signal(struct connected_device *condev) { bdaddr_t addr; char addr_str[18]; char *addr_str_ptr = addr_str; struct link_loss_adapter *adapter = condev->adapter; if (!condev->device) return; device_get_address(condev->device, &addr, NULL); ba2str(&addr, addr_str); DBG("emit signal alert %d remote %s", condev->alert_level, addr_str); g_dbus_emit_signal(adapter->conn, adapter_get_path(adapter->adapter), PROXIMITY_REPORTER_INTERFACE, "LinkLossAlertLevel", DBUS_TYPE_BYTE, &condev->alert_level, DBUS_TYPE_STRING, &addr_str_ptr, DBUS_TYPE_INVALID); }
static DBusMessage *default_adapter(DBusConnection *conn, DBusMessage *msg, void *data) { DBusMessage *reply; struct btd_adapter *adapter; const gchar *path; adapter = manager_find_adapter_by_id(default_adapter_id); if (!adapter) return btd_error_no_such_adapter(msg); reply = dbus_message_new_method_return(msg); if (!reply) return NULL; path = adapter_get_path(adapter); dbus_message_append_args(reply, DBUS_TYPE_OBJECT_PATH, &path, DBUS_TYPE_INVALID); return reply; }
static int register_proxy_object(struct serial_proxy *prx) { struct serial_adapter *adapter = prx->adapter; char path[MAX_PATH_LENGTH + 1]; snprintf(path, MAX_PATH_LENGTH, "%s/proxy%d", adapter_get_path(adapter->btd_adapter), sk_counter++); if (!g_dbus_register_interface(adapter->conn, path, SERIAL_PROXY_INTERFACE, proxy_methods, NULL, NULL, prx, proxy_path_unregister)) { error("D-Bus failed to register %s path", path); return -1; } prx->path = g_strdup(path); adapter->proxies = g_slist_append(adapter->proxies, prx); debug("Registered proxy: %s", path); return 0; }
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, adapter); if (!adp) return; if (adp->hfp_hs_record_id) { remove_record_from_server(adp->hfp_hs_record_id); adp->hfp_hs_record_id = 0; } if (adp->hfp_hs_server) { g_io_channel_unref(adp->hfp_hs_server); adp->hfp_hs_server = NULL; } audio_adapter_unref(adp); }
static int headset_server_probe(struct btd_adapter *adapter) { struct audio_adapter *adp; const gchar *path = adapter_get_path(adapter); int err; DBG("path %s", path); adp = audio_adapter_get(adapter); if (!adp) return -EINVAL; err = headset_server_init(adp); if (err < 0) { audio_adapter_unref(adp); return err; } btd_adapter_register_powered_callback(adapter, state_changed); state_changed(adapter, TRUE); return 0; }
int heartrate_adapter_register(struct btd_adapter *adapter) { struct heartrate_adapter *hradapter; hradapter = g_new0(struct heartrate_adapter, 1); hradapter->adapter = adapter; heartrate_adapters = g_slist_prepend(heartrate_adapters, hradapter); if (!g_dbus_register_interface(btd_get_dbus_connection(), adapter_get_path(adapter), HEART_RATE_MANAGER_INTERFACE, heartrate_manager_methods, NULL, NULL, hradapter, destroy_heartrate_adapter)) { error("D-Bus failed to register %s interface", HEART_RATE_MANAGER_INTERFACE); destroy_heartrate_adapter(hradapter); return -EIO; } return 0; }
static int csc_adapter_probe(struct btd_profile *p, struct btd_adapter *adapter) { struct csc_adapter *cadapter; cadapter = g_new0(struct csc_adapter, 1); cadapter->adapter = adapter; if (!g_dbus_register_interface(btd_get_dbus_connection(), adapter_get_path(adapter), CYCLINGSPEED_MANAGER_INTERFACE, cyclingspeed_manager_methods, NULL, NULL, cadapter, destroy_csc_adapter)) { error("D-Bus failed to register %s interface", CYCLINGSPEED_MANAGER_INTERFACE); destroy_csc_adapter(cadapter); return -EIO; } csc_adapters = g_slist_prepend(csc_adapters, cadapter); return 0; }
static DBusMessage *get_properties(DBusConnection *conn, DBusMessage *msg, void *data) { DBusMessage *reply; DBusMessageIter iter; DBusMessageIter dict; GSList *list; char **array; int i; reply = dbus_message_new_method_return(msg); if (!reply) return NULL; dbus_message_iter_init_append(reply, &iter); dbus_message_iter_open_container(&iter, DBUS_TYPE_ARRAY, DBUS_DICT_ENTRY_BEGIN_CHAR_AS_STRING DBUS_TYPE_STRING_AS_STRING DBUS_TYPE_VARIANT_AS_STRING DBUS_DICT_ENTRY_END_CHAR_AS_STRING, &dict); array = g_new0(char *, g_slist_length(adapters) + 1); for (i = 0, list = adapters; list; list = list->next, i++) { struct btd_adapter *adapter = list->data; if (!adapter_is_ready(adapter)) continue; array[i] = (char *) adapter_get_path(adapter); } dict_append_array(&dict, "Adapters", DBUS_TYPE_OBJECT_PATH, &array, i); g_free(array); dbus_message_iter_close_container(&iter, &dict); return reply; }
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, adapter); 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_shutdown(adp->hsp_ag_server, TRUE, NULL); 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_shutdown(adp->hfp_ag_server, TRUE, NULL); g_io_channel_unref(adp->hfp_ag_server); adp->hfp_ag_server = NULL; } btd_adapter_unregister_powered_callback(adapter, state_changed); audio_adapter_unref(adp); }
static int sap_server_probe(struct btd_profile *p, struct btd_adapter *adapter) { DBG("path %s", adapter_get_path(adapter)); return sap_server_register(adapter); }
static int media_server_probe(struct btd_adapter *adapter) { DBG("path %s", adapter_get_path(adapter)); return media_register(adapter); }
static void media_server_remove(struct btd_adapter *adapter) { DBG("path %s", adapter_get_path(adapter)); media_unregister(adapter); }
static void service_remove(struct btd_adapter *adapter) { unregister_interface(adapter_get_path(adapter)); }
static int service_probe(struct btd_adapter *adapter) { register_interface(adapter_get_path(adapter), adapter); return 0; }
void time_server_exit(struct btd_adapter *adapter) { const char *path = adapter_get_path(adapter); DBG("path %s", path); }
static DBusMessage *create_proxy(DBusConnection *conn, DBusMessage *msg, void *data) { struct serial_adapter *adapter = data; char path[MAX_PATH_LENGTH + 1]; const char *pattern, *address, *ppath = path; char *uuid_str; proxy_type_t type; uuid_t uuid; int ret; if (!dbus_message_get_args(msg, NULL, DBUS_TYPE_STRING, &pattern, DBUS_TYPE_STRING, &address, DBUS_TYPE_INVALID)) return NULL; uuid_str = bt_name2string(pattern); if (!uuid_str) return invalid_arguments(msg, "Invalid UUID"); bt_string2uuid(&uuid, uuid_str); type = addr2type(address); if (type == UNKNOWN_PROXY_TYPE) { g_free(uuid_str); return invalid_arguments(msg, "Invalid address"); } /* Only one proxy per address(TTY or unix socket) is allowed */ if (g_slist_find_custom(adapter->proxies, address, proxy_addrcmp)) { g_free(uuid_str); return g_dbus_create_error(msg, ERROR_INTERFACE ".AlreadyExist", "Proxy already exists"); } switch (type) { case UNIX_SOCKET_PROXY: ret = proxy_socket_register(adapter, uuid_str, address, path, sizeof(path), TRUE); break; case TTY_PROXY: ret = proxy_tty_register(adapter, uuid_str, address, NULL, path, sizeof(path), TRUE); break; case TCP_SOCKET_PROXY: ret = proxy_tcp_register(adapter, uuid_str, address, path, sizeof(path), TRUE); break; default: ret = -1; } g_free(uuid_str); if (ret < 0) return failed(msg, "Create object path failed"); g_dbus_emit_signal(adapter->conn, adapter_get_path(adapter->btd_adapter), SERIAL_MANAGER_INTERFACE, "ProxyCreated", DBUS_TYPE_STRING, &ppath, DBUS_TYPE_INVALID); return g_dbus_create_reply(msg, DBUS_TYPE_STRING, &ppath, DBUS_TYPE_INVALID); }
int sap_server_register(struct btd_adapter *adapter) { sdp_record_t *record = NULL; GError *gerr = NULL; GIOChannel *io; struct sap_server *server; if (sap_init() < 0) { error("Sap driver initialization failed."); return -1; } record = create_sap_record(SAP_SERVER_CHANNEL); if (!record) { error("Creating SAP SDP record failed."); goto sdp_err; } if (adapter_service_add(adapter, record) < 0) { error("Adding SAP SDP record to the SDP server failed."); sdp_record_free(record); goto sdp_err; } server = g_new0(struct sap_server, 1); server->adapter = btd_adapter_ref(adapter); server->record_id = record->handle; io = bt_io_listen(NULL, connect_confirm_cb, server, NULL, &gerr, BT_IO_OPT_SOURCE_BDADDR, btd_adapter_get_address(adapter), 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; } server->listen_io = io; if (!g_dbus_register_interface(btd_get_dbus_connection(), adapter_get_path(server->adapter), SAP_SERVER_INTERFACE, server_methods, NULL, server_properties, server, destroy_sap_interface)) { error("D-Bus failed to register %s interface", SAP_SERVER_INTERFACE); goto server_err; } DBG("server %p, listen socket 0x%02x", server, g_io_channel_unix_get_fd(io)); return 0; server_err: server_remove(server); sdp_err: sap_exit(); return -1; }