Merge "Added cap_dac_override capability" into tizen_4.0
[platform/core/connectivity/net-config.git] / src / wifi-wps.c
1 /*
2  * Network Configuration Module
3  *
4  * Copyright (c) 2000 - 2012 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 <errno.h>
21 #include <vconf.h>
22 #include <glib.h>
23
24 #include "log.h"
25 #include "util.h"
26 #include "netdbus.h"
27 #include "neterror.h"
28 #include "wifi-wps.h"
29 #include "wifi-power.h"
30 #include "wifi-state.h"
31 #include "netsupplicant.h"
32 #include "wifi-background-scan.h"
33
34 struct netconfig_wifi_wps {
35         char *pin;
36         gboolean pbc;
37 };
38
39 static struct netconfig_wifi_wps wifi_wps;
40
41 void netconfig_wifi_notify_wps_credentials(const char *ssid, gsize ssid_len, const char *wps_key)
42 {
43         GVariantBuilder *builder;
44         GVariant *params;
45         const char *sig_name = "WpsCredentials";
46         const char *prop_ssid = "ssid";
47         const char *prop_key = "key";
48         GVariantBuilder *rawssid_builder = NULL;
49         int i;
50
51         builder = g_variant_builder_new(G_VARIANT_TYPE("a{sv}"));
52         rawssid_builder = g_variant_builder_new(G_VARIANT_TYPE("ay"));
53         for (i = 0; i < ssid_len; i++)
54                 g_variant_builder_add(rawssid_builder, "y", ssid[i]);
55         g_variant_builder_add(builder, "{sv}", prop_ssid, g_variant_new("ay", rawssid_builder));
56         g_variant_builder_unref(rawssid_builder);
57         g_variant_builder_add(builder, "{sv}", prop_key, g_variant_new_string(wps_key));
58
59         params = g_variant_new("(@a{sv})", g_variant_builder_end(builder));
60         g_variant_builder_unref(builder);
61
62         netconfig_dbus_emit_signal(NULL,
63                                 NETCONFIG_WIFI_PATH,
64                                 NETCONFIG_WIFI_INTERFACE,
65                                 sig_name,
66                                 params);
67
68         INFO("Sent signal (%s)", sig_name);
69         return;
70 }
71
72 void netconfig_wifi_notify_wps_completed(const char *ssid, gsize ssid_len)
73 {
74         GVariantBuilder *builder;
75         GVariant *params;
76         const char *sig_name = "WpsCompleted";
77         const char *prop_ssid = "ssid";
78         GVariantBuilder *rawssid_builder = NULL;
79         int i;
80
81         builder = g_variant_builder_new(G_VARIANT_TYPE("a{sv}"));
82         rawssid_builder = g_variant_builder_new(G_VARIANT_TYPE("ay"));
83         for (i = 0; i < ssid_len; i++)
84                 g_variant_builder_add(rawssid_builder, "y", ssid[i]);
85         g_variant_builder_add(builder, "{sv}", prop_ssid, g_variant_new("ay", rawssid_builder));
86         g_variant_builder_unref(rawssid_builder);
87
88         params = g_variant_new("(@a{sv})", g_variant_builder_end(builder));
89         g_variant_builder_unref(builder);
90
91         netconfig_dbus_emit_signal(NULL,
92                                 NETCONFIG_WIFI_PATH,
93                                 NETCONFIG_WIFI_INTERFACE,
94                                 sig_name,
95                                 params);
96
97         INFO("Sent signal (%s)", sig_name);
98         return;
99 }
100
101 void netconfig_wifi_notify_wps_fail_event(int config_error, int error_indication)
102 {
103         GVariantBuilder *builder;
104         GVariant *params;
105         const char *sig_name = "WpsFailEvent";
106         const char *prop_config_error = "config_error";
107         const char *prop_error_indication = "error_indication";
108
109         builder = g_variant_builder_new(G_VARIANT_TYPE("a{sv}"));
110         g_variant_builder_add(builder, "{sv}", prop_config_error, g_variant_new_int32(config_error));
111         g_variant_builder_add(builder, "{sv}", prop_error_indication, g_variant_new_int32(error_indication));
112
113         params = g_variant_new("(@a{sv})", g_variant_builder_end(builder));
114         g_variant_builder_unref(builder);
115
116         netconfig_dbus_emit_signal(NULL,
117                                 NETCONFIG_WIFI_PATH,
118                                 NETCONFIG_WIFI_INTERFACE,
119                                 sig_name,
120                                 params);
121
122         INFO("Sent signal (%s)", sig_name);
123         return;
124 }
125
126 static void interface_wps_start_result(GObject *source_object,
127                         GAsyncResult *res, gpointer user_data)
128 {
129         GVariant *reply;
130         GDBusConnection *conn = NULL;
131         GError *error = NULL;
132
133         conn = G_DBUS_CONNECTION(source_object);
134         reply = g_dbus_connection_call_finish(conn, res, &error);
135
136         if (reply == NULL) {
137                 if (error != NULL) {
138                         ERR("Fail to request status [%d: %s]",
139                                         error->code, error->message);
140                         g_error_free(error);
141                 } else {
142                         ERR("Fail torequest status");
143                 }
144         } else {
145                 DBG("Successfully M/W--->WPAS: Interface.WPS.Start Method");
146         }
147
148         g_variant_unref(reply);
149         netconfig_gdbus_pending_call_unref();
150 }
151
152 static void __netconfig_wifi_invoke_wps_connect(GObject *source_object,
153                         GAsyncResult *res, gpointer user_data)
154 {
155         GVariant *message = NULL;
156         GVariantBuilder *builder = NULL;
157         const char *role = "enrollee", *type, *key;
158         const char *if_path = NULL;
159         gboolean reply = FALSE;
160
161         if (if_path == NULL)
162                 if_path = netconfig_wifi_get_supplicant_interface();
163
164         if (if_path == NULL) {
165                 DBG("Fail to get wpa_supplicant DBus path");
166                 return;
167         }
168
169         builder = g_variant_builder_new(G_VARIANT_TYPE("a{sv}"));
170
171         key = "Role";
172         g_variant_builder_add(builder, "{sv}", key, g_variant_new_string(role));
173
174         key = "Type";
175
176         if (wifi_wps.pbc == TRUE)
177                 type = "pbc";
178         else
179                 type = "pin";
180
181         g_variant_builder_add(builder, "{sv}", key, g_variant_new_string(type));
182
183         if (wifi_wps.pin != NULL) {
184                 key = "Pin";
185                 g_variant_builder_add(builder, "{sv}", key, g_variant_new_string(wifi_wps.pin));
186         }
187         message = g_variant_new("(@a{sv})", g_variant_builder_end(builder));
188         g_variant_builder_unref(builder);
189
190         DBG("[net-config]: TizenMW-->WPAS: .Interface.WPS.Start");
191         reply = netconfig_supplicant_invoke_dbus_method_nonblock(
192                         SUPPLICANT_SERVICE,
193                         if_path,
194                         SUPPLICANT_IFACE_WPS,
195                         "Start",
196                         message,
197                         (GAsyncReadyCallback) interface_wps_start_result);
198
199         if (reply != TRUE)
200                 ERR("Fail to Scan");
201
202         return;
203 }
204
205 static gboolean __netconfig_wifi_invoke_wps_process_credentials(const char *object_path)
206 {
207         gboolean reply = FALSE;
208         GVariant *params = NULL;
209         const char *interface = SUPPLICANT_IFACE_WPS;
210         const char *key = "ProcessCredentials";
211         gboolean credentials = TRUE;
212         GVariant *var = NULL;
213
214          var = g_variant_new_boolean(credentials);
215         params = g_variant_new("(ssv)", interface, key, var);
216
217         INFO("[net-config]: TizenMW-->WPAS: .Set");
218         reply = netconfig_invoke_dbus_method_nonblock(SUPPLICANT_SERVICE,
219                         object_path, DBUS_INTERFACE_PROPERTIES,
220                         "Set", params, __netconfig_wifi_invoke_wps_connect);
221
222         if (reply != TRUE)
223                 ERR("M/W--->WPAS: Interface.WPS.Set Method Failed");
224
225         return reply;
226 }
227
228 gboolean netconfig_wifi_wps_connect()
229 {
230         const char *if_path = NULL;
231
232         if_path = netconfig_wifi_get_supplicant_interface();
233         if (if_path == NULL) {
234                 DBG("Fail to get wpa_supplicant DBus path");
235                  return FALSE;
236         }
237
238         if (__netconfig_wifi_invoke_wps_process_credentials(if_path) == TRUE) {
239                 ERR("Wi-Fi WPS Connect started");
240
241                 return TRUE;
242         }
243
244         return FALSE;
245 }
246
247 static void __interface_wps_cancel_result(GObject *source_object,
248                         GAsyncResult *res, gpointer user_data)
249 {
250         GVariant *reply;
251         GDBusConnection *conn = NULL;
252         GError *error = NULL;
253
254         conn = G_DBUS_CONNECTION(source_object);
255         reply = g_dbus_connection_call_finish(conn, res, &error);
256
257         if (reply == NULL) {
258                 if (error != NULL) {
259                         ERR("Fail to request status [%d: %s]",
260                                         error->code, error->message);
261                         g_error_free(error);
262                 } else {
263                         ERR("Fail torequest status");
264                 }
265         } else {
266                 DBG("Successfully M/W--->WPAS: Interface.WPS.Cancel Method");
267         }
268
269         g_variant_unref(reply);
270         netconfig_gdbus_pending_call_unref();
271 }
272
273 static gboolean __netconfig_wifi_invoke_wps_cancel()
274 {
275         gboolean reply = FALSE;
276         const char *if_path = NULL;
277
278         if_path = netconfig_wifi_get_supplicant_interface();
279         if (if_path == NULL) {
280                 DBG("Fail to get wpa_supplicant DBus path");
281                 return -ESRCH;
282         }
283
284         DBG("M/W--->WPAS: Interface.WPS.Cancel Method");
285
286         reply = netconfig_invoke_dbus_method_nonblock(SUPPLICANT_SERVICE,
287                         if_path, SUPPLICANT_IFACE_WPS,
288                         "Cancel", NULL, __interface_wps_cancel_result);
289
290         if (reply != TRUE)
291                 ERR("M/W--->WPAS: Interface.WPS.Cancel Method Failed");
292
293         return reply;
294 }
295
296 gboolean netconfig_get_wps_field()
297 {
298         return wifi_wps.pbc;
299 }
300
301 gboolean handle_request_wps_cancel(Wifi *wifi, GDBusMethodInvocation *context)
302 {
303         INFO("Received WPS PBC Cancel Request");
304         g_return_val_if_fail(wifi != NULL, FALSE);
305         __netconfig_wifi_invoke_wps_cancel();
306
307         wifi_complete_request_wps_cancel(wifi, context);
308         return TRUE;
309 }
310
311 gboolean handle_request_wps_connect(Wifi *wifi, GDBusMethodInvocation *context, gchar *param)
312 {
313         INFO("Received WPS PBC/PIN Connection Request");
314
315         g_return_val_if_fail(wifi != NULL, FALSE);
316
317         /* Checking the value of pin if param have a string "PBC"
318          * in that scenario PBC will trigger otherwise PIN Connection */
319
320         if (g_strcmp0(param, "PBC") == 0) {
321                 wifi_wps.pbc = TRUE;
322                 wifi_wps.pin = NULL;
323         } else {
324                 wifi_wps.pin = g_strdup(param);
325                 wifi_wps.pbc = FALSE;
326         }
327
328         netconfig_wifi_wps_connect();
329
330         wifi_complete_request_wps_connect(wifi, context);
331         return TRUE;
332 }