ofono: Merge context_set_in/active()
[framework/connectivity/connman.git] / plugins / nmcompat.c
1 /*
2  *
3  *  Connection Manager
4  *
5  *  Copyright (C) 2007-2010  Intel Corporation. All rights reserved.
6  *
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.
10  *
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.
15  *
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
19  *
20  */
21
22 #ifdef HAVE_CONFIG_H
23 #include <config.h>
24 #endif
25
26 #include <gdbus.h>
27
28 #define CONNMAN_API_SUBJECT_TO_CHANGE
29 #include <connman/plugin.h>
30 #include <connman/log.h>
31 #include <connman/notifier.h>
32 #include <connman/dbus.h>
33
34 enum {
35         NM_STATE_UNKNOWN          = 0,
36         NM_STATE_ASLEEP           = 10,
37         NM_STATE_DISCONNECTED     = 20,
38         NM_STATE_DISCONNECTING    = 30,
39         NM_STATE_CONNECTING       = 40,
40         NM_STATE_CONNECTED_LOCAL  = 50,
41         NM_STATE_CONNECTED_SITE   = 60,
42         NM_STATE_CONNECTED_GLOBAL = 70
43 };
44
45 #define NM_STATE_CONNECTED NM_STATE_CONNECTED_GLOBAL
46
47 #define NM_SERVICE    "org.freedesktop.NetworkManager"
48 #define NM_PATH       "/org/freedesktop/NetworkManager"
49 #define NM_INTERFACE  NM_SERVICE
50
51 #define DBUS_PROPERTIES_INTERFACE       "org.freedesktop.DBus.Properties"
52
53 static DBusConnection *connection = NULL;
54 static dbus_uint32_t state = NM_STATE_UNKNOWN;
55
56 static void state_changed(dbus_uint32_t state)
57 {
58         DBusMessage *signal;
59
60         signal = dbus_message_new_signal(NM_PATH, NM_INTERFACE,
61                                                 "StateChanged");
62         if (signal == NULL)
63                 return;
64
65         dbus_message_append_args(signal, DBUS_TYPE_UINT32, &state,
66                                 DBUS_TYPE_INVALID);
67
68         g_dbus_send_message(connection, signal);
69 }
70
71 static void properties_changed(dbus_uint32_t state)
72 {
73         const char *key = "State";
74         DBusMessageIter iter, dict, dict_entry, dict_val;
75         DBusMessage *signal;
76
77         signal = dbus_message_new_signal(NM_PATH, NM_INTERFACE,
78                                                 "PropertiesChanged");
79         if (signal == NULL)
80                 return;
81
82         dbus_message_iter_init_append(signal, &iter);
83
84         dbus_message_iter_open_container(&iter, DBUS_TYPE_ARRAY,
85                                         DBUS_DICT_ENTRY_BEGIN_CHAR_AS_STRING
86                                         DBUS_TYPE_STRING_AS_STRING
87                                         DBUS_TYPE_VARIANT_AS_STRING
88                                         DBUS_DICT_ENTRY_END_CHAR_AS_STRING,
89                                         &dict);
90
91         dbus_message_iter_open_container(&dict, DBUS_TYPE_DICT_ENTRY,
92                                                         NULL, &dict_entry);
93
94         dbus_message_iter_append_basic(&dict_entry, DBUS_TYPE_STRING, &key);
95
96         dbus_message_iter_open_container(&dict_entry, DBUS_TYPE_VARIANT,
97                                         DBUS_TYPE_UINT32_AS_STRING, &dict_val);
98
99         dbus_message_iter_append_basic(&dict_val, DBUS_TYPE_UINT32, &state);
100
101         dbus_message_iter_close_container(&dict_entry, &dict_val);
102         dbus_message_iter_close_container(&dict, &dict_entry);
103         dbus_message_iter_close_container(&iter, &dict);
104
105         g_dbus_send_message(connection, signal);
106 }
107
108 static void default_changed(struct connman_service *service)
109 {
110         if (service != NULL)
111                 state = NM_STATE_CONNECTED;
112         else
113                 state = NM_STATE_DISCONNECTED;
114
115         DBG("%p %d", service, state);
116
117         state_changed(state);
118
119         properties_changed(state);
120 }
121
122 static struct connman_notifier notifier = {
123         .name           = "nmcompat",
124         .priority       = CONNMAN_NOTIFIER_PRIORITY_DEFAULT,
125         .default_changed= default_changed,
126 };
127
128 static DBusMessage *property_get(DBusConnection *conn,
129                                         DBusMessage *msg, void *data)
130 {
131         const char *interface, *key;
132
133         DBG("conn %p", conn);
134
135         dbus_message_get_args(msg, NULL,
136                                 DBUS_TYPE_STRING, &interface,
137                                 DBUS_TYPE_STRING, &key,
138                                 DBUS_TYPE_INVALID);
139
140         DBG("interface %s property %s", interface, key);
141
142         if (g_strcmp0(key, "State") == 0) {
143                 DBusMessage *reply;
144                 DBusMessageIter iter, value;
145
146                 reply = dbus_message_new_method_return(msg);
147                 if (reply == NULL)
148                         return NULL;
149
150                 dbus_message_iter_init_append(reply, &iter);
151
152                 dbus_message_iter_open_container(&iter, DBUS_TYPE_VARIANT,
153                                                 DBUS_TYPE_UINT32_AS_STRING,
154                                                 &value);
155                 dbus_message_iter_append_basic(&value, DBUS_TYPE_UINT32,
156                                                 &state);
157                 dbus_message_iter_close_container(&iter, &value);
158
159                 return reply;
160         }
161
162         return dbus_message_new_error(msg, DBUS_ERROR_FAILED,
163                                                 "Unsupported property");
164 }
165
166 static GDBusMethodTable methods[] = {
167         { "Get", "ss",  "v",   property_get     },
168         { },
169 };
170
171 static GDBusSignalTable signals[] = {
172         { "PropertiesChanged",  "a{sv}" },
173         { "StateChanged",       "u"     },
174         { },
175 };
176
177 static int nmcompat_init(void)
178 {
179         DBG("");
180
181         connection = connman_dbus_get_connection();
182         if (connection == NULL)
183                 return -1;
184
185         if (g_dbus_request_name(connection, NM_SERVICE, NULL) == FALSE) {
186                 connman_error("nmcompat: failed register service\n");
187                 return -1;
188         }
189
190         if (connman_notifier_register(&notifier) < 0) {
191                 connman_error("nmcompat: failed to register notifier");
192                 return -1;
193         }
194
195         if (g_dbus_register_interface(connection, NM_PATH,
196                                 DBUS_PROPERTIES_INTERFACE,
197                                 methods, signals, NULL, NULL, NULL) == FALSE) {
198                 connman_error("nmcompat: failed to register "
199                                                 DBUS_PROPERTIES_INTERFACE);
200                 return -1;
201         }
202
203         return 0;
204 }
205
206 static void nmcompat_exit(void)
207 {
208         DBG("");
209
210         connman_notifier_unregister(&notifier);
211
212         if (connection == NULL)
213                 return;
214
215         g_dbus_unregister_interface(connection, NM_PATH,
216                                         DBUS_PROPERTIES_INTERFACE);
217
218         dbus_connection_unref(connection);
219 }
220
221 CONNMAN_PLUGIN_DEFINE(nmcompat, "NetworkManager compatibility interfaces",
222                         VERSION, CONNMAN_PLUGIN_PRIORITY_DEFAULT,
223                         nmcompat_init, nmcompat_exit)