DBusHandlerResult error_sdp_failed(DBusConnection *conn, DBusMessage *msg, int err) { const char *str = strsdperror(err); return send_message_and_unref(conn, dbus_message_new_error(msg, ERROR_INTERFACE ".Failed", str)); }
static void send_cancel_request(struct pending_agent_request *req) { DBusMessage *message; char address[18], *ptr = address; message = dbus_message_new_method_call(req->agent->name, req->agent->path, "org.bluez.PasskeyAgent", "Cancel"); if (message == NULL) { error("Couldn't allocate D-Bus message"); return; } ba2str(&req->bda, address); dbus_message_append_args(message, DBUS_TYPE_STRING, &req->path, DBUS_TYPE_STRING, &ptr, DBUS_TYPE_INVALID); dbus_message_set_no_reply(message, TRUE); send_message_and_unref(req->agent->conn, message); debug("PasskeyAgent.Request(%s, %s) was canceled", req->path, address); dbus_pending_call_cancel(req->call); dbus_pending_call_unref(req->call); g_free(req->pin); g_free(req->path); g_free(req); }
static DBusHandlerResult auth_agent_send_cancel(DBusMessage *msg, struct authorization_agent *agent, const char *adapter_path, struct service *service, const char *address, const char *path) { struct auth_agent_req *req = NULL; DBusMessage *message; GSList *l; for (l = agent->pending_requests; l != NULL; l = l->next) { req = l->data; if (!strcmp(adapter_path, req->adapter_path) && !strcmp(address, req->address) && !strcmp(service->object_path, req->service_path) && !strcmp(path, req->uuid)) break; } if (!req) return error_does_not_exist(agent->conn, msg, "No such authorization process"); message = dbus_message_new_method_return(msg); if (!message) return DBUS_HANDLER_RESULT_NEED_MEMORY; auth_agent_call_cancel(req); auth_agent_req_cancel(req); agent->pending_requests = g_slist_remove(agent->pending_requests, req); auth_agent_req_free(req); return send_message_and_unref(agent->conn, message); }
static void release_agent(struct passkey_agent *agent) { DBusMessage *message; debug("Releasing agent %s, %s", agent->name, agent->path); message = dbus_message_new_method_call(agent->name, agent->path, "org.bluez.PasskeyAgent", "Release"); if (message == NULL) { error("Couldn't allocate D-Bus message"); return; } dbus_message_set_no_reply(message, TRUE); send_message_and_unref(agent->conn, message); if (agent == default_agent) name_listener_remove(agent->conn, agent->name, (name_cb_t) default_agent_exited, NULL); else { struct passkey_agent ref; /* Only remove the name listener if there are no more agents for this name */ memset(&ref, 0, sizeof(ref)); ref.name = agent->name; if (!g_slist_find_custom(agent->adapter->passkey_agents, &ref, (GCompareFunc) agent_cmp)) name_listener_remove(agent->conn, ref.name, (name_cb_t) agent_exited, agent->adapter); } }
static DBusHandlerResult unregister_default_passkey_agent(DBusConnection *conn, DBusMessage *msg, void *data) { DBusMessage *reply; const char *path, *name; if (!default_agent) return error_passkey_agent_does_not_exist(conn, msg); if (!dbus_message_get_args(msg, NULL, DBUS_TYPE_STRING, &path, DBUS_TYPE_INVALID)) return error_invalid_arguments(conn, msg, NULL); name = dbus_message_get_sender(msg); if (strcmp(name, default_agent->name) || strcmp(path, default_agent->path)) return error_passkey_agent_does_not_exist(conn, msg); reply = dbus_message_new_method_return(msg); if (!reply) return DBUS_HANDLER_RESULT_NEED_MEMORY; name_listener_remove(conn, default_agent->name, (name_cb_t) default_agent_exited, NULL); info("Default passkey agent (%s, %s) unregistered", default_agent->name, default_agent->path); default_agent->exited = 1; passkey_agent_free(default_agent); default_agent = NULL; return send_message_and_unref(conn, reply); }
static DBusHandlerResult register_passkey_agent(DBusConnection *conn, DBusMessage *msg, void *data) { struct passkey_agent *agent, ref; struct adapter *adapter; DBusMessage *reply; const char *path, *addr; if (!data) { error("register_passkey_agent called without any adapter info!"); return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; } adapter = data; if (!dbus_message_get_args(msg, NULL, DBUS_TYPE_STRING, &path, DBUS_TYPE_STRING, &addr, DBUS_TYPE_INVALID)) return error_invalid_arguments(conn, msg, NULL); if ((check_address(addr) < 0) || (path[0] != '/')) return error_invalid_arguments(conn, msg, NULL); memset(&ref, 0, sizeof(ref)); ref.name = (char *) dbus_message_get_sender(msg); ref.addr = (char *) addr; ref.path = (char *) path; if (g_slist_find_custom(adapter->passkey_agents, &ref, (GCompareFunc) agent_cmp)) return error_passkey_agent_already_exists(conn, msg); agent = passkey_agent_new(adapter, conn, ref.name, path, addr); if (!agent) return DBUS_HANDLER_RESULT_NEED_MEMORY; reply = dbus_message_new_method_return(msg); if (!reply) { agent->exited = 1; passkey_agent_free(agent); return DBUS_HANDLER_RESULT_NEED_MEMORY; } /* Only add a name listener if there isn't one already for this name */ ref.addr = NULL; ref.path = NULL; if (!g_slist_find_custom(adapter->passkey_agents, &ref, (GCompareFunc) agent_cmp)) name_listener_add(conn, ref.name, (name_cb_t) agent_exited, adapter); agent->timeout = g_timeout_add(AGENT_TIMEOUT, (GSourceFunc)agent_timeout, agent); adapter->passkey_agents = g_slist_append(adapter->passkey_agents, agent); return send_message_and_unref(conn, reply); }
DBusHandlerResult error_unknown_method(DBusConnection *conn, DBusMessage *msg) { char error[128]; const char *signature = dbus_message_get_signature(msg); const char *method = dbus_message_get_member(msg); const char *interface = dbus_message_get_interface(msg); snprintf(error, 128, "Method \"%s\" with signature \"%s\" on interface \"%s\" doesn't exist", method, signature, interface); return send_message_and_unref(conn, dbus_message_new_error(msg, ERROR_INTERFACE ".UnknownMethod", error)); }
static void auth_agent_req_reply(DBusPendingCall *call, void *data) { struct auth_agent_req *req = data; struct authorization_agent *agent = req->agent; DBusMessage *reply = dbus_pending_call_steal_reply(call); DBusMessage *message; DBusError err; debug("authorize reply"); dbus_error_init(&err); if (dbus_set_error_from_message(&err, reply)) { if (dbus_error_has_name(&err, DBUS_ERROR_NO_REPLY)) auth_agent_call_cancel(req); error("Authorization agent replied with an error: %s, %s", err.name, err.message); dbus_error_free(&err); goto reject; } dbus_error_init(&err); if (!dbus_message_get_args(reply, &err, DBUS_TYPE_INVALID)) { error("Wrong authorization agent reply signature: %s", err.message); dbus_error_free(&err); goto reject; } message = dbus_message_new_method_return(req->msg); if (!message) goto reject; send_message_and_unref(agent->conn, message); debug("successfull reply was sent"); goto done; reject: error_rejected(agent->conn, req->msg); done: dbus_message_unref(reply); agent->pending_requests = g_slist_remove(agent->pending_requests, req); auth_agent_req_free(req); debug("auth_agent_reply: returning"); }
static DBusHandlerResult unregister_passkey_agent(DBusConnection *conn, DBusMessage *msg, void *data) { struct adapter *adapter; GSList *match; struct passkey_agent ref, *agent; DBusMessage *reply; const char *path, *addr; if (!data) { error("unregister_passkey_agent called without any adapter info!"); return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; } adapter = data; if (!dbus_message_get_args(msg, NULL, DBUS_TYPE_STRING, &path, DBUS_TYPE_STRING, &addr, DBUS_TYPE_INVALID)) return error_invalid_arguments(conn, msg, NULL); memset(&ref, 0, sizeof(ref)); ref.name = (char *) dbus_message_get_sender(msg); ref.path = (char *) path; ref.addr = (char *) addr; match = g_slist_find_custom(adapter->passkey_agents, &ref, (GCompareFunc) agent_cmp); if (!match) return error_passkey_agent_does_not_exist(conn, msg); agent = match->data; name_listener_remove(agent->conn, agent->name, (name_cb_t) agent_exited, adapter); adapter->passkey_agents = g_slist_remove(adapter->passkey_agents, agent); agent->exited = 1; passkey_agent_free(agent); reply = dbus_message_new_method_return(msg); if (!reply) return DBUS_HANDLER_RESULT_NEED_MEMORY; return send_message_and_unref(conn, reply); }
static void auth_agent_release(struct authorization_agent *agent) { DBusMessage *message; debug("Releasing authorization agent %s, %s", agent->name, agent->path); message = dbus_message_new_method_call(agent->name, agent->path, "org.bluez.AuthorizationAgent", "Release"); if (!message) { error("Couldn't allocate D-Bus message"); return; } dbus_message_set_no_reply(message, TRUE); send_message_and_unref(agent->conn, message); if (agent == default_auth_agent) name_listener_remove(agent->conn, agent->name, (name_cb_t) default_auth_agent_exited, NULL); }
static DBusHandlerResult register_default_auth_agent(DBusConnection *conn, DBusMessage *msg, void *data) { DBusMessage *reply; const char *path; if (default_auth_agent) return error_auth_agent_already_exists(conn, msg); if (!dbus_message_get_args(msg, NULL, DBUS_TYPE_STRING, &path, DBUS_TYPE_INVALID)) return error_invalid_arguments(conn, msg, NULL); default_auth_agent = auth_agent_new(conn, dbus_message_get_sender(msg), path); if (!default_auth_agent) goto need_memory; reply = dbus_message_new_method_return(msg); if (!reply) goto need_memory; name_listener_add(conn, default_auth_agent->name, (name_cb_t) default_auth_agent_exited, NULL); info("Default authorization agent (%s, %s) registered", default_auth_agent->name, default_auth_agent->path); return send_message_and_unref(conn, reply); need_memory: if (default_auth_agent) { auth_agent_free(default_auth_agent); default_auth_agent = NULL; } return DBUS_HANDLER_RESULT_NEED_MEMORY; }
static void auth_agent_call_cancel(struct auth_agent_req *req) { struct authorization_agent *agent = req->agent; DBusMessage *message; message = dbus_message_new_method_call(agent->name, agent->path, "org.bluez.AuthorizationAgent", "Cancel"); if (!message) { error("Couldn't allocate D-Bus message"); return; } dbus_message_append_args(message, DBUS_TYPE_STRING, &req->adapter_path, DBUS_TYPE_STRING, &req->address, DBUS_TYPE_STRING, &req->service_path, DBUS_TYPE_STRING, &req->uuid, DBUS_TYPE_INVALID); dbus_message_set_no_reply(message, TRUE); send_message_and_unref(agent->conn, message); }
DBusHandlerResult error_no_such_adapter(DBusConnection *conn, DBusMessage *msg) { return send_message_and_unref(conn, dbus_message_new_error(msg, ERROR_INTERFACE ".NoSuchAdapter", "No such adapter")); }
DBusHandlerResult error_unsupported_major_class(DBusConnection *conn, DBusMessage *msg) { return send_message_and_unref(conn, dbus_message_new_error(msg, ERROR_INTERFACE ".UnsupportedMajorClass", "Unsupported Major Class")); }
DBusHandlerResult error_request_deferred(DBusConnection *conn, DBusMessage *msg) { return send_message_and_unref(conn, dbus_message_new_error(msg, ERROR_INTERFACE ".RequestDeferred", "Request Deferred")); }
DBusHandlerResult error_no_such_service(DBusConnection *conn, DBusMessage *msg) { return send_message_and_unref(conn, dbus_message_new_error(msg, ERROR_INTERFACE ".NoSuchService", "No such service")); }
DBusHandlerResult error_not_authorized(DBusConnection *conn, DBusMessage *msg) { return send_message_and_unref(conn, dbus_message_new_error(msg, ERROR_INTERFACE ".NotAuthorized", "Not authorized")); }
DBusHandlerResult error_authentication_canceled(DBusConnection *conn, DBusMessage *msg) { return send_message_and_unref(conn, dbus_message_new_error(msg, ERROR_INTERFACE ".AuthenticationCanceled", "Authentication Canceled")); }
DBusHandlerResult error_not_in_progress(DBusConnection *conn, DBusMessage *msg, const char *str) { return send_message_and_unref(conn, dbus_message_new_error(msg, ERROR_INTERFACE ".NotInProgress", str)); }
DBusHandlerResult error_not_ready(DBusConnection *conn, DBusMessage *msg) { return send_message_and_unref(conn, dbus_message_new_error(msg, ERROR_INTERFACE ".NotReady", "Adapter is not ready")); }