📄 agent.c
字号:
} dbus_error_init(&err); if (!dbus_message_get_args(message, &err, DBUS_TYPE_STRING, &pin, DBUS_TYPE_INVALID)) { error("Wrong passkey reply signature: %s", err.message); cb(agent, &err, NULL, req->user_data); dbus_error_free(&err); goto done; } len = strlen(pin); dbus_error_init(&err); if (len > 16 || len < 1) { error("Invalid passkey length from handler"); dbus_set_error_const(&err, "org.bluez.Error.InvalidArgs", "Invalid passkey length"); cb(agent, &err, NULL, req->user_data); dbus_error_free(&err); goto done; } str2ba(source, &sba); set_pin_length(&sba, len); cb(agent, NULL, pin, req->user_data);done: if (message) dbus_message_unref(message); dbus_pending_call_cancel(req->call); agent->request = NULL; agent_request_free(req);}static int pincode_request_new(struct agent_request *req, const char *device_path, dbus_bool_t numeric){ struct agent *agent = req->agent; req->msg = dbus_message_new_method_call(agent->name, agent->path, "org.bluez.Agent", "RequestPinCode"); if (req->msg == NULL) { error("Couldn't allocate D-Bus message"); return -ENOMEM; } dbus_message_append_args(req->msg, DBUS_TYPE_OBJECT_PATH, &device_path, DBUS_TYPE_INVALID); if (dbus_connection_send_with_reply(connection, req->msg, &req->call, REQUEST_TIMEOUT) == FALSE) { error("D-Bus send failed"); return -EIO; } dbus_pending_call_set_notify(req->call, pincode_reply, req, NULL); return 0;}int agent_request_pincode(struct agent *agent, struct btd_device *device, agent_pincode_cb cb, void *user_data){ struct agent_request *req; const gchar *dev_path = device_get_path(device); int err; if (agent->request) return -EBUSY; req = agent_request_new(agent, AGENT_REQUEST_PINCODE, cb, user_data); err = pincode_request_new(req, dev_path, FALSE); if (err < 0) goto failed; agent->request = req; return 0;failed: g_free(req); return err;}static int confirm_mode_change_request_new(struct agent_request *req, const char *mode){ struct agent *agent = req->agent; req->msg = dbus_message_new_method_call(agent->name, agent->path, "org.bluez.Agent", "ConfirmModeChange"); if (req->msg == NULL) { error("Couldn't allocate D-Bus message"); return -ENOMEM; } dbus_message_append_args(req->msg, DBUS_TYPE_STRING, &mode, DBUS_TYPE_INVALID); if (dbus_connection_send_with_reply(connection, req->msg, &req->call, REQUEST_TIMEOUT) == FALSE) { error("D-Bus send failed"); return -EIO; } dbus_pending_call_set_notify(req->call, simple_agent_reply, req, NULL); return 0;}int agent_confirm_mode_change(struct agent *agent, const char *new_mode, agent_cb cb, void *user_data){ struct agent_request *req; int err; if (agent->request) return -EBUSY; debug("Calling Agent.ConfirmModeChange: name=%s, path=%s, mode=%s", agent->name, agent->path, new_mode); req = agent_request_new(agent, AGENT_REQUEST_CONFIRM_MODE, cb, user_data); err = confirm_mode_change_request_new(req, new_mode); if (err < 0) goto failed; agent->request = req; return 0;failed: agent_request_free(req); return err;}static void passkey_reply(DBusPendingCall *call, void *user_data){ struct agent_request *req = user_data; struct agent *agent = req->agent; agent_passkey_cb cb = req->cb; DBusMessage *message; DBusError err; uint32_t passkey; /* steal_reply will always return non-NULL since the callback * is only called after a reply has been received */ message = dbus_pending_call_steal_reply(call); dbus_error_init(&err); if (dbus_set_error_from_message(&err, message)) { if ((g_str_equal(DBUS_ERROR_UNKNOWN_METHOD, err.name) || g_str_equal(DBUS_ERROR_NO_REPLY, err.name)) && request_fallback(req, passkey_reply) == 0) { dbus_error_free(&err); return; } error("Agent replied with an error: %s, %s", err.name, err.message); cb(agent, &err, 0, req->user_data); dbus_error_free(&err); goto done; } dbus_error_init(&err); if (!dbus_message_get_args(message, &err, DBUS_TYPE_UINT32, &passkey, DBUS_TYPE_INVALID)) { error("Wrong passkey reply signature: %s", err.message); cb(agent, &err, 0, req->user_data); dbus_error_free(&err); goto done; } cb(agent, NULL, passkey, req->user_data);done: if (message) dbus_message_unref(message); dbus_pending_call_cancel(req->call); agent->request = NULL; agent_request_free(req);}static int passkey_request_new(struct agent_request *req, const char *device_path){ struct agent *agent = req->agent; req->msg = dbus_message_new_method_call(agent->name, agent->path, "org.bluez.Agent", "RequestPasskey"); if (req->msg == NULL) { error("Couldn't allocate D-Bus message"); return -ENOMEM; } dbus_message_append_args(req->msg, DBUS_TYPE_OBJECT_PATH, &device_path, DBUS_TYPE_INVALID); if (dbus_connection_send_with_reply(connection, req->msg, &req->call, REQUEST_TIMEOUT) == FALSE) { error("D-Bus send failed"); return -EIO; } dbus_pending_call_set_notify(req->call, passkey_reply, req, NULL); return 0;}int agent_request_passkey(struct agent *agent, struct btd_device *device, agent_passkey_cb cb, void *user_data){ struct agent_request *req; const gchar *dev_path = device_get_path(device); int err; if (agent->request) return -EBUSY; debug("Calling Agent.RequestPasskey: name=%s, path=%s", agent->name, agent->path); req = agent_request_new(agent, AGENT_REQUEST_PASSKEY, cb, user_data); err = passkey_request_new(req, dev_path); if (err < 0) goto failed; agent->request = req; return 0;failed: agent_request_free(req); return err;}static int confirmation_request_new(struct agent_request *req, const char *device_path, uint32_t passkey){ struct agent *agent = req->agent; req->msg = dbus_message_new_method_call(agent->name, agent->path, "org.bluez.Agent", "RequestConfirmation"); if (req->msg == NULL) { error("Couldn't allocate D-Bus message"); return -ENOMEM; } dbus_message_append_args(req->msg, DBUS_TYPE_OBJECT_PATH, &device_path, DBUS_TYPE_UINT32, &passkey, DBUS_TYPE_INVALID); if (dbus_connection_send_with_reply(connection, req->msg, &req->call, REQUEST_TIMEOUT) == FALSE) { error("D-Bus send failed"); return -EIO; } dbus_pending_call_set_notify(req->call, simple_agent_reply, req, NULL); return 0;}int agent_request_confirmation(struct agent *agent, struct btd_device *device, uint32_t passkey, agent_cb cb, void *user_data){ struct agent_request *req; const gchar *dev_path = device_get_path(device); int err; if (agent->request) return -EBUSY; debug("Calling Agent.RequestConfirmation: name=%s, path=%s, passkey=%06u", agent->name, agent->path, passkey); req = agent_request_new(agent, AGENT_REQUEST_CONFIRMATION, cb, user_data); err = confirmation_request_new(req, dev_path, passkey); if (err < 0) goto failed; agent->request = req; return 0;failed: agent_request_free(req); return err;}static int request_fallback(struct agent_request *req, DBusPendingCallNotifyFunction function){ struct adapter *adapter = req->agent->adapter; DBusMessage *msg; if (req->agent == adapter->agent || adapter->agent == NULL) return -EINVAL; dbus_pending_call_cancel(req->call); msg = dbus_message_copy(req->msg); dbus_message_set_destination(msg, adapter->agent->name); dbus_message_set_path(msg, adapter->agent->path); if (dbus_connection_send_with_reply(connection, msg, &req->call, REQUEST_TIMEOUT) == FALSE) { error("D-Bus send failed"); dbus_message_unref(msg); return -EIO; } req->agent->request = NULL; req->agent = adapter->agent; req->agent->request = req; dbus_message_unref(req->msg); req->msg = msg; dbus_pending_call_set_notify(req->call, function, req, NULL); return 0;}int agent_display_passkey(struct agent *agent, struct btd_device *device, uint32_t passkey){ DBusMessage *message; const gchar *dev_path = device_get_path(device); message = dbus_message_new_method_call(agent->name, agent->path, "org.bluez.Agent", "DisplayPasskey"); if (!message) { error("Couldn't allocate D-Bus message"); return -1; } dbus_message_append_args(message, DBUS_TYPE_OBJECT_PATH, &dev_path, DBUS_TYPE_UINT32, &passkey, DBUS_TYPE_INVALID); if (!g_dbus_send_message(connection, message)) { error("D-Bus send failed"); dbus_message_unref(message); return -1; } return 0;}uint8_t agent_get_io_capability(struct agent *agent){ return agent->capability;}gboolean agent_matches(struct agent *agent, const char *name, const char *path){ if (g_str_equal(agent->name, name) && g_str_equal(agent->path, path)) return TRUE; return FALSE;}void agent_exit(void){ dbus_connection_unref(connection);}void agent_init(void){ connection = dbus_bus_get(DBUS_BUS_SYSTEM, NULL);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -