5 * Copyright (C) 2007-2010 Intel Corporation. All rights reserved.
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 as
9 * published by the Free Software Foundation.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
30 #define CONNMAN_API_SUBJECT_TO_CHANGE
31 #include <connman/plugin.h>
32 #include <connman/notifier.h>
33 #include <connman/dbus.h>
34 #include <connman/log.h>
36 #define PACRUNNER_SERVICE "org.pacrunner"
37 #define PACRUNNER_INTERFACE "org.pacrunner.Manager"
38 #define PACRUNNER_PATH "/org/pacrunner/manager"
40 #define DBUS_TIMEOUT 5000
42 static DBusConnection *connection;
44 static struct connman_service *default_service = NULL;
45 static char *current_config = NULL;
47 static void create_config_reply(DBusPendingCall *call, void *user_data)
49 DBusMessage *reply = dbus_pending_call_steal_reply(call);
54 if (dbus_message_get_type(reply) == DBUS_MESSAGE_TYPE_ERROR) {
55 connman_error("Failed to create proxy configuration");
59 if (dbus_message_get_args(reply, NULL, DBUS_TYPE_OBJECT_PATH, &path,
60 DBUS_TYPE_INVALID) == FALSE)
63 g_free(current_config);
64 current_config = g_strdup(path);
67 dbus_message_unref(reply);
70 static void add_dict_with_string_value(DBusMessageIter *iter,
71 const char *key, const char *str)
73 DBusMessageIter dict, entry, value;
75 dbus_message_iter_open_container(iter, DBUS_TYPE_ARRAY,
76 DBUS_DICT_ENTRY_BEGIN_CHAR_AS_STRING
77 DBUS_TYPE_STRING_AS_STRING DBUS_TYPE_VARIANT_AS_STRING
78 DBUS_DICT_ENTRY_END_CHAR_AS_STRING, &dict);
79 dbus_message_iter_open_container(&dict, DBUS_TYPE_DICT_ENTRY,
82 dbus_message_iter_append_basic(&entry, DBUS_TYPE_STRING, &key);
84 dbus_message_iter_open_container(&entry, DBUS_TYPE_VARIANT,
85 DBUS_TYPE_STRING_AS_STRING, &value);
86 dbus_message_iter_append_basic(&value, DBUS_TYPE_STRING, &str);
87 dbus_message_iter_close_container(&entry, &value);
89 dbus_message_iter_close_container(&dict, &entry);
90 dbus_message_iter_close_container(iter, &dict);
93 static void create_proxy_configuration(const char *url)
97 DBusPendingCall *call;
105 msg = dbus_message_new_method_call(PACRUNNER_SERVICE, PACRUNNER_PATH,
106 PACRUNNER_INTERFACE, "CreateProxyConfiguration");
110 dbus_message_set_auto_start(msg, FALSE);
112 dbus_message_iter_init_append(msg, &iter);
113 add_dict_with_string_value(&iter, "URL", url);
115 result = dbus_connection_send_with_reply(connection, msg,
116 &call, DBUS_TIMEOUT);
118 dbus_message_unref(msg);
120 if (result == FALSE || call == NULL)
123 dbus_pending_call_set_notify(call, create_config_reply, NULL, NULL);
125 dbus_pending_call_unref(call);
128 static void destroy_config_reply(DBusPendingCall *call, void *user_data)
130 DBusMessage *reply = dbus_pending_call_steal_reply(call);
134 if (dbus_message_get_type(reply) == DBUS_MESSAGE_TYPE_ERROR)
135 connman_error("Failed to destoy proxy configuration");
137 dbus_message_unref(reply);
140 static void destroy_proxy_configuration(void)
143 DBusPendingCall *call;
146 if (current_config == NULL)
151 msg = dbus_message_new_method_call(PACRUNNER_SERVICE, PACRUNNER_PATH,
152 PACRUNNER_INTERFACE, "DestroyProxyConfiguration");
156 dbus_message_set_auto_start(msg, FALSE);
158 dbus_message_append_args(msg, DBUS_TYPE_OBJECT_PATH, ¤t_config,
161 result = dbus_connection_send_with_reply(connection, msg,
162 &call, DBUS_TIMEOUT);
164 dbus_message_unref(msg);
166 if (result == FALSE || call == NULL)
169 dbus_pending_call_set_notify(call, destroy_config_reply, NULL, NULL);
171 dbus_pending_call_unref(call);
173 g_free(current_config);
174 current_config = NULL;
177 static void default_service_changed(struct connman_service *service)
181 DBG("service %p", service);
183 if (service == default_service)
186 default_service = service;
188 destroy_proxy_configuration();
190 url = connman_service_get_proxy_autoconfig(service);
191 create_proxy_configuration(url);
194 static struct connman_notifier pacrunner_notifier = {
196 .default_changed = default_service_changed,
199 static void pacrunner_connect(DBusConnection *conn, void *user_data)
205 url = connman_service_get_proxy_autoconfig(default_service);
206 create_proxy_configuration(url);
209 static void pacrunner_disconnect(DBusConnection *conn, void *user_data)
213 g_free(current_config);
214 current_config = NULL;
217 static guint pacrunner_watch;
219 static int pacrunner_init(void)
221 connection = connman_dbus_get_connection();
222 if (connection == NULL)
225 pacrunner_watch = g_dbus_add_service_watch(connection,
226 PACRUNNER_SERVICE, pacrunner_connect,
227 pacrunner_disconnect, NULL, NULL);
228 if (pacrunner_watch == 0) {
229 dbus_connection_unref(connection);
233 connman_notifier_register(&pacrunner_notifier);
238 static void pacrunner_exit(void)
240 connman_notifier_unregister(&pacrunner_notifier);
242 g_dbus_remove_watch(connection, pacrunner_watch);
244 destroy_proxy_configuration();
246 dbus_connection_unref(connection);
249 CONNMAN_PLUGIN_DEFINE(pacrunner, "PAC runner proxy plugin", VERSION,
250 CONNMAN_PLUGIN_PRIORITY_DEFAULT, pacrunner_init, pacrunner_exit)