static void agent_disconnect(struct audio_device *dev, struct hf_agent *agent) { DBusMessage *msg; msg = dbus_message_new_method_call(agent->name, agent->path, "org.bluez.HandsfreeAgent", "Release"); g_dbus_send_message(btd_get_dbus_connection(), msg); agent_cancel(agent); }
static void simple_agent_reply(DBusPendingCall *call, void *user_data) { struct agent_request *req = user_data; struct agent *agent = req->agent; DBusMessage *message; DBusError err; agent_cb cb = req->cb; /* 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, simple_agent_reply) == 0) { dbus_error_free(&err); return; } error("Agent replied with an error: %s, %s", err.name, err.message); cb(agent, &err, req->user_data); if (dbus_error_has_name(&err, DBUS_ERROR_NO_REPLY)) { agent_cancel(agent); dbus_message_unref(message); dbus_error_free(&err); return; } dbus_error_free(&err); goto done; } dbus_error_init(&err); if (!dbus_message_get_args(message, &err, DBUS_TYPE_INVALID)) { error("Wrong reply signature: %s", err.message); cb(agent, &err, req->user_data); dbus_error_free(&err); goto done; } cb(agent, NULL, req->user_data); done: dbus_message_unref(message); agent->request = NULL; agent_request_free(req, TRUE); }
static void simple_agent_reply(DBusPendingCall *call, void *user_data) { struct agent_request *req = user_data; struct agent *agent = req->agent; DBusMessage *message; DBusError err; agent_cb cb = req->cb; /* 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)) { error("Agent replied with an error: %s, %s", err.name, err.message); cb(agent, &err, req->user_data); if (dbus_error_has_name(&err, DBUS_ERROR_NO_REPLY)) { agent_cancel(agent); dbus_message_unref(message); dbus_error_free(&err); return; } // +s LGBT_COMMON_TEMPORARY [email protected] 120829 if (dbus_error_has_name(&err, "org.bluez.Error.Canceled")) { DBG("User cancel the pairing"); DBG("->device_set_temporary"); device_set_temporary(((struct authentication_req*) req->user_data)->device, TRUE); } // +e LGBT_COMMON_TEMPORARY dbus_error_free(&err); goto done; } dbus_error_init(&err); if (!dbus_message_get_args(message, &err, DBUS_TYPE_INVALID)) { error("Wrong reply signature: %s", err.message); cb(agent, &err, req->user_data); dbus_error_free(&err); goto done; } cb(agent, NULL, req->user_data); done: dbus_message_unref(message); agent->request = NULL; agent_request_free(req, TRUE); }
static void simple_agent_reply(DBusPendingCall *call, void *user_data) { struct agent_request *req = user_data; struct agent *agent = req->agent; DBusMessage *message; DBusError err; agent_cb cb = req->cb; /* 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); /* Protect from the callback freeing the agent */ agent_ref(agent); dbus_error_init(&err); if (dbus_set_error_from_message(&err, message)) { DBG("agent error reply: %s, %s", err.name, err.message); cb(agent, &err, req->user_data); if (dbus_error_has_name(&err, DBUS_ERROR_NO_REPLY)) { error("Timed out waiting for reply from agent"); agent_cancel(agent); dbus_message_unref(message); dbus_error_free(&err); agent_unref(agent); return; } dbus_error_free(&err); goto done; } if (!dbus_message_get_args(message, &err, DBUS_TYPE_INVALID)) { error("Wrong reply signature: %s", err.message); cb(agent, &err, req->user_data); dbus_error_free(&err); goto done; } cb(agent, NULL, req->user_data); done: dbus_message_unref(message); agent->request = NULL; agent_request_free(req, TRUE); agent_unref(agent); }
static void display_pincode_reply(DBusPendingCall *call, void *user_data) { struct agent_request *req = user_data; struct agent *agent = req->agent; DBusMessage *message; DBusError err; agent_cb cb = req->cb; /* clear agent->request early; our callback will likely try * another request */ agent->request = NULL; /* 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)) { error("Agent replied with an error: %s, %s", err.name, err.message); cb(agent, &err, req->user_data); if (dbus_error_has_name(&err, DBUS_ERROR_NO_REPLY)) { agent_cancel(agent); dbus_message_unref(message); dbus_error_free(&err); return; } dbus_error_free(&err); goto done; } if (!dbus_message_get_args(message, &err, DBUS_TYPE_INVALID)) { error("Wrong reply signature: %s", err.message); cb(agent, &err, req->user_data); dbus_error_free(&err); goto done; } cb(agent, NULL, req->user_data); done: dbus_message_unref(message); agent_request_free(req, TRUE); }
void agent_unref(struct agent *agent) { agent->ref--; DBG("%p: ref=%d", agent, agent->ref); if (agent->ref > 0) return; if (agent->request) { DBusError err; agent_pincode_cb pincode_cb; agent_passkey_cb passkey_cb; agent_cb cb; dbus_error_init(&err); dbus_set_error_const(&err, ERROR_INTERFACE ".Failed", "Canceled"); switch (agent->request->type) { case AGENT_REQUEST_PINCODE: pincode_cb = agent->request->cb; pincode_cb(agent, &err, NULL, agent->request->user_data); break; case AGENT_REQUEST_PASSKEY: passkey_cb = agent->request->cb; passkey_cb(agent, &err, 0, agent->request->user_data); break; case AGENT_REQUEST_CONFIRMATION: case AGENT_REQUEST_AUTHORIZATION: case AGENT_REQUEST_AUTHORIZE_SERVICE: case AGENT_REQUEST_DISPLAY_PINCODE: default: cb = agent->request->cb; cb(agent, &err, agent->request->user_data); } dbus_error_free(&err); agent_cancel(agent); } g_free(agent->owner); g_free(agent->path); g_free(agent); }
void agent_free(struct agent *agent) { if (!agent) return; if (agent->remove_cb) agent->remove_cb(agent, agent->remove_cb_data); if (agent->request) { DBusError err; agent_pincode_cb pincode_cb; agent_passkey_cb passkey_cb; agent_cb cb; dbus_error_init(&err); dbus_set_error_const(&err, "org.bluez.Error.Failed", "Canceled"); switch (agent->request->type) { case AGENT_REQUEST_PINCODE: pincode_cb = agent->request->cb; pincode_cb(agent, &err, NULL, agent->request->user_data); break; case AGENT_REQUEST_PASSKEY: passkey_cb = agent->request->cb; passkey_cb(agent, &err, 0, agent->request->user_data); break; default: cb = agent->request->cb; cb(agent, &err, agent->request->user_data); } dbus_error_free(&err); agent_cancel(agent); } if (!agent->exited) { g_dbus_remove_watch(btd_get_dbus_connection(), agent->listener_id); agent_release(agent); } g_free(agent->name); g_free(agent->path); g_free(agent); }
static void agent_reply(DBusPendingCall *call, void *user_data) { DBusMessage *reply = dbus_pending_call_steal_reply(call); const char *name; DBusError derr; gboolean *got_reply = user_data; *got_reply = TRUE; /* Received a reply after the agent exited */ if (!agent) return; agent->auth_pending = FALSE; dbus_error_init(&derr); if (dbus_set_error_from_message(&derr, reply)) { error("Agent replied with an error: %s, %s", derr.name, derr.message); if (dbus_error_has_name(&derr, DBUS_ERROR_NO_REPLY)) agent_cancel(); dbus_error_free(&derr); dbus_message_unref(reply); return; } if (dbus_message_get_args(reply, NULL, DBUS_TYPE_STRING, &name, DBUS_TYPE_INVALID)) { /* Splits folder and name */ const char *slash = strrchr(name, '/'); DBG("Agent replied with %s", name); if (!slash) { agent->new_name = g_strdup(name); agent->new_folder = NULL; } else { agent->new_name = g_strdup(slash + 1); agent->new_folder = g_strndup(name, slash - name); } } dbus_message_unref(reply); }
static void agent_release(struct agent *agent) { DBusMessage *message; DBG("Releasing agent %s, %s", agent->name, agent->path); if (agent->request) agent_cancel(agent); message = dbus_message_new_method_call(agent->name, agent->path, "org.bluez.Agent", "Release"); if (message == NULL) { error("Couldn't allocate D-Bus message"); return; } g_dbus_send_message(connection, message); }
static void agent_release(struct agent *agent) { DBusMessage *message; DBG("Releasing agent %s, %s", agent->owner, agent->path); if (agent->request) agent_cancel(agent); message = dbus_message_new_method_call(agent->owner, agent->path, AGENT_INTERFACE, "Release"); if (message == NULL) { error("Couldn't allocate D-Bus message"); return; } g_dbus_send_message(btd_get_dbus_connection(), message); }
int gateway_close(struct audio_device *device) { GError *gerr = NULL; struct gateway *gw = device->gateway; int sock; if (gw->rfcomm_id != 0) { g_source_remove(gw->rfcomm_id); gw->rfcomm_id = 0; } if (gw->sco_id != 0) { g_source_remove(gw->sco_id); gw->sco_id = 0; } if (gw->rfcomm) { sock = g_io_channel_unix_get_fd(gw->rfcomm); shutdown(sock, SHUT_RDWR); g_io_channel_shutdown(gw->rfcomm, TRUE, NULL); g_io_channel_unref(gw->rfcomm); gw->rfcomm = NULL; } if (gw->sco) { g_io_channel_shutdown(gw->sco, TRUE, NULL); g_io_channel_unref(gw->sco); gw->sco = NULL; } if (gw->agent) agent_cancel(gw->agent); change_state(device, GATEWAY_STATE_DISCONNECTED); g_set_error(&gerr, GATEWAY_ERROR, GATEWAY_ERROR_DISCONNECTED, "Disconnected"); run_connect_cb(device, gerr); g_error_free(gerr); return 0; }
int manager_request_authorization(struct obex_transfer *transfer, int32_t time, char **new_folder, char **new_name) { struct obex_session *os = transfer->session; DBusMessage *msg; DBusPendingCall *call; unsigned int watch; gboolean got_reply; if (!agent) return -1; if (agent->auth_pending) return -EPERM; if (!new_folder || !new_name) return -EINVAL; msg = dbus_message_new_method_call(agent->bus_name, agent->path, AGENT_INTERFACE, "AuthorizePush"); dbus_message_append_args(msg, DBUS_TYPE_OBJECT_PATH, &transfer->path, DBUS_TYPE_INVALID); if (!g_dbus_send_message_with_reply(connection, msg, &call, TIMEOUT)) { dbus_message_unref(msg); return -EPERM; } dbus_message_unref(msg); agent->auth_pending = TRUE; got_reply = FALSE; /* Catches errors before authorization response comes */ watch = g_io_add_watch_full(os->io, G_PRIORITY_DEFAULT, G_IO_HUP | G_IO_ERR | G_IO_NVAL, auth_error, NULL, NULL); dbus_pending_call_set_notify(call, agent_reply, &got_reply, NULL); /* Workaround: process events while agent doesn't reply */ while (agent && agent->auth_pending) g_main_context_iteration(NULL, TRUE); g_source_remove(watch); if (!got_reply) { dbus_pending_call_cancel(call); agent_cancel(); } dbus_pending_call_unref(call); if (!agent || !agent->new_name) return -EPERM; *new_folder = agent->new_folder; *new_name = agent->new_name; agent->new_folder = NULL; agent->new_name = NULL; return 0; }
int manager_request_authorization(struct obex_session *os, int32_t time, char **new_folder, char **new_name) { DBusMessage *msg; DBusPendingCall *call; const char *filename = os->name ? os->name : ""; const char *type = os->type ? os->type : ""; char *path, *address; unsigned int watch; gboolean got_reply; int err; if (!agent) return -1; if (agent->auth_pending) return -EPERM; if (!new_folder || !new_name) return -EINVAL; err = obex_getpeername(os, &address); if (err < 0) return err; path = g_strdup_printf("/transfer%u", os->id); msg = dbus_message_new_method_call(agent->bus_name, agent->path, AGENT_INTERFACE, "Authorize"); dbus_message_append_args(msg, DBUS_TYPE_OBJECT_PATH, &path, DBUS_TYPE_STRING, &address, DBUS_TYPE_STRING, &filename, DBUS_TYPE_STRING, &type, DBUS_TYPE_INT32, &os->size, DBUS_TYPE_INT32, &time, DBUS_TYPE_INVALID); g_free(path); g_free(address); if (!dbus_connection_send_with_reply(connection, msg, &call, TIMEOUT)) { dbus_message_unref(msg); return -EPERM; } dbus_message_unref(msg); agent->auth_pending = TRUE; got_reply = FALSE; /* Catches errors before authorization response comes */ watch = g_io_add_watch_full(os->io, G_PRIORITY_DEFAULT, G_IO_HUP | G_IO_ERR | G_IO_NVAL, auth_error, NULL, NULL); dbus_pending_call_set_notify(call, agent_reply, &got_reply, NULL); /* Workaround: process events while agent doesn't reply */ while (agent && agent->auth_pending) g_main_context_iteration(NULL, TRUE); g_source_remove(watch); if (!got_reply) { dbus_pending_call_cancel(call); agent_cancel(); } dbus_pending_call_unref(call); if (!agent || !agent->new_name) return -EPERM; *new_folder = agent->new_folder; *new_name = agent->new_name; agent->new_folder = NULL; agent->new_name = NULL; return 0; }