📄 adapter.c
字号:
rq.rlen = sizeof(status); rq.event = EVT_CMD_COMPLETE; if (hci_send_req(dd, &rq, HCI_REQ_TIMEOUT) < 0) { err = -errno; error("Unable to start periodic inquiry: %s (%d)", strerror(err), err); hci_close_dev(dd); return err; } if (status) { error("HCI_Periodic_Inquiry_Mode failed with status 0x%02x", status); hci_close_dev(dd); return -bt_error(status); } hci_close_dev(dd); adapter->state |= RESOLVE_NAME; return 0;}static DBusMessage *adapter_start_discovery(DBusConnection *conn, DBusMessage *msg, void *data){ struct session_req *req; struct btd_adapter *adapter = data; const char *sender = dbus_message_get_sender(msg); int err; if (!adapter->up) return adapter_not_ready(msg); req = find_session(adapter->disc_sessions, sender); if (req) { session_ref(req); return dbus_message_new_method_return(msg); } if (adapter->disc_sessions) goto done; if (main_opts.inqmode) err = start_inquiry(adapter); else err = start_periodic_inquiry(adapter); if (err < 0) return failed_strerror(msg, -err);done: req = create_session(adapter, conn, msg, 0, session_owner_exit); adapter->disc_sessions = g_slist_append(adapter->disc_sessions, req); return dbus_message_new_method_return(msg);}static DBusMessage *adapter_stop_discovery(DBusConnection *conn, DBusMessage *msg, void *data){ struct btd_adapter *adapter = data; struct session_req *req; const char *sender = dbus_message_get_sender(msg); if (!adapter->up) return adapter_not_ready(msg); req = find_session(adapter->disc_sessions, sender); if (!req) return g_dbus_create_error(msg, ERROR_INTERFACE ".Failed", "Invalid discovery session"); session_unref(req); return dbus_message_new_method_return(msg);}struct remote_device_list_t { GSList *list; time_t time;};static DBusMessage *get_properties(DBusConnection *conn, DBusMessage *msg, void *data){ struct btd_adapter *adapter = data; const char *property; DBusMessage *reply; DBusMessageIter iter; DBusMessageIter dict; char str[249], srcaddr[18]; gboolean value; char **devices; int i; GSList *l; ba2str(&adapter->bdaddr, srcaddr); if (check_address(srcaddr) < 0) return adapter_not_ready(msg); 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); /* Address */ property = srcaddr; dict_append_entry(&dict, "Address", DBUS_TYPE_STRING, &property); /* Name */ memset(str, 0, sizeof(str)); strncpy(str, (char *) adapter->dev.name, 248); property = str; dict_append_entry(&dict, "Name", DBUS_TYPE_STRING, &property); /* Powered */ if (main_opts.offmode == HCID_OFFMODE_DEVDOWN) value = adapter->up ? TRUE : FALSE; else value = adapter->scan_mode == SCAN_DISABLED ? FALSE : TRUE; dict_append_entry(&dict, "Powered", DBUS_TYPE_BOOLEAN, &value); /* Discoverable */ value = adapter->scan_mode & SCAN_INQUIRY ? TRUE : FALSE; dict_append_entry(&dict, "Discoverable", DBUS_TYPE_BOOLEAN, &value); /* Pairable */ dict_append_entry(&dict, "Pairable", DBUS_TYPE_BOOLEAN, &adapter->pairable); /* DiscoverableTimeout */ dict_append_entry(&dict, "DiscoverableTimeout", DBUS_TYPE_UINT32, &adapter->discov_timeout); /* PairableTimeout */ dict_append_entry(&dict, "PairableTimeout", DBUS_TYPE_UINT32, &adapter->pairable_timeout); if (adapter->state & PERIODIC_INQUIRY || adapter->state & STD_INQUIRY) value = TRUE; else value = FALSE; /* Discovering */ dict_append_entry(&dict, "Discovering", DBUS_TYPE_BOOLEAN, &value); /* Devices */ devices = g_new0(char *, g_slist_length(adapter->devices) + 1); for (i = 0, l = adapter->devices; l; l = l->next, i++) { struct btd_device *dev = l->data; devices[i] = (char *) device_get_path(dev); } dict_append_array(&dict, "Devices", DBUS_TYPE_OBJECT_PATH, &devices, i); g_free(devices); dbus_message_iter_close_container(&iter, &dict); return reply;}static DBusMessage *set_property(DBusConnection *conn, DBusMessage *msg, void *data){ struct btd_adapter *adapter = data; DBusMessageIter iter; DBusMessageIter sub; const char *property; char srcaddr[18]; ba2str(&adapter->bdaddr, srcaddr); if (!dbus_message_iter_init(msg, &iter)) return invalid_args(msg); if (dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_STRING) return invalid_args(msg); dbus_message_iter_get_basic(&iter, &property); dbus_message_iter_next(&iter); if (dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_VARIANT) return invalid_args(msg); dbus_message_iter_recurse(&iter, &sub); if (g_str_equal("Name", property)) { const char *name; if (dbus_message_iter_get_arg_type(&sub) != DBUS_TYPE_STRING) return invalid_args(msg); dbus_message_iter_get_basic(&sub, &name); return set_name(conn, msg, name, data); } else if (g_str_equal("Powered", property)) { gboolean powered; if (dbus_message_iter_get_arg_type(&sub) != DBUS_TYPE_BOOLEAN) return invalid_args(msg); dbus_message_iter_get_basic(&sub, &powered); return set_powered(conn, msg, powered, data); } else if (g_str_equal("Discoverable", property)) { gboolean discoverable; if (dbus_message_iter_get_arg_type(&sub) != DBUS_TYPE_BOOLEAN) return invalid_args(msg); dbus_message_iter_get_basic(&sub, &discoverable); return set_discoverable(conn, msg, discoverable, data); } else if (g_str_equal("DiscoverableTimeout", property)) { uint32_t timeout; if (dbus_message_iter_get_arg_type(&sub) != DBUS_TYPE_UINT32) return invalid_args(msg); dbus_message_iter_get_basic(&sub, &timeout); return set_discoverable_timeout(conn, msg, timeout, data); } else if (g_str_equal("Pairable", property)) { gboolean pairable; if (dbus_message_iter_get_arg_type(&sub) != DBUS_TYPE_BOOLEAN) return invalid_args(msg); dbus_message_iter_get_basic(&sub, &pairable); return set_pairable(conn, msg, pairable, data); } else if (g_str_equal("PairableTimeout", property)) { uint32_t timeout; if (dbus_message_iter_get_arg_type(&sub) != DBUS_TYPE_UINT32) return invalid_args(msg); dbus_message_iter_get_basic(&sub, &timeout); return set_pairable_timeout(conn, msg, timeout, data); } return invalid_args(msg);}static DBusMessage *request_session(DBusConnection *conn, DBusMessage *msg, void *data){ struct btd_adapter *adapter = data; struct session_req *req; const char *sender = dbus_message_get_sender(msg); uint8_t new_mode; int ret; if (!adapter->agent) return g_dbus_create_error(msg, ERROR_INTERFACE ".Failed", "No agent registered"); if (!adapter->mode_sessions) adapter->global_mode = adapter->mode; new_mode = get_mode(&adapter->bdaddr, "on"); req = find_session(adapter->mode_sessions, sender); if (req) { session_ref(req); return dbus_message_new_method_return(msg); } else { req = create_session(adapter, conn, msg, new_mode, session_owner_exit); adapter->mode_sessions = g_slist_append(adapter->mode_sessions, req); } /* No need to change mode */ if (adapter->mode >= new_mode) return dbus_message_new_method_return(msg); ret = agent_confirm_mode_change(adapter->agent, mode2str(new_mode), confirm_mode_cb, req); if (ret < 0) { session_unref(req); return failed_strerror(msg, -ret); } return NULL;}static DBusMessage *release_session(DBusConnection *conn, DBusMessage *msg, void *data){ struct btd_adapter *adapter = data; struct session_req *req; const char *sender = dbus_message_get_sender(msg); req = find_session(adapter->mode_sessions, sender); if (!req) return g_dbus_create_error(msg, ERROR_INTERFACE ".Failed", "No Mode to release"); session_unref(req); return dbus_message_new_method_return(msg);}static DBusMessage *list_devices(DBusConnection *conn, DBusMessage *msg, void *data){ struct btd_adapter *adapter = data; DBusMessage *reply; GSList *l; DBusMessageIter iter; DBusMessageIter array_iter; const gchar *dev_path; if (!dbus_message_has_signature(msg, DBUS_TYPE_INVALID_AS_STRING)) return invalid_args(msg); 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_TYPE_OBJECT_PATH_AS_STRING, &array_iter); for (l = adapter->devices; l; l = l->next) { struct btd_device *device = l->data; if (device_is_temporary(device)) continue; dev_path = device_get_path(device); dbus_message_iter_append_basic(&array_iter, DBUS_TYPE_OBJECT_PATH, &dev_path); } dbus_message_iter_close_container(&iter, &array_iter); return reply;}static DBusMessage *cancel_device_creation(DBusConnection *conn, DBusMessage *msg, void *data){ struct btd_adapter *adapter = data; struct bonding_request_info *bonding = adapter->bonding; const gchar *address; bdaddr_t bda; if (dbus_message_get_args(msg, NULL, DBUS_TYPE_STRING, &address, DBUS_TYPE_INVALID) == FALSE) return invalid_args(msg); if (check_address(address) < 0) return invalid_args(msg); str2ba(address, &bda); if (bonding && !bacmp(&bonding->bdaddr, &bda)) { if (!g_str_equal(dbus_message_get_sender(msg), dbus_message_get_sender(bonding->msg))) return not_authorized(msg); debug("Canceling device creation for %s", address); cancel_bonding(adapter, FALSE); } return dbus_message_new_method_return(msg);}static DBusMessage *create_device(DBusConnection *conn, DBusMessage *msg, void *data){ struct btd_adapter *adapter = data; struct btd_device *device; const gchar *address; if (dbus_message_get_args(msg, NULL, DBUS_TYPE_STRING, &address, DBUS_TYPE_INVALID) == FALSE) return invalid_args(msg); if (check_address(address) < 0) return invalid_args(msg); if (adapter_find_device(adapter, address)) return g_dbus_create_error(msg, ERROR_INTERFACE ".AlreadyExists", "Device already exists"); debug("create_device(%s)", address); device = adapter_create_device(conn, adapter, address); if (!device) return NULL; device_set_temporary(device, FALSE); device_browse(device, conn, msg, NULL, FALSE); return NULL;}static uint8_t parse_io_capability(const char *capability){ if (g_str_equal(capability, "")) return IO_CAPABILITY_DISPLAYYESNO; if (g_str_equal(capability, "DisplayOnly")) return IO_CAPABILITY_DISPLAYONLY; if (g_str_equal(capability, "DisplayYesNo")) return IO_CAPABILITY_DISPLAYYESNO; if (g_str_equal(capability, "KeyboardOnly")) return IO_CAPABILITY_KEYBOARDONLY; if (g_str_equal(capability, "NoInputOutput")) return IO_CAPABILITY_NOINPUTOUTPUT; return IO_CAPABILITY_INVALID;}static DBusMessage *create_paired_device(DBusConnection *conn, DBusMessage *msg, void *data){ const gchar *address, *agent_path, *capability; uint8_t cap; if (dbus_message_get_args(msg, NULL, DBUS_TYPE_STRING, &address, DBUS_TYPE_OBJECT_PATH, &agent_path, DBUS_TYPE_STRING, &capability, DBUS_TYPE_INVALID) == FALSE) return invalid_args(msg); if (check_address(address) < 0) return invalid_args(msg); cap = parse_io_capability(capability); if (cap == IO_CAPABILITY_INVALID) return invalid_args(msg); return create_bonding(conn, msg, address, agent_path, cap, data);}static gint device_path_cmp(struct btd_device *device, const gchar *path){ const gchar *dev_path = device_get_path(device); return strcasecmp(dev_path, path);}static DBusMessage *remove_device(DBusConnection *conn, DBusMessage *msg, void *data){ struct btd_adapter *adapter = data; struct btd_device *device; const char *path; GSList *l; if (dbus_message_get_args(msg, NULL, DBUS_TYPE_OBJECT_PATH, &path, DBUS_TYPE_INVALID) == FALSE) return invalid_args(msg); l = g_slist_find_custom(adapter->devices, path, (GCompareFunc) device_path_cmp); if (!l) return g_dbus_create_error(msg, ERROR_INTERFACE ".DoesNotExist", "Device does not exist"); device = l->data; if (device_is_temporary(device) || device_is_busy(device)) return g_dbus_create_error(msg, ERROR_INTERFACE ".DoesNotExist", "Device creation in progress"); adapter_remove_device(conn, adapter, device); return dbus_message_new_method_return(msg);}static DBusMessage *find_device(DBusConnection *conn, DBusMessage *msg, void *data){ struct btd_adapter *adapter = data; struct btd_device *device; DBusMessage *reply; const gchar *address; GSList *l; const gchar *dev_path; if (!dbus_message_get_args(msg, NULL, DBUS_TYPE_STRING, &address, DBUS_TYPE_INVALID)) return invalid_args(msg); l = g_slist_find_custom(adapter->devices, address, (GCompareFunc) device_address_cmp); if (!l) return g_dbus_create_error(msg, ERROR_INTERFACE ".DoesNotExist", "Device does not exist"); device = l->data; if (device_is_temporary(device)) return g_dbus_create_error(msg, ERROR_INTERFACE ".DoesNotExist", "Device creation in progress"); reply = dbus_message_new_method_return(msg); if (!reply) return NULL; dev_path = device_get_path(device); dbus_message_append_args(reply, DBUS_TYPE_OBJECT_PATH, &dev_path, DBUS_TYPE_INVALID); return reply;}static void agent_removed(struct agent *agent, struct btd_adapter *adapter){ struct pending_auth_info *auth; GSList *l; adapter->agent = NULL; l = g_slist_find_custom(adapter->auth_reqs, agent, auth_info_agent_cmp); if (!l) return; auth = l->data; auth->agent = NULL;}static DBusMessage *register_agent(DBusConnection *conn, DBusMessage *msg, void *data){ const char *path, *name, *capability;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -