792c70697747c0cfd585dfaedb9278a9402d8570
[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 #define NETCONFIG_SSID_LEN                                              32
35 #define NETCONFIG_BSSID_LEN                                             6
36 #define NETCONFIG_WPS_DBUS_REPLY_TIMEOUT                (10 * 1000)
37
38 #define VCONF_WIFI_ALWAYS_ALLOW_SCANNING \
39         "file/private/wifi/always_allow_scanning"
40
41 static gboolean netconfig_is_wps_enabled = FALSE;
42 static gboolean netconfig_is_device_scanning = FALSE;
43 static gboolean netconfig_is_wps_scan_aborted = FALSE;
44 static int wps_bss_list_count = 0;
45
46 struct wps_bss_info_t {
47         unsigned char ssid[NETCONFIG_SSID_LEN + 1];
48         unsigned char bssid[NETCONFIG_BSSID_LEN + 1];
49         int ssid_len;
50         int rssi;
51         int mode;
52 };
53
54 struct netconfig_wifi_wps {
55         char *pin;
56         gboolean pbc;
57 };
58
59 static struct netconfig_wifi_wps wifi_wps;
60
61 static GSList *wps_bss_info_list = NULL;
62
63 static void __netconfig_wps_set_mode(gboolean enable)
64 {
65         if (netconfig_is_wps_enabled == enable)
66                 return;
67
68         netconfig_is_wps_enabled = enable;
69 }
70
71 gboolean netconfig_wifi_is_wps_enabled(void)
72 {
73         return netconfig_is_wps_enabled;
74 }
75
76 void netconfig_wifi_notify_wps_credentials(const char *ssid, gsize ssid_len, const char *wps_key)
77 {
78         GVariantBuilder *builder;
79         GVariant *params;
80         const char *sig_name = "WpsCredentials";
81         const char *prop_ssid = "ssid";
82         const char *prop_key = "key";
83         GVariantBuilder *rawssid_builder = NULL;
84         int i;
85
86         builder = g_variant_builder_new(G_VARIANT_TYPE("a{sv}"));
87         rawssid_builder = g_variant_builder_new(G_VARIANT_TYPE("ay"));
88         for (i = 0; i < ssid_len; i++)
89                 g_variant_builder_add(rawssid_builder, "y", ssid[i]);
90         g_variant_builder_add(builder, "{sv}", prop_ssid, g_variant_new("ay", rawssid_builder));
91         g_variant_builder_unref(rawssid_builder);
92         g_variant_builder_add(builder, "{sv}", prop_key, g_variant_new_string(wps_key));
93
94         params = g_variant_new("(@a{sv})", g_variant_builder_end(builder));
95         g_variant_builder_unref(builder);
96
97         netconfig_dbus_emit_signal(NULL,
98                                 NETCONFIG_WIFI_PATH,
99                                 NETCONFIG_WIFI_INTERFACE,
100                                 sig_name,
101                                 params);
102
103         INFO("Sent signal (%s)", sig_name);
104         return;
105 }
106
107 void netconfig_wifi_notify_wps_completed(const char *ssid, gsize ssid_len)
108 {
109         GVariantBuilder *builder;
110         GVariant *params;
111         const char *sig_name = "WpsCompleted";
112         const char *prop_ssid = "ssid";
113         GVariantBuilder *rawssid_builder = NULL;
114         int i;
115
116         builder = g_variant_builder_new(G_VARIANT_TYPE("a{sv}"));
117         rawssid_builder = g_variant_builder_new(G_VARIANT_TYPE("ay"));
118         for (i = 0; i < ssid_len; i++)
119                 g_variant_builder_add(rawssid_builder, "y", ssid[i]);
120         g_variant_builder_add(builder, "{sv}", prop_ssid, g_variant_new("ay", rawssid_builder));
121         g_variant_builder_unref(rawssid_builder);
122
123         params = g_variant_new("(@a{sv})", g_variant_builder_end(builder));
124         g_variant_builder_unref(builder);
125
126         netconfig_dbus_emit_signal(NULL,
127                                 NETCONFIG_WIFI_PATH,
128                                 NETCONFIG_WIFI_INTERFACE,
129                                 sig_name,
130                                 params);
131
132         INFO("Sent signal (%s)", sig_name);
133         return;
134 }
135
136 void netconfig_wifi_notify_wps_fail_event(int config_error, int error_indication)
137 {
138         GVariantBuilder *builder;
139         GVariant *params;
140         const char *sig_name = "WpsFailEvent";
141         const char *prop_config_error = "config_error";
142         const char *prop_error_indication = "error_indication";
143
144         builder = g_variant_builder_new(G_VARIANT_TYPE("a{sv}"));
145         g_variant_builder_add(builder, "{sv}", prop_config_error, g_variant_new_int32(config_error));
146         g_variant_builder_add(builder, "{sv}", prop_error_indication, g_variant_new_int32(error_indication));
147
148         params = g_variant_new("(@a{sv})", g_variant_builder_end(builder));
149         g_variant_builder_unref(builder);
150
151         netconfig_dbus_emit_signal(NULL,
152                                 NETCONFIG_WIFI_PATH,
153                                 NETCONFIG_WIFI_INTERFACE,
154                                 sig_name,
155                                 params);
156
157         INFO("Sent signal (%s)", sig_name);
158         return;
159 }
160
161 static void __netconfig_wifi_wps_notify_scan_done(void)
162 {
163         GVariantBuilder *builder = NULL;
164         GVariantBuilder *builder1 = NULL;
165         GSList* list = NULL;
166         const char *prop_ssid = "ssid";
167         const char *prop_bssid = "bssid";
168         const char *prop_rssi = "rssi";
169         const char *prop_mode = "mode";
170
171         builder = g_variant_builder_new(G_VARIANT_TYPE("a{sv}"));
172         for (list = wps_bss_info_list; list != NULL; list = list->next) {
173                 struct wps_bss_info_t *bss_info = (struct wps_bss_info_t *)list->data;
174
175                 if (bss_info) {
176                         gchar bssid_buff[18] = { 0, };
177                         gchar *bssid_str = bssid_buff;
178                         unsigned char *ssid = (unsigned char *)bss_info->ssid;
179                         int ssid_len = (int)bss_info->ssid_len;
180                         int rssi = (int)bss_info->rssi;
181                         int mode = (int)bss_info->mode;
182                         int i = 0;
183                         g_snprintf(bssid_buff, 18, "%02x:%02x:%02x:%02x:%02x:%02x",
184                                         bss_info->bssid[0], bss_info->bssid[1], bss_info->bssid[2],
185                                         bss_info->bssid[3], bss_info->bssid[4], bss_info->bssid[5]);
186
187                         DBG("BSS found; SSID %s, BSSID %s, RSSI %d MODE %d", ssid, bssid_str, rssi, mode);
188
189                         builder1 = g_variant_builder_new(G_VARIANT_TYPE("ay"));
190                         for (i = 0; i < ssid_len; i++)
191                                 g_variant_builder_add(builder1, "y", ssid[i]);
192                         g_variant_builder_add(builder, "{sv}", prop_ssid, g_variant_builder_end(builder1));
193                         g_variant_builder_unref(builder1);
194
195                         g_variant_builder_add(builder, "{sv}", prop_bssid, g_variant_new_string(bssid_str));
196                         g_variant_builder_add(builder, "{sv}", prop_rssi, g_variant_new_int32(rssi));
197                         g_variant_builder_add(builder, "{sv}", prop_mode, g_variant_new_int32(mode));
198                 }
199         }
200
201         wifi_emit_wps_scan_completed((Wifi *)get_wifi_object(), g_variant_builder_end(builder));
202         g_variant_builder_unref(builder);
203
204         if (wps_bss_info_list != NULL)
205                 g_slist_free_full(wps_bss_info_list, g_free);
206
207         wps_bss_info_list = NULL;
208         wps_bss_list_count = 0;
209         INFO("WpsScanCompleted");
210
211         return;
212 }
213
214 static void __netconfig_wifi_wps_get_bss_info_result(
215                 GObject *source_object, GAsyncResult *res, gpointer user_data)
216 {
217         GVariant *reply = NULL;
218         GVariant *value;
219         GVariantIter *iter;
220         gchar *key;
221         struct wps_bss_info_t *bss_info;
222         GDBusConnection *conn = NULL;
223         GError *error = NULL;
224
225         conn = G_DBUS_CONNECTION(source_object);
226         reply = g_dbus_connection_call_finish(conn, res, &error);
227
228         if (error != NULL) {
229                 ERR("Error code: [%d] Error message: [%s]", error->code, error->message);
230                 g_error_free(error);
231                 goto done;
232         }
233
234         bss_info = g_try_new0(struct wps_bss_info_t, 1);
235         if (bss_info == NULL)
236                 goto done;
237
238         g_variant_get(reply, "(a{sv})", &iter);
239         while (g_variant_iter_loop(iter, "{sv}", &key, &value)) {
240                 if (key != NULL) {
241                         if (g_strcmp0(key, "BSSID") == 0) {
242                                 const guchar *bssid;
243                                 gsize bssid_len;
244
245                                 bssid = g_variant_get_fixed_array(value, &bssid_len, sizeof(guchar));
246                                 if (bssid_len == NETCONFIG_BSSID_LEN)
247                                         memcpy(bss_info->bssid, bssid, bssid_len);
248                         } else if (g_strcmp0(key, "SSID") == 0) {
249                                 const guchar *ssid;
250                                 gsize ssid_len;
251
252                                 ssid = g_variant_get_fixed_array(value, &ssid_len, sizeof(guchar));
253                                 if (ssid != NULL && ssid_len > 0 && ssid_len <= NETCONFIG_SSID_LEN) {
254                                         memcpy(bss_info->ssid, ssid, ssid_len);
255                                         bss_info->ssid_len = ssid_len;
256                                 } else {
257                                         memset(bss_info->ssid, 0, sizeof(bss_info->ssid));
258                                         bss_info->ssid_len = 0;
259                                 }
260                         } else if (g_strcmp0(key, "Mode") == 0) {
261                                 gchar *mode = NULL;
262
263                                 g_variant_get(value, "s", &mode);
264                                 if (mode == NULL)
265                                         bss_info->mode = 0;
266                                 else {
267                                         if (g_strcmp0(mode, "infrastructure") == 0)
268                                                 bss_info->mode = 1;
269                                         else if (g_strcmp0(mode, "ad-hoc") == 0)
270                                                 bss_info->mode = 2;
271                                         else
272                                                 bss_info->mode = 0;
273                                         g_free(mode);
274                                 }
275                         } else if (g_strcmp0(key, "Signal") == 0) {
276                                 gint16 signal;
277
278                                 signal = g_variant_get_int16(value);
279                                 bss_info->rssi = signal;
280                         }
281                 }
282         }
283
284         if (bss_info->ssid[0] == '\0')
285                 g_free(bss_info);
286         else
287                 wps_bss_info_list = g_slist_append(wps_bss_info_list, bss_info);
288
289         g_variant_iter_free(iter);
290 done:
291         if (reply)
292                 g_variant_unref(reply);
293
294         netconfig_gdbus_pending_call_unref();
295
296         wps_bss_list_count--;
297         if (wps_bss_list_count <= 0) {
298                 __netconfig_wifi_wps_notify_scan_done();
299
300                 if (netconfig_is_wps_scan_aborted == FALSE)
301                         wifi_power_driver_and_supplicant(FALSE);
302         }
303 }
304
305 static void __netconfig_wifi_wps_get_bss_info(const char *path, int index)
306 {
307         gboolean reply = FALSE;
308         GVariant *param = NULL;
309
310         param = g_variant_new("(s)", SUPPLICANT_IFACE_BSS);
311
312         reply = netconfig_invoke_dbus_method_nonblock(SUPPLICANT_SERVICE,
313                         path, DBUS_INTERFACE_PROPERTIES,
314                         "GetAll", param, __netconfig_wifi_wps_get_bss_info_result);
315         if (reply != TRUE)
316                 ERR("Fail to invoke_dbus_method_nonblock GetAll");
317
318         return;
319 }
320
321 static void __netconfig_wifi_wps_get_bsss_result(GObject *source_object,
322                 GAsyncResult *res, gpointer user_data)
323 {
324         GVariant *reply = NULL;
325         GVariant *value = NULL;
326         GVariantIter *iter = NULL;
327         GDBusConnection *conn = NULL;
328         gchar *path = NULL;
329         gboolean counter_flag = FALSE;
330         GError *error = NULL;
331
332         conn = G_DBUS_CONNECTION(source_object);
333         reply = g_dbus_connection_call_finish(conn, res, &error);
334         if (error != NULL) {
335                 ERR("Error code: [%d] Error message: [%s]", error->code, error->message);
336                 g_error_free(error);
337                 goto done;
338         }
339
340         g_variant_get(reply, "(v)", &value);
341         if (g_variant_is_of_type(value, G_VARIANT_TYPE_OBJECT_PATH_ARRAY)) {
342                 g_variant_get(value, "ao", &iter);
343                 while (g_variant_iter_next(iter, "o", &path)) {
344                         if (path != NULL && g_strcmp0(path, "/") != 0) {
345                                 __netconfig_wifi_wps_get_bss_info(path, ++wps_bss_list_count);
346
347                                 counter_flag = TRUE;
348                         }
349
350                         if (path)
351                                 g_free(path);
352                 }
353         }
354
355         if (iter)
356                 g_variant_iter_free(iter);
357
358         if (value)
359                 g_variant_unref(value);
360
361 done:
362         if (reply)
363                 g_variant_unref(reply);
364
365         netconfig_gdbus_pending_call_unref();
366
367         /* Send WpsScanCompleted signal even when the BSS count is 0 */
368         if (wps_bss_list_count <= 0 && counter_flag == FALSE) {
369                 __netconfig_wifi_wps_notify_scan_done();
370
371                 if (netconfig_is_wps_scan_aborted == FALSE)
372                         wifi_power_driver_and_supplicant(FALSE);
373         }
374 }
375
376 static int _netconfig_wifi_wps_get_bsss(void)
377 {
378         gboolean reply = FALSE;
379         const char *if_path = NULL;
380         GVariant *params = NULL;
381
382         if_path = netconfig_wifi_get_supplicant_interface();
383         if (if_path == NULL) {
384                 DBG("Fail to get wpa_supplicant DBus path");
385                 return -ESRCH;
386         }
387
388         params = g_variant_new("(ss)", SUPPLICANT_IFACE_INTERFACE, "BSSs");
389
390         reply = netconfig_invoke_dbus_method_nonblock(SUPPLICANT_SERVICE,
391                         if_path, DBUS_INTERFACE_PROPERTIES,
392                         "Get", params, __netconfig_wifi_wps_get_bsss_result);
393         if (reply != TRUE) {
394                 ERR("Fail to method: Get");
395
396                 return -ESRCH;
397         }
398
399         return 0;
400 }
401
402 void netconfig_wifi_wps_signal_scandone(void)
403 {
404         wps_bss_list_count = 0;
405         _netconfig_wifi_wps_get_bsss();
406
407         netconfig_is_device_scanning = FALSE;
408
409         __netconfig_wps_set_mode(FALSE);
410 }
411
412 void netconfig_wifi_wps_signal_scanaborted(void)
413 {
414         wps_bss_list_count = 0;
415         netconfig_is_wps_scan_aborted = TRUE;
416         _netconfig_wifi_wps_get_bsss();
417
418         netconfig_is_device_scanning = FALSE;
419
420         __netconfig_wps_set_mode(FALSE);
421 }
422
423 static int __netconfig_wifi_wps_request_scan(const char *if_path)
424 {
425         GDBusConnection *connection = NULL;
426         GVariant *message = NULL;
427         GVariantBuilder *builder = NULL;
428         const char *key1 = "Type";
429         const char *val1 = "passive";
430
431         if (if_path == NULL)
432                 if_path = netconfig_wifi_get_supplicant_interface();
433
434         if (if_path == NULL) {
435                 DBG("Fail to get wpa_supplicant DBus path");
436                 return -ESRCH;
437         }
438
439         connection = netdbus_get_connection();
440         if (connection == NULL) {
441                 ERR("Failed to get GDBusconnection");
442                 return -EIO;
443         }
444
445         builder = g_variant_builder_new(G_VARIANT_TYPE("a{sv}"));
446         g_variant_builder_add(builder, "{sv}", key1, g_variant_new_string(val1));
447         message = g_variant_new("(@a{sv})", g_variant_builder_end(builder));
448         g_variant_builder_unref(builder);
449
450         g_dbus_connection_call(connection,
451                         SUPPLICANT_SERVICE,
452                         if_path,
453                         SUPPLICANT_INTERFACE ".Interface",
454                         "Scan",
455                         message,
456                         NULL,
457                         G_DBUS_CALL_FLAGS_NONE,
458                         NETCONFIG_WPS_DBUS_REPLY_TIMEOUT,
459                         netdbus_get_cancellable(),
460                         NULL,
461                         NULL);
462
463         netconfig_is_device_scanning = TRUE;
464
465         g_variant_unref(message);
466         /* Clear bss_info_list for the next scan result */
467         if (wps_bss_info_list) {
468                 g_slist_free_full(wps_bss_info_list, g_free);
469                 wps_bss_info_list = NULL;
470         }
471
472         netconfig_is_wps_scan_aborted = FALSE;
473
474         return 0;
475 }
476
477 static void __netconfig_wifi_interface_create_result(
478                 GObject *source_object, GAsyncResult *res, gpointer user_data)
479 {
480         GVariant *message;
481         gchar *path = NULL;
482         GDBusConnection *conn = NULL;
483         GError *error = NULL;
484
485         conn = G_DBUS_CONNECTION(source_object);
486
487         message = g_dbus_connection_call_finish(conn, res, &error);
488         if (error == NULL) {
489                 g_variant_get(message, "(o)", &path);
490
491                 if (path) {
492                         __netconfig_wifi_wps_request_scan(path);
493                         g_free(path);
494                 }
495         } else if (NULL != strstr(error->message, ".InterfaceExists")) {
496                 INFO("Error Message %s %s", error->message, path);
497                 g_variant_get(message, "(o)", &path);
498                 if (path) {
499                         __netconfig_wifi_wps_request_scan(path);
500                         g_free(path);
501                 } else
502                         __netconfig_wifi_wps_request_scan(NULL);
503         } else {
504                 ERR("Failed to create interface, Error: %d[%s]", error->code, error->message);
505                 __netconfig_wps_set_mode(FALSE);
506                 wifi_power_driver_and_supplicant(FALSE);
507         }
508
509         g_variant_unref(message);
510 }
511
512 static int  __netconfig_wifi_wps_create_interface(void)
513 {
514         GDBusConnection *connection = NULL;
515         GVariant *message = NULL;
516         GVariantBuilder *builder = NULL;
517         const char *key = "Ifname";
518         const char *val = WIFI_IFNAME;
519
520         connection = netdbus_get_connection();
521         if (connection == NULL) {
522                 DBG("Failed to get GDBusconnection");
523                 return -EIO;
524         }
525
526         builder = g_variant_builder_new(G_VARIANT_TYPE("a{sv}"));
527         g_variant_builder_add(builder, "{sv}", key, g_variant_new_string(val));
528         message = g_variant_new("(@a{sv})", g_variant_builder_end(builder));
529
530         g_dbus_connection_call(connection,
531                         SUPPLICANT_SERVICE,
532                         SUPPLICANT_PATH,
533                         SUPPLICANT_INTERFACE,
534                         "CreateInterface",
535                         message,
536                         NULL,
537                         G_DBUS_CALL_FLAGS_NONE,
538                         NETCONFIG_WPS_DBUS_REPLY_TIMEOUT,
539                         netdbus_get_cancellable(),
540                         (GAsyncReadyCallback) __netconfig_wifi_interface_create_result,
541                         NULL);
542
543         g_variant_unref(message);
544
545         return 0;
546 }
547
548 static int __netconfig_wifi_wps_scan(void)
549 {
550         int err = 0;
551         wifi_tech_state_e wifi_tech_state;
552
553         if (netconfig_is_device_scanning == TRUE)
554                 return -EINPROGRESS;
555
556         wifi_tech_state = wifi_state_get_technology_state();
557         if (wifi_tech_state <= NETCONFIG_WIFI_TECH_OFF)
558                 err = wifi_power_driver_and_supplicant(TRUE);
559
560         if (err < 0 && err != -EALREADY)
561                 return err;
562
563         netconfig_is_device_scanning = TRUE;
564
565         DBG("WPS scan requested");
566         if (wifi_tech_state >= NETCONFIG_WIFI_TECH_POWERED) {
567                 if (netconfig_wifi_get_scanning() == TRUE)
568                         return -EINPROGRESS;
569
570                 netconfig_wifi_bgscan_start(TRUE);
571
572                 if (wifi_tech_state == NETCONFIG_WIFI_TECH_CONNECTED)
573                         __netconfig_wifi_wps_request_scan(NULL);
574         } else {
575                 err = __netconfig_wifi_wps_create_interface();
576         }
577
578         return err;
579 }
580
581 gboolean handle_request_wps_scan(Wifi *wifi, GDBusMethodInvocation *context)
582 {
583         int err, enabled = 0;
584         wifi_tech_state_e tech_state;
585
586         g_return_val_if_fail(wifi != NULL, FALSE);
587
588         if (netconfig_is_wifi_tethering_on() == TRUE) {
589                 ERR("Wi-Fi Tethering is enabled");
590                 netconfig_error_dbus_method_return(context, NETCONFIG_ERROR_NO_SERVICE, "TetheringEnabled");
591                 return -EBUSY;
592         }
593
594 #if !defined TIZEN_WEARABLE
595         if (netconfig_wifi_is_bgscan_paused()) {
596                 ERR("Scan is paused");
597                 netconfig_error_dbus_method_return(context, NETCONFIG_ERROR_NO_SERVICE, "ScanPaused");
598                 return FALSE;
599         }
600 #endif
601
602         tech_state = wifi_state_get_technology_state();
603         if (tech_state <= NETCONFIG_WIFI_TECH_OFF) {
604 #if !defined TIZEN_WEARABLE
605                 netconfig_vconf_get_int(VCONF_WIFI_ALWAYS_ALLOW_SCANNING, &enabled);
606 #else
607                 enabled = 0;
608 #endif
609
610                 if (enabled == 0) {
611                         netconfig_error_permission_denied(context);
612                         return FALSE;
613                 }
614         }
615
616         __netconfig_wps_set_mode(TRUE);
617
618         err = __netconfig_wifi_wps_scan();
619         if (err < 0) {
620                 if (err == -EINPROGRESS)
621                         netconfig_error_inprogress(context);
622                 else
623                         netconfig_error_wifi_driver_failed(context);
624
625                 return FALSE;
626         }
627
628         wifi_complete_request_wps_scan(wifi, context);
629         return TRUE;
630 }
631
632 static void interface_wps_start_result(GObject *source_object,
633                         GAsyncResult *res, gpointer user_data)
634 {
635         GVariant *reply;
636         GDBusConnection *conn = NULL;
637         GError *error = NULL;
638
639         conn = G_DBUS_CONNECTION(source_object);
640         reply = g_dbus_connection_call_finish(conn, res, &error);
641
642         if (reply == NULL) {
643                 if (error != NULL) {
644                         ERR("Fail to request status [%d: %s]",
645                                         error->code, error->message);
646                         g_error_free(error);
647                 } else {
648                         ERR("Fail torequest status");
649                 }
650         } else {
651                 DBG("Successfully M/W--->WPAS: Interface.WPS.Start Method");
652         }
653
654         g_variant_unref(reply);
655         netconfig_gdbus_pending_call_unref();
656 }
657
658 static void __netconfig_wifi_invoke_wps_connect(GObject *source_object,
659                         GAsyncResult *res, gpointer user_data)
660 {
661         GVariant *message = NULL;
662         GVariantBuilder *builder = NULL;
663         const char *role = "enrollee", *type, *key;
664         const char *if_path = NULL;
665         gboolean reply = FALSE;
666
667         if (if_path == NULL)
668                 if_path = netconfig_wifi_get_supplicant_interface();
669
670         if (if_path == NULL) {
671                 DBG("Fail to get wpa_supplicant DBus path");
672                 return;
673         }
674
675         builder = g_variant_builder_new(G_VARIANT_TYPE("a{sv}"));
676
677         key = "Role";
678         g_variant_builder_add(builder, "{sv}", key, g_variant_new_string(role));
679
680         key = "Type";
681
682         if (wifi_wps.pbc == TRUE)
683                 type = "pbc";
684         else
685                 type = "pin";
686
687         g_variant_builder_add(builder, "{sv}", key, g_variant_new_string(type));
688
689         if (wifi_wps.pin != NULL) {
690                 key = "Pin";
691                 g_variant_builder_add(builder, "{sv}", key, g_variant_new_string(wifi_wps.pin));
692         }
693         message = g_variant_new("(@a{sv})", g_variant_builder_end(builder));
694         g_variant_builder_unref(builder);
695
696         DBG("[net-config]: TizenMW-->WPAS: .Interface.WPS.Start");
697         reply = netconfig_supplicant_invoke_dbus_method_nonblock(
698                         SUPPLICANT_SERVICE,
699                         if_path,
700                         SUPPLICANT_IFACE_WPS,
701                         "Start",
702                         message,
703                         (GAsyncReadyCallback) interface_wps_start_result);
704
705         if (reply != TRUE)
706                 ERR("Fail to Scan");
707
708         return;
709 }
710
711 static gboolean __netconfig_wifi_invoke_wps_process_credentials(const char *object_path)
712 {
713         gboolean reply = FALSE;
714         GVariant *params = NULL;
715         const char *interface = SUPPLICANT_IFACE_WPS;
716         const char *key = "ProcessCredentials";
717         gboolean credentials = TRUE;
718         GVariant *var = NULL;
719
720          var = g_variant_new_boolean(credentials);
721         params = g_variant_new("(ssv)", interface, key, var);
722
723         INFO("[net-config]: TizenMW-->WPAS: .Set");
724         reply = netconfig_invoke_dbus_method_nonblock(SUPPLICANT_SERVICE,
725                         object_path, DBUS_INTERFACE_PROPERTIES,
726                         "Set", params, __netconfig_wifi_invoke_wps_connect);
727
728         if (reply != TRUE)
729                 ERR("M/W--->WPAS: Interface.WPS.Set Method Failed");
730
731         return reply;
732 }
733
734 gboolean netconfig_wifi_wps_connect()
735 {
736         const char *if_path = NULL;
737
738         if_path = netconfig_wifi_get_supplicant_interface();
739         if (if_path == NULL) {
740                 DBG("Fail to get wpa_supplicant DBus path");
741                  return FALSE;
742         }
743
744         if (__netconfig_wifi_invoke_wps_process_credentials(if_path) == TRUE) {
745                 ERR("Wi-Fi WPS Connect started");
746
747                 return TRUE;
748         }
749
750         return FALSE;
751 }
752
753 static void __interface_wps_cancel_result(GObject *source_object,
754                         GAsyncResult *res, gpointer user_data)
755 {
756         GVariant *reply;
757         GDBusConnection *conn = NULL;
758         GError *error = NULL;
759
760         conn = G_DBUS_CONNECTION(source_object);
761         reply = g_dbus_connection_call_finish(conn, res, &error);
762
763         if (reply == NULL) {
764                 if (error != NULL) {
765                         ERR("Fail to request status [%d: %s]",
766                                         error->code, error->message);
767                         g_error_free(error);
768                 } else {
769                         ERR("Fail torequest status");
770                 }
771         } else {
772                 DBG("Successfully M/W--->WPAS: Interface.WPS.Cancel Method");
773         }
774
775         g_variant_unref(reply);
776         netconfig_gdbus_pending_call_unref();
777 }
778
779 static gboolean __netconfig_wifi_invoke_wps_cancel()
780 {
781         gboolean reply = FALSE;
782         const char *if_path = NULL;
783
784         if_path = netconfig_wifi_get_supplicant_interface();
785         if (if_path == NULL) {
786                 DBG("Fail to get wpa_supplicant DBus path");
787                 return -ESRCH;
788         }
789
790         DBG("M/W--->WPAS: Interface.WPS.Cancel Method");
791
792         reply = netconfig_invoke_dbus_method_nonblock(SUPPLICANT_SERVICE,
793                         if_path, SUPPLICANT_IFACE_WPS,
794                         "Cancel", NULL, __interface_wps_cancel_result);
795
796         if (reply != TRUE)
797                 ERR("M/W--->WPAS: Interface.WPS.Cancel Method Failed");
798
799         return reply;
800 }
801
802 gboolean netconfig_get_wps_field()
803 {
804         return wifi_wps.pbc;
805 }
806
807 gboolean handle_request_wps_cancel(Wifi *wifi, GDBusMethodInvocation *context)
808 {
809         INFO("Received WPS PBC Cancel Request");
810         g_return_val_if_fail(wifi != NULL, FALSE);
811         __netconfig_wifi_invoke_wps_cancel();
812
813         wifi_complete_request_wps_cancel(wifi, context);
814         return TRUE;
815 }
816
817 gboolean handle_request_wps_connect(Wifi *wifi, GDBusMethodInvocation *context, gchar *param)
818 {
819         INFO("Received WPS PBC/PIN Connection Request");
820
821         g_return_val_if_fail(wifi != NULL, FALSE);
822
823         /* Checking the value of pin if param have a string "PBC"
824          * in that scenario PBC will trigger otherwise PIN Connection */
825
826         if (g_strcmp0(param, "PBC") == 0) {
827                 wifi_wps.pbc = TRUE;
828                 wifi_wps.pin = NULL;
829         } else {
830                 wifi_wps.pin = g_strdup(param);
831                 wifi_wps.pbc = FALSE;
832         }
833
834         netconfig_wifi_wps_connect();
835
836         wifi_complete_request_wps_connect(wifi, context);
837         return TRUE;
838 }