]> git.ipfire.org Git - thirdparty/openembedded/openembedded-core-contrib.git/blob
98230525b6a803aa8ec91098e7490dcfa162971d
[thirdparty/openembedded/openembedded-core-contrib.git] /
1 From c742b40860851f1659e801d0a652f854f6783bd1 Mon Sep 17 00:00:00 2001
2 Message-Id: <c742b40860851f1659e801d0a652f854f6783bd1.1334369310.git.paul.eggleton@linux.intel.com>
3 In-Reply-To: <cover.1334369310.git.paul.eggleton@linux.intel.com>
4 References: <cover.1334369310.git.paul.eggleton@linux.intel.com>
5 From: Paul Eggleton <paul.eggleton@linux.intel.com>
6 Date: Sat, 14 Apr 2012 02:32:43 +0100
7 Subject: [PATCH 4/6] Handle WiFi authentication using an agent
8
9 Register an agent within the applet which shows an appropriate dialog
10 when credentials are requested upon connecting to a secured wireless
11 network.
12
13 Thanks to Julien Massot for providing the underlying agent library code.
14
15 Upstream-Status: Submitted
16
17 Signed-off-by: Paul Eggleton <paul.eggleton@linux.intel.com>
18 ---
19 applet/Makefile.am | 3 +-
20 applet/agent.c | 209 +++++++++++++++++++++++
21 applet/agent.h | 29 +++
22 applet/main.c | 3 +
23 common/Makefile.am | 13 +-
24 common/connman-agent.c | 426 ++++++++++++++++++++++++++++++++++++++++++++++
25 common/connman-agent.h | 77 +++++++++
26 common/connman-agent.xml | 26 +++
27 common/marshal.list | 2 +
28 9 files changed, 783 insertions(+), 5 deletions(-)
29 create mode 100644 applet/agent.c
30 create mode 100644 applet/agent.h
31 create mode 100644 common/connman-agent.c
32 create mode 100644 common/connman-agent.h
33 create mode 100644 common/connman-agent.xml
34
35 diff --git a/applet/Makefile.am b/applet/Makefile.am
36 index fe582ef..2e7c157 100644
37 --- a/applet/Makefile.am
38 +++ b/applet/Makefile.am
39 @@ -2,7 +2,8 @@
40 bin_PROGRAMS = connman-applet
41
42 connman_applet_SOURCES = main.c \
43 - properties.h properties.c status.h status.c
44 + properties.h properties.c status.h \
45 + status.c agent.h agent.c
46
47 connman_applet_LDADD = $(top_builddir)/common/libcommon.a \
48 @GTK_LIBS@ @DBUS_LIBS@
49 diff --git a/applet/agent.c b/applet/agent.c
50 new file mode 100644
51 index 0000000..b12d337
52 --- /dev/null
53 +++ b/applet/agent.c
54 @@ -0,0 +1,209 @@
55 +/*
56 + *
57 + * Connection Manager
58 + *
59 + * Agent implementation based on code from bluez-gnome
60 + *
61 + * Copyright (C) 2005-2008 Marcel Holtmann <marcel@holtmann.org>
62 + * Copyright (C) 2006-2007 Bastien Nocera <hadess@hadess.net>
63 + * Copyright (C) 2012 Intel Corporation
64 + *
65 + *
66 + * This program is free software; you can redistribute it and/or modify
67 + * it under the terms of the GNU General Public License as published by
68 + * the Free Software Foundation; either version 2 of the License, or
69 + * (at your option) any later version.
70 + *
71 + * This program is distributed in the hope that it will be useful,
72 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
73 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
74 + * GNU General Public License for more details.
75 + *
76 + * You should have received a copy of the GNU General Public License
77 + * along with this program; if not, write to the Free Software
78 + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
79 + *
80 + */
81 +
82 +#ifdef HAVE_CONFIG_H
83 +#include <config.h>
84 +#endif
85 +
86 +#include <stdlib.h>
87 +
88 +#include <glib/gi18n.h>
89 +#include <gtk/gtk.h>
90 +
91 +#include <dbus/dbus-glib.h>
92 +
93 +#include <connman-agent.h>
94 +
95 +#include "agent.h"
96 +
97 +struct input_data {
98 + gboolean numeric;
99 + gpointer request_data;
100 + GtkWidget *dialog;
101 + GHashTable *entries;
102 +};
103 +
104 +static struct input_data *input_data_inst = NULL;
105 +
106 +static void input_free(struct input_data *input)
107 +{
108 + gtk_widget_destroy(input->dialog);
109 +
110 + g_hash_table_destroy(input->entries);
111 +
112 + if( input_data_inst == input )
113 + input_data_inst = NULL;
114 +
115 + g_free(input);
116 +}
117 +
118 +static void request_input_callback(GtkWidget *dialog,
119 + gint response, gpointer user_data)
120 +{
121 + GHashTableIter iter;
122 + gpointer key, value;
123 + GValue *retvalue = NULL;
124 + const gchar *text;
125 + struct input_data *input = user_data;
126 +
127 + if (response == GTK_RESPONSE_OK) {
128 + GHashTable *reply = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, g_free);
129 + g_hash_table_iter_init (&iter, input->entries);
130 + while (g_hash_table_iter_next (&iter, &key, &value)) {
131 + text = gtk_entry_get_text((GtkEntry *)value);
132 + if(strlen(text)) {
133 + retvalue = g_slice_new0(GValue);
134 + g_value_init(retvalue, G_TYPE_STRING);
135 + g_value_set_string(retvalue, text);
136 + g_hash_table_insert(reply, g_strdup(key), retvalue);
137 + }
138 + }
139 +
140 + connman_agent_request_input_set_reply(input->request_data, reply);
141 + } else {
142 + connman_agent_request_input_abort(input->request_data);
143 + }
144 +
145 + input_free(input);
146 +}
147 +
148 +static void show_dialog(gpointer data, gpointer user_data)
149 +{
150 + struct input_data *input = data;
151 +
152 + gtk_widget_show_all(input->dialog);
153 +
154 + gtk_window_present(GTK_WINDOW(input->dialog));
155 +}
156 +
157 +static void request_input_dialog(GHashTable *request,
158 + gpointer request_data)
159 +{
160 + GtkWidget *dialog;
161 + GtkWidget *label;
162 + GtkWidget *table;
163 + GtkWidget *entry;
164 + struct input_data *input;
165 + GHashTableIter iter;
166 + gpointer key, value;
167 + int elems, i;
168 +
169 + input = g_try_malloc0(sizeof(*input));
170 + if (!input)
171 + return;
172 +
173 + input->request_data = request_data;
174 +
175 + input->entries = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, NULL);
176 +
177 + dialog = gtk_dialog_new();
178 + gtk_window_set_title(GTK_WINDOW(dialog), _("Connection Manager"));
179 + gtk_window_set_resizable(GTK_WINDOW(dialog), FALSE);
180 + gtk_window_set_position(GTK_WINDOW(dialog), GTK_WIN_POS_CENTER);
181 + gtk_window_set_keep_above(GTK_WINDOW(dialog), TRUE);
182 + gtk_window_set_urgency_hint(GTK_WINDOW(dialog), TRUE);
183 + gtk_dialog_set_has_separator(GTK_DIALOG(dialog), FALSE);
184 + input->dialog = dialog;
185 +
186 + gtk_dialog_add_button(GTK_DIALOG(dialog),
187 + GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL);
188 + gtk_dialog_add_button(GTK_DIALOG(dialog),
189 + GTK_STOCK_OK, GTK_RESPONSE_OK);
190 +
191 + elems = g_hash_table_size(request);
192 + table = gtk_table_new(elems+1, 2, FALSE);
193 + gtk_table_set_row_spacings(GTK_TABLE(table), 4);
194 + gtk_table_set_col_spacings(GTK_TABLE(table), 20);
195 + gtk_container_set_border_width(GTK_CONTAINER(table), 12);
196 + gtk_container_add(GTK_CONTAINER(GTK_DIALOG(dialog)->vbox), table);
197 +
198 + label = gtk_label_new(_("Please provide some network information:"));
199 + gtk_misc_set_alignment(GTK_MISC(label), 0.0, 0.0);
200 + gtk_table_attach(GTK_TABLE(table), label, 0, 2, 0, 1,
201 + GTK_EXPAND | GTK_FILL, GTK_SHRINK, 0, 0);
202 +
203 + g_hash_table_iter_init (&iter, request);
204 + i=1;
205 + while (g_hash_table_iter_next (&iter, &key, &value)) {
206 + label = gtk_label_new((const char *)key);
207 + gtk_misc_set_alignment(GTK_MISC(label), 0.0, 0.0);
208 + gtk_table_attach(GTK_TABLE(table), label, 0, 1, i, i+1,
209 + GTK_EXPAND | GTK_FILL, GTK_SHRINK, 0, 0);
210 +
211 + entry = gtk_entry_new();
212 + gtk_entry_set_max_length(GTK_ENTRY(entry), 64);
213 + gtk_entry_set_width_chars(GTK_ENTRY(entry), 16);
214 + gtk_entry_set_visibility(GTK_ENTRY(entry), FALSE);
215 + gtk_table_attach(GTK_TABLE(table), entry, 1, 2, i, i+1,
216 + GTK_EXPAND | GTK_FILL, GTK_SHRINK, 0, 0);
217 + g_hash_table_insert(input->entries, g_strdup(key), entry);
218 +
219 + i++;
220 + }
221 +
222 + input_data_inst = input;
223 +
224 + g_signal_connect(G_OBJECT(dialog), "response",
225 + G_CALLBACK(request_input_callback), input);
226 +
227 + show_dialog(input, NULL);
228 +}
229 +
230 +static void request_input(const char *service_id,
231 + GHashTable *request, gpointer request_data, gpointer user_data)
232 +{
233 + request_input_dialog(request, request_data);
234 +}
235 +
236 +static gboolean cancel_request(DBusGMethodInvocation *context,
237 + gpointer user_data)
238 +{
239 + if( input_data_inst ) {
240 + connman_agent_request_input_abort(input_data_inst->request_data);
241 +
242 + input_free(input_data_inst);
243 + }
244 +
245 + return TRUE;
246 +}
247 +
248 +int setup_agents(void)
249 +{
250 + ConnmanAgent *agent = connman_agent_new();
251 + connman_agent_setup(agent, "/org/gnome/connman/applet");
252 +
253 + connman_agent_set_request_input_func(agent, request_input, agent);
254 + connman_agent_set_cancel_func(agent, cancel_request, agent);
255 +
256 + connman_agent_register(agent);
257 +
258 + return 0;
259 +}
260 +
261 +void cleanup_agents(void)
262 +{
263 +}
264 diff --git a/applet/agent.h b/applet/agent.h
265 new file mode 100644
266 index 0000000..d85676b
267 --- /dev/null
268 +++ b/applet/agent.h
269 @@ -0,0 +1,29 @@
270 +/*
271 + *
272 + * Connection Manager
273 + *
274 + * Agent implementation based on code from bluez-gnome
275 + *
276 + * Copyright (C) 2005-2008 Marcel Holtmann <marcel@holtmann.org>
277 + * Copyright (C) 2006-2007 Bastien Nocera <hadess@hadess.net>
278 + * Copyright (C) 2012 Intel Corporation
279 + *
280 + *
281 + * This program is free software; you can redistribute it and/or modify
282 + * it under the terms of the GNU General Public License as published by
283 + * the Free Software Foundation; either version 2 of the License, or
284 + * (at your option) any later version.
285 + *
286 + * This program is distributed in the hope that it will be useful,
287 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
288 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
289 + * GNU General Public License for more details.
290 + *
291 + * You should have received a copy of the GNU General Public License
292 + * along with this program; if not, write to the Free Software
293 + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
294 + *
295 + */
296 +
297 +int setup_agents(void);
298 +void cleanup_agents(void);
299 diff --git a/applet/main.c b/applet/main.c
300 index 68a77b1..d06ce60 100644
301 --- a/applet/main.c
302 +++ b/applet/main.c
303 @@ -32,6 +32,7 @@
304
305 #include "properties.h"
306 #include "status.h"
307 +#include "agent.h"
308
309 static gboolean global_ready = FALSE;
310 static gint global_strength = -1;
311 @@ -132,6 +133,7 @@ static void manager_init(DBusGConnection *connection)
312 "/", "net.connman.Manager");
313
314 properties_create(manager, manager_property_changed, NULL);
315 + setup_agents();
316 }
317
318 static void manager_cleanup(void)
319 @@ -148,6 +150,7 @@ static void name_owner_changed(DBusGProxy *proxy, const char *name,
320 if (*new != '\0') {
321 status_offline();
322 properties_enable(manager);
323 + setup_agents();
324 } else {
325 properties_disable(manager);
326 status_unavailable();
327 diff --git a/common/Makefile.am b/common/Makefile.am
328 index ef1267a..5bfff19 100644
329 --- a/common/Makefile.am
330 +++ b/common/Makefile.am
331 @@ -3,19 +3,21 @@ noinst_LIBRARIES = libcommon.a
332
333 libcommon_a_SOURCES = connman-dbus.c connman-dbus.h connman-dbus-glue.h \
334 connman-client.h connman-client.c \
335 - instance.h instance.c
336 + instance.h instance.c \
337 + connman-agent.h connman-agent.c
338
339 BUILT_SOURCES = marshal.h marshal.c \
340 connman-dbus-glue.h \
341 - instance-glue.h
342 + instance-glue.h \
343 + connman-agent-glue.h
344
345 -nodist_libcommon_a_SOURCES = connman-dbus-glue.h instance-glue.h
346 +nodist_libcommon_a_SOURCES = connman-dbus-glue.h instance-glue.h connman-agent-glue.h
347
348 CLEANFILES = $(BUILT_SOURCES)
349
350 AM_CFLAGS = @DBUS_CFLAGS@ @GTK_CFLAGS@
351
352 -EXTRA_DIST = marshal.list instance.xml connman-dbus.xml
353 +EXTRA_DIST = marshal.list instance.xml connman-dbus.xml connman-agent.xml
354
355 MAINTAINERCLEANFILES = Makefile.in
356
357 @@ -30,3 +32,6 @@ instance-glue.h: instance.xml
358
359 connman-dbus-glue.h: connman-dbus.xml
360 $(DBUS_BINDING_TOOL) --prefix=connman --mode=glib-client --output=$@ $<
361 +
362 +connman-agent-glue.h: connman-agent.xml
363 + $(DBUS_BINDING_TOOL) --prefix=connman_agent --mode=glib-server --output=$@ $<
364 diff --git a/common/connman-agent.c b/common/connman-agent.c
365 new file mode 100644
366 index 0000000..769bf27
367 --- /dev/null
368 +++ b/common/connman-agent.c
369 @@ -0,0 +1,426 @@
370 +/*
371 + * Connection Manager Agent implementation
372 + *
373 + * Author(s):
374 + * - Julien MASSOT <jmassot@aldebaran-robotics.com>
375 + * - Paul Eggleton <paul.eggleton@linux.intel.com>
376 + *
377 + * Copyright (C) 2012 Aldebaran Robotics
378 + * Copyright (C) 2012 Intel Corporation
379 + *
380 + * This library is free software; you can redistribute it and/or
381 + * modify it under the terms of the GNU Lesser General Public
382 + * License version 2.1 as published by the Free Software Foundation.
383 + *
384 + * This library is distributed in the hope that it will be useful,
385 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
386 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
387 + * Lesser General Public License for more details.
388 + *
389 + * You should have received a copy of the GNU Lesser General Public
390 + * License along with this library; if not, write to the Free Software
391 + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
392 + */
393 +
394 +#include <dbus/dbus-glib.h>
395 +#include <dbus/dbus-glib-lowlevel.h>
396 +#include <stdio.h>
397 +
398 +#include "connman-agent.h"
399 +#include "connman-dbus.h"
400 +
401 +#define CONNMAN_AGENT_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE((obj), \
402 + CONNMAN_TYPE_AGENT, ConnmanAgentPrivate))
403 +
404 +typedef enum {
405 + AGENT_ERROR_REJECT,
406 + AGENT_ERROR_RETRY
407 +} AgentError;
408 +
409 +#define AGENT_ERROR (agent_error_quark())
410 +
411 +#define AGENT_ERROR_TYPE (agent_error_get_type())
412 +
413 +static GQuark agent_error_quark(void)
414 +{
415 + static GQuark quark = 0;
416 + if (!quark)
417 + quark = g_quark_from_static_string("Agent");
418 +
419 + return quark;
420 +}
421 +
422 +#define ENUM_ENTRY(NAME, DESC) { NAME, "" #NAME "", DESC }
423 +
424 +static GType agent_error_get_type(void)
425 +{
426 + static GType etype = 0;
427 + if (etype == 0) {
428 + static const GEnumValue values[] = {
429 + ENUM_ENTRY(AGENT_ERROR_REJECT, "Rejected"),
430 + ENUM_ENTRY(AGENT_ERROR_RETRY, "Retry"),
431 + { 0, 0, 0 }
432 + };
433 +
434 + etype = g_enum_register_static("Agent", values);
435 + }
436 +
437 + return etype;
438 +}
439 +
440 +typedef struct _ConnmanAgentPrivate ConnmanAgentPrivate;
441 +
442 +typedef struct _PendingRequest PendingRequest;
443 +
444 +struct _PendingRequest {
445 + DBusGMethodInvocation *context;
446 + ConnmanAgent *agent;
447 +};
448 +
449 +struct _ConnmanAgentPrivate {
450 + gchar *busname;
451 + gchar *path;
452 + DBusGConnection *connection;
453 + DBusGProxy *connman_proxy;
454 +
455 + ConnmanAgentRequestInputFunc input_func;
456 + gpointer input_data;
457 +
458 + ConnmanAgentCancelFunc cancel_func;
459 + gpointer cancel_data;
460 +
461 + ConnmanAgentReleaseFunc release_func;
462 + gpointer release_data;
463 +
464 + ConnmanAgentDebugFunc debug_func;
465 + gpointer debug_data;
466 +
467 +};
468 +
469 +G_DEFINE_TYPE(ConnmanAgent, connman_agent, G_TYPE_OBJECT)
470 +
471 +static inline void debug(ConnmanAgent *agent, const char *format, ...)
472 +{
473 + char str[256];
474 + va_list ap;
475 + ConnmanAgentPrivate *priv = CONNMAN_AGENT_GET_PRIVATE(agent);
476 +
477 + if (priv->debug_func == NULL)
478 + return;
479 +
480 + va_start(ap, format);
481 +
482 + if (vsnprintf(str, sizeof(str), format, ap) > 0)
483 + priv->debug_func(str, priv->debug_data);
484 +
485 + va_end(ap);
486 +}
487 +
488 +gboolean connman_agent_request_input_set_reply(gpointer request_data, GHashTable *reply)
489 +{
490 + PendingRequest *pendingrequest = request_data;
491 +
492 + if (request_data == NULL)
493 + return FALSE;
494 +
495 + dbus_g_method_return(pendingrequest->context, reply);
496 +
497 + g_free(pendingrequest);
498 +
499 + return FALSE;
500 +}
501 +
502 +gboolean connman_agent_request_input_abort(gpointer request_data)
503 +{
504 + PendingRequest *pendingrequest = request_data;
505 + GError *result;
506 + if (request_data == NULL)
507 + return FALSE;
508 +
509 + result = g_error_new(AGENT_ERROR, AGENT_ERROR_REJECT,
510 + "Input request rejected");
511 + dbus_g_method_return_error(pendingrequest->context, result);
512 + g_clear_error(&result);
513 + g_free(pendingrequest);
514 +
515 + return FALSE;
516 +}
517 +
518 +static gboolean connman_agent_request_input_cb(const GHashTable *reply, gpointer user_data)
519 +{
520 +
521 + PendingRequest *pendingrequest = user_data;
522 +
523 + dbus_g_method_return(pendingrequest->context, reply);
524 +
525 + g_free(pendingrequest);
526 + return FALSE;
527 +}
528 +
529 +gboolean connman_agent_report_error(ConnmanAgent *agent,
530 + const char *path, const char *error,
531 + DBusGMethodInvocation *context)
532 +{
533 + GError *result;
534 + ConnmanAgentPrivate *priv = CONNMAN_AGENT_GET_PRIVATE(agent);
535 +
536 + debug(agent, "connection %s, reports an error: %s", path, error);
537 + result = g_error_new(AGENT_ERROR, AGENT_ERROR_RETRY,
538 + "Retry");
539 + dbus_g_method_return_error(context, result);
540 + g_clear_error(&result);
541 +
542 + return FALSE;
543 +}
544 +
545 +gboolean connman_agent_request_input(ConnmanAgent *agent,
546 + const char *path, GHashTable *fields,
547 + DBusGMethodInvocation *context)
548 +{
549 + ConnmanAgentPrivate *priv = CONNMAN_AGENT_GET_PRIVATE(agent);
550 + const char *sender = dbus_g_method_get_sender(context);
551 + char *name = NULL, *type = NULL;
552 + char **id = NULL;
553 + PendingRequest *pendingrequest = NULL;
554 +
555 + debug(agent, "request %s, sender %s", path, sender);
556 +
557 + if (fields == NULL)
558 + return FALSE;
559 +
560 + if (priv->input_func != NULL) {
561 + id = g_strsplit(path, "/net/connman/service/", 2);
562 + if (g_strv_length(id) == 2) {
563 + pendingrequest = g_try_new0(PendingRequest, 1);
564 + pendingrequest->context = context;
565 + pendingrequest->agent = agent;
566 + priv->input_func(id[1], fields, pendingrequest, priv->input_data);
567 + }
568 + g_strfreev(id);
569 + }
570 +
571 + return FALSE;
572 +}
573 +
574 +gboolean connman_agent_cancel(ConnmanAgent *agent,
575 + DBusGMethodInvocation *context)
576 +{
577 + ConnmanAgentPrivate *priv = CONNMAN_AGENT_GET_PRIVATE(agent);
578 + const char *sender = dbus_g_method_get_sender(context);
579 + gboolean result = FALSE;
580 +
581 + debug(agent, "Request Canceled %s", sender);
582 +
583 + if (g_str_equal(sender, priv->busname) == FALSE)
584 + return FALSE;
585 +
586 + if (priv->cancel_func)
587 + result = priv->cancel_func(context, priv->cancel_data);
588 +
589 + return result;
590 +}
591 +
592 +gboolean connman_agent_release(ConnmanAgent *agent,
593 + DBusGMethodInvocation *context)
594 +{
595 + ConnmanAgentPrivate *priv = CONNMAN_AGENT_GET_PRIVATE(agent);
596 + const char *sender = dbus_g_method_get_sender(context);
597 +
598 + debug(agent, "agent %p sender %s", agent, sender);
599 +
600 + if (g_str_equal(sender, priv->busname) == FALSE)
601 + return FALSE;
602 +
603 + dbus_g_method_return(context);
604 +
605 + return TRUE;
606 +}
607 +
608 +#include "connman-agent-glue.h"
609 +
610 +static void connman_agent_init(ConnmanAgent *agent)
611 +{
612 + debug(agent, "agent %p", agent);
613 +}
614 +
615 +static void connman_agent_finalize(GObject *agent)
616 +{
617 + ConnmanAgentPrivate *priv = CONNMAN_AGENT_GET_PRIVATE(agent);
618 +
619 + if (priv->connman_proxy != NULL) {
620 + g_object_unref(priv->connman_proxy);
621 + }
622 +
623 + g_free(priv->path);
624 + g_free(priv->busname);
625 + dbus_g_connection_unref(priv->connection);
626 +
627 + G_OBJECT_CLASS(connman_agent_parent_class)->finalize(agent);
628 +}
629 +
630 +static void connman_agent_class_init(ConnmanAgentClass *klass)
631 +{
632 + GObjectClass *object_class = (GObjectClass *) klass;
633 +
634 + g_type_class_add_private(klass, sizeof(ConnmanAgentPrivate));
635 +
636 + object_class->finalize = connman_agent_finalize;
637 +
638 + dbus_g_object_type_install_info(CONNMAN_TYPE_AGENT,
639 + &dbus_glib_connman_agent_object_info);
640 +}
641 +
642 +ConnmanAgent *connman_agent_new(void)
643 +{
644 + ConnmanAgent *agent;
645 + g_type_init();
646 +
647 + agent = CONNMAN_AGENT(g_object_new(CONNMAN_TYPE_AGENT, NULL));
648 +
649 + return agent;
650 +}
651 +
652 +gboolean connman_agent_setup(ConnmanAgent *agent, const char *path)
653 +{
654 + ConnmanAgentPrivate *priv = CONNMAN_AGENT_GET_PRIVATE(agent);
655 + DBusGProxy *proxy;
656 + GObject *object;
657 + GError *error = NULL;
658 +
659 + debug(agent, "agent_setup %p", agent);
660 +
661 + if (priv->path != NULL)
662 + return FALSE;
663 +
664 + priv->path = g_strdup(path);
665 + priv->connection = dbus_g_bus_get(DBUS_BUS_SYSTEM, &error);
666 + if (error != NULL) {
667 + g_printerr("Connecting to system bus failed: %s\n",
668 + error->message);
669 + g_error_free(error);
670 + return FALSE;
671 + }
672 +
673 + proxy = dbus_g_proxy_new_for_name_owner(priv->connection, CONNMAN_SERVICE,
674 + CONNMAN_MANAGER_PATH, CONNMAN_MANAGER_INTERFACE, NULL);
675 +
676 + g_free(priv->busname);
677 +
678 + if (proxy != NULL) {
679 + priv->busname = g_strdup(dbus_g_proxy_get_bus_name(proxy));
680 + g_object_unref(proxy);
681 + } else
682 + priv->busname = NULL;
683 +
684 + object = dbus_g_connection_lookup_g_object(priv->connection, priv->path);
685 + if (object != NULL)
686 + g_object_unref(object);
687 +
688 + return TRUE;
689 +}
690 +
691 +
692 +gboolean connman_agent_register(ConnmanAgent *agent)
693 +{
694 + ConnmanAgentPrivate *priv = CONNMAN_AGENT_GET_PRIVATE(agent);
695 + DBusGProxy *proxy;
696 + GObject *object;
697 + GError *error = NULL;
698 + gchar *path;
699 +
700 + debug(agent, "register agent %p", agent);
701 +
702 + if (priv->connman_proxy != NULL)
703 + return FALSE;
704 +
705 + priv->connman_proxy = dbus_g_proxy_new_for_name_owner(priv->connection, CONNMAN_SERVICE,
706 + CONNMAN_MANAGER_PATH, CONNMAN_MANAGER_INTERFACE, NULL);
707 +
708 + g_free(priv->busname);
709 +
710 + priv->busname = g_strdup(dbus_g_proxy_get_bus_name(priv->connman_proxy));
711 +
712 + object = dbus_g_connection_lookup_g_object(priv->connection, priv->path);
713 + if (object != NULL)
714 + g_object_unref(object);
715 +
716 + dbus_g_connection_register_g_object(priv->connection,
717 + priv->path, G_OBJECT(agent));
718 +
719 + dbus_g_proxy_call(priv->connman_proxy, "RegisterAgent", &error,
720 + DBUS_TYPE_G_OBJECT_PATH, priv->path,
721 + G_TYPE_INVALID, G_TYPE_INVALID);
722 +
723 + if (error != NULL) {
724 + g_printerr("Agent registration failed: %s\n",
725 + error->message);
726 + g_error_free(error);
727 + return FALSE;
728 + }
729 +
730 + return TRUE;
731 +}
732 +
733 +gboolean connman_agent_unregister(ConnmanAgent *agent)
734 +{
735 + ConnmanAgentPrivate *priv = CONNMAN_AGENT_GET_PRIVATE(agent);
736 + GError *error = NULL;
737 +
738 + debug(agent, "unregister agent %p", agent);
739 +
740 + if (priv->connman_proxy == NULL)
741 + return FALSE;
742 +
743 + dbus_g_proxy_call(priv->connman_proxy, "UnregisterAgent", &error,
744 + DBUS_TYPE_G_OBJECT_PATH, priv->path,
745 + G_TYPE_INVALID, G_TYPE_INVALID);
746 +
747 + if (error != NULL) {
748 + g_printerr("Agent unregistration failed: %s\n",
749 + error->message);
750 + g_error_free(error);
751 + }
752 +
753 + g_object_unref(priv->connman_proxy);
754 + priv->connman_proxy = NULL;
755 +
756 + g_free(priv->path);
757 + priv->path = NULL;
758 +
759 + return TRUE;
760 +}
761 +
762 +void connman_agent_set_request_input_func(ConnmanAgent *agent,
763 + ConnmanAgentRequestInputFunc func, gpointer data)
764 +{
765 + ConnmanAgentPrivate *priv = CONNMAN_AGENT_GET_PRIVATE(agent);
766 +
767 + priv->input_func = func;
768 + priv->input_data = data;
769 +}
770 +
771 +void connman_agent_set_cancel_func(ConnmanAgent *agent,
772 + ConnmanAgentCancelFunc func, gpointer data)
773 +{
774 + ConnmanAgentPrivate *priv = CONNMAN_AGENT_GET_PRIVATE(agent);
775 +
776 + priv->cancel_func = func;
777 + priv->cancel_data = data;
778 +}
779 +
780 +void connman_agent_set_release_func(ConnmanAgent *agent,
781 + ConnmanAgentReleaseFunc func, gpointer data)
782 +{
783 + ConnmanAgentPrivate *priv = CONNMAN_AGENT_GET_PRIVATE(agent);
784 +
785 + priv->release_func = func;
786 + priv->release_data = data;
787 +}
788 +
789 +void connman_agent_set_debug_func(ConnmanAgent *agent, ConnmanAgentDebugFunc func, gpointer data)
790 +{
791 + ConnmanAgentPrivate *priv = CONNMAN_AGENT_GET_PRIVATE(agent);
792 +
793 + priv->debug_func = func;
794 + priv->debug_data = data;
795 +}
796 diff --git a/common/connman-agent.h b/common/connman-agent.h
797 new file mode 100644
798 index 0000000..0a1aa92
799 --- /dev/null
800 +++ b/common/connman-agent.h
801 @@ -0,0 +1,77 @@
802 +/*
803 + * Connection Manager Agent implementation
804 + *
805 + * Author(s):
806 + * - Julien MASSOT <jmassot@aldebaran-robotics.com>
807 + * - Paul Eggleton <paul.eggleton@linux.intel.com>
808 + *
809 + * Copyright (C) 2012 Aldebaran Robotics
810 + * Copyright (C) 2012 Intel Corporation
811 + *
812 + * This library is free software; you can redistribute it and/or
813 + * modify it under the terms of the GNU Lesser General Public
814 + * License version 2.1 as published by the Free Software Foundation.
815 + *
816 + * This library is distributed in the hope that it will be useful,
817 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
818 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
819 + * Lesser General Public License for more details.
820 + *
821 + * You should have received a copy of the GNU Lesser General Public
822 + * License along with this library; if not, write to the Free Software
823 + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
824 + */
825 +
826 +#ifndef CONNMAN_AGENT_H_
827 +# define CONNMAN_AGENT_H_
828 +
829 +#include <glib-object.h>
830 +#include <dbus/dbus-glib.h>
831 +
832 +G_BEGIN_DECLS
833 +
834 +#define CONNMAN_TYPE_AGENT (connman_agent_get_type())
835 +#define CONNMAN_AGENT(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), \
836 + CONNMAN_TYPE_AGENT, ConnmanAgent))
837 +#define CONNMAN_AGENT_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), \
838 + CONNMAN_TYPE_AGENT, ConnmanAgentClass))
839 +#define CONNMAN_IS_AGENT(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), \
840 + CONNMAN_TYPE_AGENT))
841 +#define CONNMAN_IS_AGENT_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), \
842 + CONNMAN_TYPE_AGENT))
843 +#define CONNMAN_GET_AGENT_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), \
844 + CONNMAN_TYPE_AGENT, ConnmanAgentClass))
845 +
846 +typedef struct _ConnmanAgent ConnmanAgent;
847 +typedef struct _ConnmanAgentClass ConnmanAgentClass;
848 +
849 +struct _ConnmanAgent {
850 + GObject parent;
851 +};
852 +
853 +struct _ConnmanAgentClass {
854 + GObjectClass parent_class;
855 +};
856 +
857 +GType connman_agent_get_type(void);
858 +
859 +ConnmanAgent *connman_agent_new(void);
860 +
861 +gboolean connman_agent_setup(ConnmanAgent *agent, const char *path);
862 +
863 +gboolean connman_agent_register(ConnmanAgent *agent);
864 +gboolean connman_agent_unregister(ConnmanAgent *agent);
865 +gboolean connman_agent_request_input_set_reply(gpointer request_data, GHashTable *reply);
866 +gboolean connman_agent_request_input_abort(gpointer request_data);
867 +
868 +typedef void (*ConnmanAgentRequestInputFunc) (const char *service_id, GHashTable *request, gpointer request_data, gpointer user_data);
869 +typedef gboolean (*ConnmanAgentCancelFunc) (DBusGMethodInvocation *context, gpointer data);
870 +typedef gboolean (*ConnmanAgentReleaseFunc) (DBusGMethodInvocation *context, gpointer data);
871 +typedef void (*ConnmanAgentDebugFunc) (const char *str, gpointer user_data);
872 +
873 +void connman_agent_set_request_input_func(ConnmanAgent *agent, ConnmanAgentRequestInputFunc func, gpointer data);
874 +void connman_agent_set_cancel_func(ConnmanAgent *agent, ConnmanAgentCancelFunc func, gpointer data);
875 +void connman_agent_set_debug_func(ConnmanAgent *agent, ConnmanAgentDebugFunc func, gpointer data);
876 +
877 +G_END_DECLS
878 +#endif /* !CONNMAN_AGENT_H_ */
879 diff --git a/common/connman-agent.xml b/common/connman-agent.xml
880 new file mode 100644
881 index 0000000..ed9ee8b
882 --- /dev/null
883 +++ b/common/connman-agent.xml
884 @@ -0,0 +1,26 @@
885 +<?xml version="1.0" encoding="UTF-8" ?>
886 +
887 +<node name="/net/connman/Agent">
888 + <interface name="net.connman.Agent">
889 + <method name="ReportError">
890 + <annotation name="org.freedesktop.DBus.GLib.Async" value="true"/>
891 + <arg type="o" direction="in"/>
892 + <arg type="s" direction="in"/>
893 + </method>
894 +
895 + <method name="RequestInput">
896 + <annotation name="org.freedesktop.DBus.GLib.Async" value="true"/>
897 + <arg type="o" direction="in"/>
898 + <arg type="a{sv}" direction="in"/>
899 + <arg type="a{sv}" direction="out"/>
900 + </method>
901 +
902 + <method name="Cancel">
903 + <annotation name="org.freedesktop.DBus.GLib.Async" value=""/>
904 + </method>
905 +
906 + <method name="Release">
907 + <annotation name="org.freedesktop.DBus.GLib.Async" value=""/>
908 + </method>
909 + </interface>
910 +</node>
911 diff --git a/common/marshal.list b/common/marshal.list
912 index 8b174d0..3c6317b 100644
913 --- a/common/marshal.list
914 +++ b/common/marshal.list
915 @@ -1,3 +1,5 @@
916 VOID:STRING,BOXED
917 +VOID:OBJECT,BOXED
918 +VOID:OBJECT
919 VOID:BOXED
920 VOID:STRING
921 --
922 1.7.5.4
923