Tizen 2.1 base
[platform/core/connectivity/net-config.git] / src / dbus / netsupplicant.c
1 /*
2  * Network Configuration Module
3  *
4  * Copyright (c) 2012-2013 Samsung Electronics Co., Ltd. All rights reserved.
5  *
6  * Licensed under the Apache License, Version 2.0 (the "License");
7  * you may not use this file except in compliance with the License.
8  * You may obtain a copy of the License at
9  *
10  * http://www.apache.org/licenses/LICENSE-2.0
11  *
12  * Unless required by applicable law or agreed to in writing, software
13  * distributed under the License is distributed on an "AS IS" BASIS,
14  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15  * See the License for the specific language governing permissions and
16  * limitations under the License.
17  *
18  */
19
20 #include "log.h"
21 #include "netdbus.h"
22 #include "netsupplicant.h"
23
24 #define NETCONFIG_DBUS_REPLY_TIMEOUT (10 * 1000)
25
26 static void setup_dbus_args(gpointer data, gpointer user_data)
27 {
28         struct dbus_input_arguments *args;
29         DBusMessageIter *iter;
30
31         if (data != NULL && user_data != NULL) {
32                 args = (struct dbus_input_arguments *)data;
33                 iter = (DBusMessageIter *) user_data;
34
35                 dbus_message_iter_append_basic(iter, args->type,
36                                 &(args->data));
37         }
38 }
39
40 static GList *setup_input_args(GList *list,
41                 struct dbus_input_arguments *items)
42 {
43         struct dbus_input_arguments *iter = items;
44
45         if (iter == NULL)
46                 return NULL;
47
48         while (iter->data) {
49                 list = g_list_append(list, iter);
50                 iter++;
51         }
52
53         return list;
54 }
55
56 gboolean netconfig_wifi_get_ifname(char **ifname)
57 {
58         DBusConnection *connection = NULL;
59         DBusMessage *message = NULL;
60         DBusMessageIter iter;
61         int MessageType = 0;
62         char *ptr = (char *)*ifname;
63         const char *temp = NULL;
64
65         char object_path[DBUS_PATH_MAX_BUFLEN] = { 0, };
66         char *path_ptr = &object_path[0];
67
68         GList *input_args = NULL;
69         struct dbus_input_arguments args[] = {
70                         {DBUS_TYPE_STRING, SUPPLICANT_INTERFACE ".Interface"},
71                         {DBUS_TYPE_STRING, "Ifname"},
72                         {0, NULL}
73         };
74
75         if (ptr == NULL)
76                 return FALSE;
77
78         if (netconfig_wifi_get_supplicant_interface(&path_ptr) != TRUE) {
79                 DBG("Fail to get wpa_supplicant DBus path");
80                 return FALSE;
81         }
82
83         connection = dbus_bus_get(DBUS_BUS_SYSTEM, NULL);
84         if (connection == NULL) {
85                 ERR("Error!!! Fail to get system DBus");
86                 return FALSE;
87         }
88
89         input_args = setup_input_args(input_args, args);
90
91         message = netconfig_supplicant_invoke_dbus_method(
92                         SUPPLICANT_SERVICE, connection,
93                         path_ptr,
94                         SUPPLICANT_GLOBAL_INTERFACE, "Get",
95                         input_args);
96
97         g_list_free(input_args);
98
99         if (message == NULL) {
100                 ERR("Error!!! Failed to get service properties");
101                 goto error;
102         }
103
104         MessageType = dbus_message_get_type(message);
105
106         if (MessageType == DBUS_MESSAGE_TYPE_ERROR) {
107                 const char *err_ptr = dbus_message_get_error_name(message);
108                 ERR("Error!!! Error message received %s", err_ptr);
109                 goto error;
110         }
111
112         dbus_message_iter_init(message, &iter);
113
114         if ((MessageType = dbus_message_iter_get_arg_type(&iter))
115                         == DBUS_TYPE_VARIANT) {
116                 DBusMessageIter string_type;
117                 dbus_message_iter_recurse(&iter, &string_type);
118
119                 if ((MessageType = dbus_message_iter_get_arg_type(&string_type))
120                                 == DBUS_TYPE_STRING) {
121                         dbus_message_iter_get_basic(&string_type, &temp);
122                 } else
123                         goto error;
124         } else
125                 goto error;
126
127         g_strlcpy(ptr, temp, 16);
128
129         dbus_message_unref(message);
130         dbus_connection_unref(connection);
131
132         return TRUE;
133
134 error:
135         if (message != NULL)
136                 dbus_message_unref(message);
137
138         if (connection != NULL)
139                 dbus_connection_unref(connection);
140
141         return FALSE;
142 }
143
144 gboolean netconfig_wifi_get_supplicant_interface(char **path)
145 {
146         DBusConnection *connection = NULL;
147         DBusMessage *message = NULL;
148         DBusMessageIter iter;
149         int MessageType = 0;
150         char *ptr = (char *)*path;
151         const char *temp = NULL;
152
153         GList *input_args = NULL;
154         struct dbus_input_arguments args[] = {
155                         {DBUS_TYPE_STRING, SUPPLICANT_INTERFACE},
156                         {DBUS_TYPE_STRING, "Interfaces"},
157                         {0, NULL}
158         };
159
160         if (ptr == NULL)
161                 return FALSE;
162
163         connection = dbus_bus_get(DBUS_BUS_SYSTEM, NULL);
164         if (connection == NULL) {
165                 ERR("Error!!! Fail to get system DBus");
166                 return FALSE;
167         }
168
169         input_args = setup_input_args(input_args, args);
170
171         message = netconfig_supplicant_invoke_dbus_method(
172                         SUPPLICANT_SERVICE, connection,
173                         SUPPLICANT_PATH,
174                         SUPPLICANT_GLOBAL_INTERFACE, "Get",
175                         input_args);
176
177         g_list_free(input_args);
178
179         if (message == NULL) {
180                 ERR("Error!!! Failed to get service properties");
181                 goto error;
182         }
183
184         MessageType = dbus_message_get_type(message);
185
186         if (MessageType == DBUS_MESSAGE_TYPE_ERROR) {
187                 const char *err_msg = dbus_message_get_error_name(message);
188                 ERR("Error!!! Error message received %s", err_msg);
189                 goto error;
190         }
191
192         dbus_message_iter_init(message, &iter);
193         if ((MessageType = dbus_message_iter_get_arg_type(&iter))
194                         == DBUS_TYPE_VARIANT) {
195                 DBusMessageIter array;
196                 dbus_message_iter_recurse(&iter, &array);
197
198                 if ((MessageType = dbus_message_iter_get_arg_type(&array))
199                                 == DBUS_TYPE_ARRAY) {
200                         DBusMessageIter object_path;
201                         dbus_message_iter_recurse(&array, &object_path);
202
203                         if ((MessageType = dbus_message_iter_get_arg_type(&object_path))
204                                         == DBUS_TYPE_OBJECT_PATH)
205                                 dbus_message_iter_get_basic(&object_path, &temp);
206                         else
207                                 goto error;
208                 } else
209                         goto error;
210         } else
211                 goto error;
212
213         g_strlcpy(ptr, temp, DBUS_PATH_MAX_BUFLEN);
214
215         dbus_message_unref(message);
216         dbus_connection_unref(connection);
217
218         return TRUE;
219
220 error:
221         if (message != NULL)
222                 dbus_message_unref(message);
223
224         if (connection != NULL)
225                 dbus_connection_unref(connection);
226
227         return FALSE;
228 }
229
230 DBusMessage *netconfig_supplicant_invoke_dbus_method(const char *dest,
231                 DBusConnection *connection,
232                 const char *path, const char *interface_name,
233                 const char *method, GList *args)
234 {
235         DBusError error;
236         DBusMessageIter iter;
237         DBusMessage *reply = NULL;
238         DBusMessage *message = NULL;
239
240         message = dbus_message_new_method_call(dest, path, interface_name, method);
241         if (message == NULL) {
242                 ERR("Error!!! DBus method call fail");
243                 return NULL;
244         }
245
246         dbus_message_iter_init_append(message, &iter);
247
248         if (args != NULL)
249                 g_list_foreach(args, setup_dbus_args, (gpointer) &iter);
250
251         dbus_error_init(&error);
252
253         reply = dbus_connection_send_with_reply_and_block(connection, message,
254                         NETCONFIG_DBUS_REPLY_TIMEOUT, &error);
255
256         if (reply == NULL) {
257                 if (dbus_error_is_set(&error) == TRUE) {
258                         ERR("Error!!! dbus_connection_send_with_reply_and_block() failed. DBus error [%s: %s]",
259                                         error.name, error.message);
260
261                         dbus_error_free(&error);
262                 } else
263                         ERR("Error!!! Failed to get properties");
264
265                 dbus_message_unref(message);
266
267                 return NULL;
268         }
269
270         dbus_message_unref(message);
271
272         return reply;
273 }