if (i != data->info.end()) {
auto & response = i->second.response;
response.send_error(error);
+
+ /**
+ * @todo Make sure map element removal occurs if exception is
+ * thrown above.
+ */
+ // Done with the connection data.
+ data->info.erase(i);
}
}
bool
on_handle_request_input(Agent * object,
GDBusMethodInvocation * invocation,
- gchar const * /* service */,
- GVariant * /* fields */,
- gpointer /* user_data */)
+ gchar const * service,
+ GVariant * fields,
+ gpointer user_data)
{
- GVariant * response = nullptr;
+ using namespace ivi::settings;
+ typedef agent::user_data data_type;
+
+ data_type * const data = static_cast<data_type *>(user_data);
+
+ {
+ std::lock_guard<std::mutex> guard(data->lock);
+
+ auto const i = data->info.find(service);
+ if (i != data->info.end()) {
+ // Extract requested mandatory and alternate fields.
+ GVariantIter * vi = nullptr;
+ g_variant_get(fields, "(a{sv})", &vi);
+ unique_ptr<GVariantIter> const iter(vi);
+
+ gchar * fname = nullptr;
+ GVariant * fvalue = nullptr;
+
+ while (g_variant_iter_next(vi, "{sv}", &fname, &fvalue)) {
+ unique_ptr<gchar> const name(fname);
+ unique_ptr<GVariant> const value(fvalue);
+
+
+ }
+
+
+ auto & response = i->second.response;
+
+ // Nothing to add to successful response.
+ response.send_response(
+ [](JsonBuilder * /* builder */) {});
+
+ /**
+ * @todo Make sure map element removal occurs if exception is
+ * thrown above.
+ */
+ // Done with the connection data.
+ data->info.erase(i);
+ }
+ }
+
+
+
+ GVariant * dictionary = nullptr;
+
+
// The method return value will contain a dictionary of the
// requested input fields.
- agent_complete_request_input(object, invocation, response);
+ agent_complete_request_input(object, invocation, dictionary);
return true;
}
* @struct connect_data
*
* @brief Connman Service object-specific connect data.
+ *
+ * An instance of this structure will be created each time a
+ * Connman connection operation will be performed in case
+ * Connman needs additional information, such as a passphrase,
+ * to complete a connection.
*/
struct connect_data
{
+ /**
+ * Constructor.
+ *
+ * @note We bump the reference count on the @c JsonReader
+ * object.
+ */
connect_data(JsonReader * rd,
response_callback const & resp)
: reader(static_cast<JsonReader *>(g_object_ref(rd)))
{
}
+ /// Move constructor.
connect_data(connect_data && other)
: reader(std::move(other.reader))
, response(other.response)
// Nothing to do with response field.
}
+ /// Disallow copy construction.
connect_data(connect_data const &) = delete;
+ /**
+ * Pointer to the @c JsonReader object containing the request
+ * information, including arguments.
+ */
unique_ptr<JsonReader> reader;
+
+ /**
+ * The response callback through errors will be sent to the
+ * caller.
+ */
response_callback response;
};
if (manager_.register_connect_data(service_path,
reader,
response)) {
+ class auto_deregister
+ {
+ public:
+ auto_deregister(connman_manager & manager,
+ char const * service_path)
+ : manager_(manager)
+ , service_path_(service_path)
+ {
+ }
+
+ ~auto_deregister()
+ {
+ manager_.deregister_connect_data(service_path_);
+ }
+
+ private:
+
+ connman_manager & manager_;
+ char const * service_path_;
+
+ };
+
+ auto_deregister const dereg(manager_, service_path);
+
service s(service_path,
connman_.connection(),
event_callback_);
+
+ // This connect() method call should not return until the
+ // service is fully connected.
s.connect(response);
} else {
response.send_error(std::string("Connection already pending: ")