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;
43 static dbus_bool_t daemon_running = FALSE;
45 static struct connman_service *default_service = NULL;
46 static char *current_config = NULL;
48 static void create_config_reply(DBusPendingCall *call, void *user_data)
50 DBusMessage *reply = dbus_pending_call_steal_reply(call);
55 if (dbus_message_get_type(reply) == DBUS_MESSAGE_TYPE_ERROR) {
56 connman_error("Failed to create proxy configuration");
60 if (dbus_message_get_args(reply, NULL, DBUS_TYPE_OBJECT_PATH, &path,
61 DBUS_TYPE_INVALID) == FALSE)
64 g_free(current_config);
65 current_config = g_strdup(path);
68 dbus_message_unref(reply);
71 static void append_string(DBusMessageIter *iter, void *user_data)
73 dbus_message_iter_append_basic(iter, DBUS_TYPE_STRING, user_data);
76 static void create_proxy_configuration(void)
79 DBusMessageIter iter, dict;
80 DBusPendingCall *call;
85 if (default_service == NULL)
90 msg = dbus_message_new_method_call(PACRUNNER_SERVICE, PACRUNNER_PATH,
91 PACRUNNER_INTERFACE, "CreateProxyConfiguration");
95 dbus_message_set_auto_start(msg, FALSE);
97 dbus_message_iter_init_append(msg, &iter);
98 connman_dbus_dict_open(&iter, &dict);
100 interface = connman_service_get_interface(default_service);
101 if (interface != NULL) {
102 connman_dbus_dict_append_basic(&dict, "Interface",
103 DBUS_TYPE_STRING, &interface);
107 str = connman_service_get_proxy_autoconfig(default_service);
109 const char *method = "auto";
110 connman_dbus_dict_append_basic(&dict, "Method",
111 DBUS_TYPE_STRING, &method);
112 connman_dbus_dict_append_basic(&dict, "URL",
113 DBUS_TYPE_STRING, &str);
115 const char *method = "direct";
116 connman_dbus_dict_append_basic(&dict, "Method",
117 DBUS_TYPE_STRING, &method);
120 str = connman_service_get_domainname(default_service);
122 connman_dbus_dict_append_array(&dict, "Domains",
123 DBUS_TYPE_STRING, append_string, &str);
125 str = connman_service_get_nameserver(default_service);
127 connman_dbus_dict_append_array(&dict, "Nameservers",
128 DBUS_TYPE_STRING, append_string, &str);
130 connman_dbus_dict_close(&iter, &dict);
132 result = dbus_connection_send_with_reply(connection, msg,
133 &call, DBUS_TIMEOUT);
135 dbus_message_unref(msg);
137 if (result == FALSE || call == NULL)
140 dbus_pending_call_set_notify(call, create_config_reply, NULL, NULL);
142 dbus_pending_call_unref(call);
145 static void destroy_config_reply(DBusPendingCall *call, void *user_data)
147 DBusMessage *reply = dbus_pending_call_steal_reply(call);
151 if (dbus_message_get_type(reply) == DBUS_MESSAGE_TYPE_ERROR)
152 connman_error("Failed to destoy proxy configuration");
154 dbus_message_unref(reply);
157 static void destroy_proxy_configuration(void)
160 DBusPendingCall *call;
163 if (current_config == NULL)
168 msg = dbus_message_new_method_call(PACRUNNER_SERVICE, PACRUNNER_PATH,
169 PACRUNNER_INTERFACE, "DestroyProxyConfiguration");
173 dbus_message_set_auto_start(msg, FALSE);
175 dbus_message_append_args(msg, DBUS_TYPE_OBJECT_PATH, ¤t_config,
178 result = dbus_connection_send_with_reply(connection, msg,
179 &call, DBUS_TIMEOUT);
181 dbus_message_unref(msg);
183 if (result == FALSE || call == NULL)
186 dbus_pending_call_set_notify(call, destroy_config_reply, NULL, NULL);
188 dbus_pending_call_unref(call);
190 g_free(current_config);
191 current_config = NULL;
194 static void default_service_changed(struct connman_service *service)
196 DBG("service %p", service);
198 if (service == default_service)
201 default_service = service;
203 if (daemon_running == FALSE)
206 destroy_proxy_configuration();
208 create_proxy_configuration();
211 static struct connman_notifier pacrunner_notifier = {
213 .default_changed = default_service_changed,
216 static void pacrunner_connect(DBusConnection *conn, void *user_data)
220 daemon_running = TRUE;
222 create_proxy_configuration();
225 static void pacrunner_disconnect(DBusConnection *conn, void *user_data)
229 daemon_running = FALSE;
231 g_free(current_config);
232 current_config = NULL;
235 static guint pacrunner_watch;
237 static int pacrunner_init(void)
239 connection = connman_dbus_get_connection();
240 if (connection == NULL)
243 pacrunner_watch = g_dbus_add_service_watch(connection,
244 PACRUNNER_SERVICE, pacrunner_connect,
245 pacrunner_disconnect, NULL, NULL);
246 if (pacrunner_watch == 0) {
247 dbus_connection_unref(connection);
251 connman_notifier_register(&pacrunner_notifier);
256 static void pacrunner_exit(void)
258 connman_notifier_unregister(&pacrunner_notifier);
260 g_dbus_remove_watch(connection, pacrunner_watch);
262 destroy_proxy_configuration();
264 dbus_connection_unref(connection);
267 CONNMAN_PLUGIN_DEFINE(pacrunner, "PAC runner proxy plugin", VERSION,
268 CONNMAN_PLUGIN_PRIORITY_DEFAULT, pacrunner_init, pacrunner_exit)