📄 adapter.c
字号:
{ DBusMessage *reply; const char *minor_class; uint32_t class; if (get_remote_class(conn, msg, data, &class) < 0) return DBUS_HANDLER_RESULT_HANDLED; minor_class = minor_class_str(class); reply = dbus_message_new_method_return(msg); if (!reply) return DBUS_HANDLER_RESULT_NEED_MEMORY; dbus_message_append_args(reply, DBUS_TYPE_STRING, &minor_class, DBUS_TYPE_INVALID); return send_message_and_unref(conn, reply);}static void append_class_string(const char *class, DBusMessageIter *iter){ dbus_message_iter_append_basic(iter, DBUS_TYPE_STRING, &class);}static DBusHandlerResult adapter_get_remote_service_cls(DBusConnection *conn, DBusMessage *msg, void *data){ DBusMessage *reply; DBusMessageIter iter, array_iter; GSList *service_classes; uint32_t class; if (get_remote_class(conn, msg, data, &class) < 0) return DBUS_HANDLER_RESULT_HANDLED; reply = dbus_message_new_method_return(msg); if (!reply) return DBUS_HANDLER_RESULT_NEED_MEMORY; service_classes = service_classes_str(class); dbus_message_iter_init_append(reply, &iter); dbus_message_iter_open_container(&iter, DBUS_TYPE_ARRAY, DBUS_TYPE_STRING_AS_STRING, &array_iter); g_slist_foreach(service_classes, (GFunc) append_class_string, &array_iter); dbus_message_iter_close_container(&iter, &array_iter); g_slist_free(service_classes); return send_message_and_unref(conn, reply);}static DBusHandlerResult adapter_get_remote_class(DBusConnection *conn, DBusMessage *msg, void *data){ DBusMessage *reply; uint32_t class; if (get_remote_class(conn, msg, data, &class) < 0) return DBUS_HANDLER_RESULT_HANDLED; reply = dbus_message_new_method_return(msg); if (!reply) return DBUS_HANDLER_RESULT_NEED_MEMORY; dbus_message_append_args(reply, DBUS_TYPE_UINT32, &class, DBUS_TYPE_INVALID); return send_message_and_unref(conn, reply);}static DBusHandlerResult adapter_get_remote_features(DBusConnection *conn, DBusMessage *msg, void *data){ char filename[PATH_MAX + 1]; struct adapter *adapter = data; DBusMessage *reply = NULL; DBusMessageIter iter, array_iter; uint8_t features[8], *ptr = features; const char *addr; char *str; int i; if (!dbus_message_get_args(msg, NULL, DBUS_TYPE_STRING, &addr, DBUS_TYPE_INVALID)) return error_invalid_arguments(conn, msg, NULL); if (check_address(addr) < 0) return error_invalid_arguments(conn, msg, NULL); create_name(filename, PATH_MAX, STORAGEDIR, adapter->address, "features"); str = textfile_caseget(filename, addr); if (!str) return error_not_available(conn, msg); memset(features, 0, sizeof(features)); for (i = 0; i < sizeof(features); i++) { char tmp[3]; memcpy(tmp, str + (i * 2), 2); tmp[2] = '\0'; features[i] = (uint8_t) strtol(tmp, NULL, 16); } reply = dbus_message_new_method_return(msg); if (!reply) { free(str); return DBUS_HANDLER_RESULT_NEED_MEMORY; } dbus_message_iter_init_append(reply, &iter); dbus_message_iter_open_container(&iter, DBUS_TYPE_ARRAY, DBUS_TYPE_BYTE_AS_STRING, &array_iter); dbus_message_iter_append_fixed_array(&array_iter, DBUS_TYPE_BYTE, &ptr, sizeof(features)); dbus_message_iter_close_container(&iter, &array_iter); free(str); return send_message_and_unref(conn, reply);}static DBusHandlerResult adapter_get_remote_name(DBusConnection *conn, DBusMessage *msg, void *data){ char filename[PATH_MAX + 1]; struct adapter *adapter = data; DBusMessage *reply = NULL; const char *peer_addr; bdaddr_t peer_bdaddr; char *str; if (!dbus_message_get_args(msg, NULL, DBUS_TYPE_STRING, &peer_addr, DBUS_TYPE_INVALID)) return error_invalid_arguments(conn, msg, NULL); if (check_address(peer_addr) < 0) return error_invalid_arguments(conn, msg, NULL); /* check if it is in the cache */ create_name(filename, PATH_MAX, STORAGEDIR, adapter->address, "names"); str = textfile_caseget(filename, peer_addr); if (str) { reply = dbus_message_new_method_return(msg); if (!reply) { free(str); return DBUS_HANDLER_RESULT_NEED_MEMORY; } /* send the cached name */ dbus_message_append_args(reply, DBUS_TYPE_STRING, &str, DBUS_TYPE_INVALID); free(str); return send_message_and_unref(conn, reply); } if (!adapter->up) return error_not_ready(conn, msg); /* If the discover process is not running, return an error */ if (!adapter->discov_active && !adapter->pdiscov_active) return error_not_available(conn, msg); /* Queue the request when there is a discovery running */ str2ba(peer_addr, &peer_bdaddr); found_device_add(&adapter->found_devices, &peer_bdaddr, 0, NAME_REQUIRED); return error_request_deferred(conn, msg);}static DBusHandlerResult adapter_get_remote_alias(DBusConnection *conn, DBusMessage *msg, void *data){ struct adapter *adapter = data; DBusMessage *reply; char str[249], *str_ptr = str, *addr_ptr; bdaddr_t bdaddr; int ecode; if (!dbus_message_get_args(msg, NULL, DBUS_TYPE_STRING, &addr_ptr, DBUS_TYPE_INVALID)) return error_invalid_arguments(conn, msg, NULL); if (check_address(addr_ptr) < 0) return error_invalid_arguments(conn, msg, NULL); str2ba(addr_ptr, &bdaddr); ecode = get_device_alias(adapter->dev_id, &bdaddr, str, sizeof(str)); if (ecode < 0) return error_not_available(conn, msg); reply = dbus_message_new_method_return(msg); if (!reply) return DBUS_HANDLER_RESULT_NEED_MEMORY; dbus_message_append_args(reply, DBUS_TYPE_STRING, &str_ptr, DBUS_TYPE_INVALID); return send_message_and_unref(conn, reply);}static DBusHandlerResult adapter_set_remote_alias(DBusConnection *conn, DBusMessage *msg, void *data){ struct adapter *adapter = data; DBusMessage *reply; char *alias, *addr; bdaddr_t bdaddr; int ecode; if (!dbus_message_get_args(msg, NULL, DBUS_TYPE_STRING, &addr, DBUS_TYPE_STRING, &alias, DBUS_TYPE_INVALID)) return error_invalid_arguments(conn, msg, NULL); if ((strlen(alias) == 0) || (check_address(addr) < 0)) { error("Alias change failed: Invalid parameter"); return error_invalid_arguments(conn, msg, NULL); } str2ba(addr, &bdaddr); ecode = set_device_alias(adapter->dev_id, &bdaddr, alias); if (ecode < 0) return error_failed_errno(conn, msg, -ecode); reply = dbus_message_new_method_return(msg); if (!reply) return DBUS_HANDLER_RESULT_NEED_MEMORY; dbus_connection_emit_signal(conn, dbus_message_get_path(msg), ADAPTER_INTERFACE, "RemoteAliasChanged", DBUS_TYPE_STRING, &addr, DBUS_TYPE_STRING, &alias, DBUS_TYPE_INVALID); return send_message_and_unref(conn, reply);}static DBusHandlerResult adapter_clear_remote_alias(DBusConnection *conn, DBusMessage *msg, void *data){ struct adapter *adapter = data; DBusMessage *reply; char *addr_ptr; bdaddr_t bdaddr; int ecode, had_alias = 1; if (!dbus_message_get_args(msg, NULL, DBUS_TYPE_STRING, &addr_ptr, DBUS_TYPE_INVALID)) return error_invalid_arguments(conn, msg, NULL); if (check_address(addr_ptr) < 0) { error("Alias clear failed: Invalid parameter"); return error_invalid_arguments(conn, msg, NULL); } str2ba(addr_ptr, &bdaddr); ecode = get_device_alias(adapter->dev_id, &bdaddr, NULL, 0); if (ecode == -ENXIO) had_alias = 0; ecode = set_device_alias(adapter->dev_id, &bdaddr, NULL); if (ecode < 0) return error_failed_errno(conn, msg, -ecode); reply = dbus_message_new_method_return(msg); if (!reply) return DBUS_HANDLER_RESULT_NEED_MEMORY; if (had_alias) dbus_connection_emit_signal(conn, dbus_message_get_path(msg), ADAPTER_INTERFACE, "RemoteAliasCleared", DBUS_TYPE_STRING, &addr_ptr, DBUS_TYPE_INVALID); return send_message_and_unref(conn, reply);}static DBusHandlerResult adapter_last_seen(DBusConnection *conn, DBusMessage *msg, void *data){ struct adapter *adapter = data; DBusMessage *reply; char filename[PATH_MAX + 1]; char *addr_ptr, *str; if (!dbus_message_get_args(msg, NULL, DBUS_TYPE_STRING, &addr_ptr, DBUS_TYPE_INVALID)) return error_invalid_arguments(conn, msg, NULL); if (check_address(addr_ptr) < 0) return error_invalid_arguments(conn, msg, NULL); create_name(filename, PATH_MAX, STORAGEDIR, adapter->address, "lastseen"); str = textfile_caseget(filename, addr_ptr); if (!str) return error_not_available(conn, msg); reply = dbus_message_new_method_return(msg); if (!reply) { free(str); return DBUS_HANDLER_RESULT_NEED_MEMORY; } dbus_message_append_args(reply, DBUS_TYPE_STRING, &str, DBUS_TYPE_INVALID); free(str); return send_message_and_unref(conn, reply);}static DBusHandlerResult adapter_last_used(DBusConnection *conn, DBusMessage *msg, void *data){ struct adapter *adapter = data; DBusMessage *reply; char filename[PATH_MAX + 1]; char *addr_ptr, *str; if (!dbus_message_get_args(msg, NULL, DBUS_TYPE_STRING, &addr_ptr, DBUS_TYPE_INVALID)) return error_invalid_arguments(conn, msg, NULL); if (check_address(addr_ptr) < 0) return error_invalid_arguments(conn, msg, NULL); create_name(filename, PATH_MAX, STORAGEDIR, adapter->address, "lastused"); str = textfile_caseget(filename, addr_ptr); if (!str) return error_not_available(conn, msg); reply = dbus_message_new_method_return(msg); if (!reply) { free(str); return DBUS_HANDLER_RESULT_NEED_MEMORY; } dbus_message_append_args(reply, DBUS_TYPE_STRING, &str, DBUS_TYPE_INVALID); free(str); return send_message_and_unref(conn, reply);}gboolean dc_pending_timeout_handler(void *data){ int dd; struct adapter *adapter = data; struct pending_dc_info *pending_dc = adapter->pending_dc; DBusMessage *reply; dd = hci_open_dev(adapter->dev_id); if (dd < 0) { error_no_such_adapter(pending_dc->conn, pending_dc->msg); dc_pending_timeout_cleanup(adapter); return FALSE; } /* Send the HCI disconnect command */ if (hci_disconnect(dd, pending_dc->conn_handle, HCI_OE_USER_ENDED_CONNECTION, 500) < 0) { int err = errno; error("Disconnect failed"); error_failed_errno(pending_dc->conn, pending_dc->msg, err); } else { reply = dbus_message_new_method_return(pending_dc->msg); if (!reply) error("Failed to allocate disconnect reply"); else send_message_and_unref(pending_dc->conn, reply); } hci_close_dev(dd); dc_pending_timeout_cleanup(adapter); return FALSE;}void dc_pending_timeout_cleanup(struct adapter *adapter){ dbus_connection_unref(adapter->pending_dc->conn); dbus_message_unref(adapter->pending_dc->msg); g_free(adapter->pending_dc); adapter->pending_dc = NULL;}static DBusHandlerResult adapter_dc_remote_device(DBusConnection *conn, DBusMessage *msg, void *data){ struct adapter *adapter = data; GSList *l = adapter->active_conn; const char *peer_addr; bdaddr_t peer_bdaddr; if (!adapter->up) return error_not_ready(conn, msg); if (!dbus_message_get_args(msg, NULL, DBUS_TYPE_STRING, &peer_addr, DBUS_TYPE_INVALID)) return error_invalid_arguments(conn, msg, NULL); if (check_address(peer_addr) < 0) return error_invalid_arguments(conn, msg, NULL); str2ba(peer_addr, &peer_bdaddr); l = g_slist_find_custom(l, &peer_bdaddr, active_conn_find_by_bdaddr); if (!l) return error_not_connected(conn, msg); if (adapter->pending_dc) return error_disconnect_in_progress(conn, msg); adapter->pending_dc = g_new0(struct pending_dc_info, 1); /* Start waiting... */ adapter->pending_dc->timeout_id = g_timeout_add(DC_PENDING_TIMEOUT, dc_pending_timeout_handler, adapter); if (!adapter->pending_dc->timeout_id) { g_free(adapter->pending_dc); adapter->pending_dc = NULL; return DBUS_HANDLER_RESULT_NEED_MEMORY; } adapter->pending_dc->conn = dbus_connection_ref(conn); adapter->pending_dc->msg = dbus_message_ref(msg); adapter->pending_dc->conn_handle = ((struct active_conn_info *) l->data)->handle; dbus_connection_emit_signal(conn, dbus_message_get_path(msg), ADAPTER_INTERFACE, "RemoteDeviceDisconnectRequested", DBUS_TYPE_STRING, &peer_addr, DBUS_TYPE_INVALID); return DBUS_HANDLER_RESULT_HANDLED;}static void reply_authentication_failure(struct bonding_request_info *bonding){ DBusMessage *reply; int status; status = bonding->hci_status ? bonding->hci_status : HCI_AUTHENTICATION_FAILURE; reply = new_authentication_return(bonding->rq, status); if (reply) send_message_and_unref(bonding->conn, reply);}static gboolean create_bonding_conn_complete(GIOChannel *io, GIOCondition cond, struct adapter *adapter){ struct hci_request rq; auth_requested_cp cp; evt_cmd_status rp; struct l2cap_conninfo cinfo; socklen_t len; int sk, dd, ret; if (!adapter->bonding) { /* If we come here it implies a bug somewhere */ debug("create_bonding_conn_complete: no pending bonding!"); g_io_channel_close(io); g_io_channel_unref(io); return FALSE; } if (cond & G_IO_NVAL) { error_authentication_canceled(adapter->bonding->conn, adapter->bonding->rq); goto cleanup; } if (cond & (G_IO_HUP | G_IO_ERR)) { debug("Hangup or error on bonding IO channel"); if (!adapter->bonding->auth_active) error_connection_attempt_failed(adapter->bonding->conn, adapter->bonding->rq, ENETDOWN); else reply_authentication_failure(adapter->bonding); goto failed;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -