diff options
author | Luiz Augusto von Dentz <luiz.dentz@openbossa.org> | 2008-03-14 21:47:32 +0000 |
---|---|---|
committer | Luiz Augusto von Dentz <luiz.dentz@openbossa.org> | 2008-03-14 21:47:32 +0000 |
commit | b4fcae17e8a9f6242b752bfb9808248cadbde43b (patch) | |
tree | ac8938b3e44b69d1bdbb684d1b106f321d6ef855 /hcid/adapter.c | |
parent | 9bafbc5c70f6dde0f9219aea446d21f653826888 (diff) |
Introduce adapter method RequestMode.
Diffstat (limited to 'hcid/adapter.c')
-rw-r--r-- | hcid/adapter.c | 69 |
1 files changed, 69 insertions, 0 deletions
diff --git a/hcid/adapter.c b/hcid/adapter.c index 55565b18..ebcfb51a 100644 --- a/hcid/adapter.c +++ b/hcid/adapter.c @@ -3707,6 +3707,74 @@ static DBusHandlerResult unregister_agent(DBusConnection *conn, return send_message_and_unref(conn, reply); } +void request_mode_cb(struct agent *agent, DBusError *err, void *data) +{ + struct mode_req *req = data; + DBusMessage *derr; + + if (err && dbus_error_is_set(err)) { + derr = dbus_message_new_error(req->msg, err->name, err->message); + dbus_connection_send_and_unref(req->conn, derr); + goto cleanup; + } + + set_mode(req->conn, req->msg, req->mode, req->adapter); + +cleanup: + dbus_connection_unref(req->conn); + dbus_message_unref(req->msg); + g_free(req->mode); + g_free(req); +} + +static DBusHandlerResult request_mode(DBusConnection *conn, + DBusMessage *msg, void *data) +{ + const char *mode; + struct adapter *adapter = data; + DBusMessage *reply; + struct mode_req *req; + uint8_t new_mode; + int ret; + + if (!hcid_dbus_use_experimental()) + return error_unknown_method(conn, msg); + + if (!dbus_message_get_args(msg, NULL, DBUS_TYPE_STRING, &mode, + DBUS_TYPE_INVALID)) + return error_invalid_arguments(conn, msg, NULL); + + new_mode = str2mode(adapter->address, mode); + if (new_mode != MODE_CONNECTABLE && new_mode != MODE_DISCOVERABLE) + return error_invalid_arguments(conn, msg, NULL); + + /* No need to change mode */ + if (adapter->mode > new_mode) { + reply = dbus_message_new_method_return(msg); + if (!reply) + return DBUS_HANDLER_RESULT_NEED_MEMORY; + + return send_message_and_unref(conn, reply); + } + + req = g_new0(struct mode_req, 1); + req->adapter = adapter; + req->conn = dbus_connection_ref(conn); + req->msg = dbus_message_ref(msg); + req->mode = g_strdup(mode); + ret = agent_confirm_mode_change(adapter->agent, mode, request_mode_cb, + req); + if (ret < 0) { + dbus_connection_unref(req->conn); + dbus_message_unref(req->msg); + g_free(req->mode); + g_free(req); + return error_invalid_arguments(conn, msg, NULL); + } + + return DBUS_HANDLER_RESULT_HANDLED; +} + const char *major_class_str(uint32_t class) { uint8_t index = (class >> 8) & 0x1F; @@ -3810,6 +3878,7 @@ static DBusMethodVTable adapter_methods[] = { { "FindDevice", find_device, "s", "o" }, { "RegisterAgent", register_agent, "o", "" }, { "UnregisterAgent", unregister_agent, "o", "" }, + { "RequestMode", request_mode, "s", "" }, { NULL, NULL, NULL, NULL } }; |