Use rand_r() instead of rand()
[platform/core/connectivity/net-config.git] / src / wifi-dpp.c
1 /*
2  * Network Configuration Module
3  *
4  * Copyright (c) 2019 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 #include <string.h>
20 #include <glib.h>
21
22 #include <vconf.h>
23 #include <vconf-keys.h>
24
25 #include "log.h"
26 #include "util.h"
27 #include "netdbus.h"
28 #include "netsupplicant.h"
29 #include "neterror.h"
30 #include "wifi-config.h"
31 #include "wifi-dpp.h"
32 #include "wifi-key-encryption.h"
33
34 #define DEFAULT_BOOTSTRAP_TYPE "qrcode"
35 #define DEFAULT_DPP_CHANNEL "81/6"
36 #define DEFAULT_DPP_FREQ 2437
37
38 #define DEFAULT_DPP_CONFIG_PROCESSING_TYPE "0"
39
40 #define MACADDR_LEN 6
41 #define MACSTR_LEN 18
42 #define MAC2STR(a) (a)[0], (a)[1], (a)[2], (a)[3], (a)[4], (a)[5]
43 #define MACSTR "%02x:%02x:%02x:%02x:%02x:%02x"
44
45 typedef enum {
46         WIFI_DPP_AKM_UNKNOWN,
47         WIFI_DPP_AKM_PSK,
48         WIFI_DPP_AKM_SAE,
49         WIFI_DPP_AKM_DPP,
50 } wifi_dpp_akm_e;
51
52 typedef enum {
53         WIFI_DPP_STATE_NONE,
54         WIFI_DPP_STATE_AWAITING,
55         WIFI_DPP_STATE_PEER_QR_REQUESTED,
56         WIFI_DPP_STATE_BOOTSTRAPPED,
57         WIFI_DPP_STATE_AUTHENTICATING,
58         WIFI_DPP_STATE_AUTHENTICATED,
59         WIFI_DPP_STATE_CONFIGURED,
60         WIFI_DPP_STATE_CONNECTING,
61         WIFI_DPP_STATE_CONNECTED,
62 } wifi_dpp_state_e;
63
64 typedef struct {
65         gchar *ssid;
66         gchar *akm;
67         gchar *passphrase;
68         gchar *connector;
69         gchar *c_sign_key;
70         gchar *net_access_key;
71 } wifi_dpp_conf_obj;
72
73 typedef struct {
74         guint32 peer_id;
75         guint32 own_id;
76         guint32 configurator_id;
77         gboolean is_initiator;
78         wifi_dpp_state_e state;
79 } wifi_dpp_s;
80
81 gboolean g_in_progress = FALSE;
82 static GSList *dpp_info_list = NULL;
83
84 static wifi_dpp_s *_get_dpp_info(guint32 peer_id, guint32 own_id)
85 {
86         wifi_dpp_s *ret = NULL;
87         GSList *list = NULL;
88
89         for (list = dpp_info_list; list; list = list->next) {
90                 ret = list->data;
91                 if (ret->own_id == own_id && ret->peer_id == peer_id)
92                         break;
93                 ret = NULL;
94         }
95         return ret;
96 }
97
98 static wifi_dpp_s *_get_dpp_in_progress()
99 {
100         wifi_dpp_s *ret = NULL;
101         GSList *list = NULL;
102
103         for (list = dpp_info_list; list; list = list->next) {
104                 ret = list->data;
105                 if (ret->state > WIFI_DPP_STATE_NONE)
106                         break;
107                 ret = NULL;
108         }
109         return ret;
110 }
111
112 static wifi_dpp_s *__create_dpp_info(gboolean is_initiator)
113 {
114         wifi_dpp_s *ret = g_try_malloc0(sizeof(wifi_dpp_s));
115         if (ret)
116                 ret->is_initiator = is_initiator;
117
118         return ret;
119 }
120
121 static void __add_to_dpp_info_list(wifi_dpp_s * p_dpp)
122 {
123         dpp_info_list = g_slist_prepend(dpp_info_list, p_dpp);
124 }
125
126 static void __remove_from_dpp_info_list(wifi_dpp_s * p_dpp)
127 {
128         dpp_info_list = g_slist_remove(dpp_info_list, p_dpp);
129 }
130
131 static void __destroy_dpp_info(wifi_dpp_s *p_dpp)
132 {
133         g_free(p_dpp);
134 }
135
136
137 static void __free_critical(char *critical)
138 {
139         size_t length = 0;
140         if (!critical)
141                 return;
142
143         length = strlen(critical);
144         memset((void *)critical, 0x0, length);
145         g_free(critical);
146 }
147
148 static void __netconfig_wifi_notify_dpp_uri_generated(guint32 own_id, const gchar *own_uri)
149 {
150         GVariantBuilder *builder = NULL;
151
152         builder = g_variant_builder_new(G_VARIANT_TYPE("a{sv}"));
153         g_variant_builder_add(builder, "{sv}", "own_id", g_variant_new_uint32(own_id));
154         g_variant_builder_add(builder, "{sv}", "own_uri", g_variant_new_string(own_uri));
155
156         wifi_emit_dpp_uri_generated((Wifi *)get_wifi_object(), g_variant_builder_end(builder));
157         g_variant_builder_unref(builder);
158
159         return;
160 }
161
162 static void __netconfig_wifi_notify_dpp_bootstrapped(guint32 peer_id)
163 {
164         GVariantBuilder *builder = NULL;
165
166         builder = g_variant_builder_new(G_VARIANT_TYPE("a{sv}"));
167         g_variant_builder_add(builder, "{sv}", "peer_id", g_variant_new_uint32(peer_id));
168
169         wifi_emit_dpp_bootstrapped((Wifi *)get_wifi_object(), g_variant_builder_end(builder));
170         g_variant_builder_unref(builder);
171
172         return;
173 }
174
175 static void __netconfig_wifi_notify_dpp_awaiting(guint32 own_id)
176 {
177         GVariantBuilder *builder = NULL;
178
179         builder = g_variant_builder_new(G_VARIANT_TYPE("a{sv}"));
180         g_variant_builder_add(builder, "{sv}", "own_id", g_variant_new_uint32(own_id));
181
182         wifi_emit_dpp_awaiting((Wifi *)get_wifi_object(), g_variant_builder_end(builder));
183         g_variant_builder_unref(builder);
184
185         return;
186 }
187
188 static void __netconfig_wifi_notify_dpp_authenticating(guint32 peer_id, guint32 own_id)
189 {
190         GVariantBuilder *builder = NULL;
191
192         builder = g_variant_builder_new(G_VARIANT_TYPE("a{sv}"));
193         g_variant_builder_add(builder, "{sv}", "peer_id", g_variant_new_uint32(peer_id));
194         g_variant_builder_add(builder, "{sv}", "own_id", g_variant_new_uint32(own_id));
195
196         wifi_emit_dpp_authenticating((Wifi *)get_wifi_object(), g_variant_builder_end(builder));
197         g_variant_builder_unref(builder);
198
199         return;
200 }
201
202 static void __netconfig_wifi_notify_dpp_failed()
203 {
204         wifi_emit_dpp_failed((Wifi *)get_wifi_object());
205
206         return;
207 }
208
209 static void __netconfig_wifi_notify_dpp_removed(guint32 peer_id, guint32 own_id)
210 {
211         GVariantBuilder *builder = NULL;
212
213         builder = g_variant_builder_new(G_VARIANT_TYPE("a{sv}"));
214         g_variant_builder_add(builder, "{sv}", "peer_id", g_variant_new_uint32(peer_id));
215         g_variant_builder_add(builder, "{sv}", "own_id", g_variant_new_uint32(own_id));
216
217         wifi_emit_dpp_removed((Wifi *)get_wifi_object(), g_variant_builder_end(builder));
218         g_variant_builder_unref(builder);
219
220         return;
221 }
222
223 static char *__netconfig_dpp_get_supplicant_interface()
224 {
225         char *if_path = NULL;
226
227         if_path = netconfig_wifi_get_supplicant_p2p_interface();
228         if (if_path)
229                 return if_path;
230
231         if_path = netconfig_wifi_get_supplicant_interface_path(NULL);
232
233         return if_path;
234 }
235
236 static gboolean __netconfig_wifi_invoke_dpp_set_dpp_config_processing()
237 {
238         char *if_path = NULL;
239         GVariant *message = NULL;
240         GVariant *params = NULL;
241
242         DBG("[TizenMW-->WPAS]: DPP Set config processing Request: ");
243
244         if_path = __netconfig_dpp_get_supplicant_interface();
245         if (if_path == NULL) {
246                 ERR("Fail to get wpa_supplicant DBus interface path");
247                 return FALSE;
248         }
249
250         params = g_variant_new("(ssv)", SUPPLICANT_INTERFACE ".Interface",
251                         "DppConfigProcessing", g_variant_new_string(DEFAULT_DPP_CONFIG_PROCESSING_TYPE));
252
253         message = netconfig_invoke_dbus_method(SUPPLICANT_SERVICE,
254                         if_path, DBUS_INTERFACE_PROPERTIES, "Set", params);
255         g_free(if_path);
256         if (message == NULL) {
257                 ERR(" DPP : Failed to set DPP config processing !!!");
258                 return FALSE;
259         }
260
261         g_variant_unref(message);
262         return TRUE;
263 }
264
265 static gboolean __netconfig_wifi_invoke_dpp_qr_code(const char *peer_uri, guint32 *peer_id)
266 {
267         char *if_path = NULL;
268         GVariant *message = NULL;
269         GVariant *params = NULL;
270
271         DBG("[TizenMW-->WPAS]: DPP QrCode Request: ");
272
273         if_path = __netconfig_dpp_get_supplicant_interface();
274         if (if_path == NULL) {
275                 ERR("Fail to get wpa_supplicant DBus interface path");
276                 return FALSE;
277         }
278
279         params = g_variant_new("(s)", peer_uri);
280         message = netconfig_invoke_dbus_method(SUPPLICANT_SERVICE,
281                         if_path, SUPPLICANT_INTERFACE ".Interface.DPP", "QrCode", params);
282         g_free(if_path);
283         if (message == NULL) {
284                 ERR(" DPP : Failed to set peer URI !!!");
285                 return FALSE;
286         }
287
288         g_variant_get(message, "(u)", peer_id);
289         INFO("DPP reply: [%u]", *peer_id);
290
291         g_variant_unref(message);
292         return TRUE;
293 }
294 #define DEBUG_G_VARIANT(str, parameters)\
295         do {\
296                 gchar *parameters_debug_str = NULL;\
297                 if (parameters)\
298                         parameters_debug_str = g_variant_print(parameters, TRUE);\
299                         DBG("%s[%s]", str, parameters_debug_str ? parameters_debug_str : "NULL");\
300                 g_free(parameters_debug_str);\
301         } while (0)
302
303
304 static int __ws_unpack_ay(unsigned char *dst, GVariant *src, int size)
305 {
306         GVariantIter *iter = NULL;
307         int length = 0;
308
309         if (!dst || !src || size == 0) {
310                 DBG("Invalid parameter");
311                 return -1;
312         }
313         g_variant_get(src, "ay", &iter);
314         if (iter == NULL) {
315                 DBG("failed to get iterator");
316                 return -1;
317         }
318
319         while (g_variant_iter_loop(iter, "y", &dst[length])) {
320                 length++;
321                 if (length >= size)
322                         break;
323         }
324         g_variant_iter_free(iter);
325
326         return length;
327 }
328
329 static gchar *__netconfig_get_p2p_address(const char *if_path)
330 {
331         GVariant *params = NULL;
332         GVariant *message = NULL;
333         GVariant *temp1 = NULL;
334         GVariant *temp2 = NULL;
335         guchar p2p_addr[MACADDR_LEN] = {0,};
336         gchar address_str[MACSTR_LEN] = {0,};
337
338         params = g_variant_new("(ss)", SUPPLICANT_INTERFACE ".Interface", "P2PAddress");
339
340         message = netconfig_invoke_dbus_method(SUPPLICANT_SERVICE,
341                         if_path,
342                         DBUS_INTERFACE_PROPERTIES,
343                         "Get",
344                         params);
345
346         if (message == NULL) {
347                 ERR("netconfig_supplicant_invoke_dbus_method() failed.");
348                 return NULL;
349         }
350         DEBUG_G_VARIANT("reply:", message);
351
352         temp1 = g_variant_get_child_value(message, 0);
353         temp2 = g_variant_get_child_value(temp1, 0);
354         DEBUG_G_VARIANT("temp2:", temp2);
355         __ws_unpack_ay(p2p_addr, temp2, MACADDR_LEN);
356         g_variant_unref(temp1);
357         g_variant_unref(temp2);
358         g_variant_unref(message);
359
360         g_snprintf(address_str, MACSTR_LEN, MACSTR, MAC2STR(p2p_addr));
361
362         DBG("P2P address %s", address_str);
363
364         return g_strdup(address_str);
365 }
366
367 static gboolean __netconfig_wifi_invoke_dpp_add_bootstrap(const char *key, guint32 *id)
368 {
369         char *if_path = NULL;
370         GVariantBuilder *builder = NULL;
371         GVariant *params = NULL;
372         GVariant *message = NULL;
373         gchar *current_mac_addr = NULL;
374
375         DBG("[TizenMW-->WPAS]: DPP AddBootstrap Request: ");
376
377         if_path = __netconfig_dpp_get_supplicant_interface();
378         if (if_path == NULL) {
379                 ERR("Fail to get wpa_supplicant DBus interface path");
380                 return FALSE;
381         }
382         builder = g_variant_builder_new(G_VARIANT_TYPE("a{sv}"));
383         g_variant_builder_add(builder, "{sv}", "type", g_variant_new_string("qrcode"));
384         g_variant_builder_add(builder, "{sv}", "channels", g_variant_new_string(DEFAULT_DPP_CHANNEL));
385         /* TODO: find more comfortable way */
386         current_mac_addr = __netconfig_get_p2p_address(if_path);
387         if (current_mac_addr)
388                 g_variant_builder_add(builder, "{sv}", "mac", g_variant_new_string(current_mac_addr));
389         if (key)
390                 g_variant_builder_add(builder, "{sv}", "key", g_variant_new_string(key));
391         params = g_variant_new("(@a{sv})", g_variant_builder_end(builder));
392         g_variant_builder_unref(builder);
393
394         message = netconfig_invoke_dbus_method(SUPPLICANT_SERVICE,
395                         if_path, SUPPLICANT_INTERFACE ".Interface.DPP", "AddBootstrap", params);
396         g_free(if_path);
397         g_free(current_mac_addr);
398         if (message == NULL) {
399                 ERR(" DPP : Failed to add bootstrap !!!");
400                 return FALSE;
401         }
402
403         g_variant_get(message, "(u)", id);
404         INFO("DPP reply: [%u]", *id);
405
406         g_variant_unref(message);
407         return TRUE;
408 }
409
410 static gboolean __netconfig_wifi_invoke_dpp_get_bootstrap_uri(guint32 id, gchar **uri)
411 {
412         char *if_path = NULL;
413         GVariant *message = NULL;
414         GVariant *params = NULL;
415
416         if (id == 0) {
417                 DBG("Invalid ID");
418                 return FALSE;
419         }
420
421         DBG("[TizenMW-->WPAS]: DPP GetBootstrapUri Request: ");
422
423         if_path = __netconfig_dpp_get_supplicant_interface();
424         if (if_path == NULL) {
425                 ERR("Fail to get wpa_supplicant DBus interface path");
426                 return FALSE;
427         }
428
429         params = g_variant_new("(u)", id);
430         message = netconfig_invoke_dbus_method(SUPPLICANT_SERVICE,
431                         if_path, SUPPLICANT_INTERFACE ".Interface.DPP", "GetBootstrapUri", params);
432         g_free(if_path);
433         if (message == NULL) {
434                 ERR(" DPP : Failed to get URI !!!");
435                 return FALSE;
436         }
437
438         g_variant_get(message, "(s)", uri);
439         INFO("DPP reply: [%s]", *uri);
440
441         g_variant_unref(message);
442         return TRUE;
443 }
444
445 static gboolean __netconfig_wifi_invoke_dpp_add_configurator(const char *key, guint32 *id)
446 {
447         char *if_path = NULL;
448         GVariantBuilder *builder = NULL;
449         GVariant *params = NULL;
450         GVariant *message = NULL;
451
452         DBG("[TizenMW-->WPAS]: DPP AddConfigurator Request: ");
453
454         if_path = __netconfig_dpp_get_supplicant_interface();
455         if (if_path == NULL) {
456                 ERR("Fail to get wpa_supplicant DBus interface path");
457                 return FALSE;
458         }
459         builder = g_variant_builder_new(G_VARIANT_TYPE("a{sv}"));
460         if (key)
461                 g_variant_builder_add(builder, "{sv}", "key", g_variant_new_string(key));
462         params = g_variant_new("(@a{sv})", g_variant_builder_end(builder));
463         g_variant_builder_unref(builder);
464
465         message = netconfig_invoke_dbus_method(SUPPLICANT_SERVICE,
466                         if_path, SUPPLICANT_INTERFACE ".Interface.DPP", "AddConfigurator", params);
467         g_free(if_path);
468         if (message == NULL) {
469                 ERR(" DPP : Failed to add configurator !!!");
470                 return FALSE;
471         }
472
473         g_variant_get(message, "(u)", id);
474         INFO("DPP reply: [%u]", *id);
475
476         g_variant_unref(message);
477         return TRUE;
478 }
479
480 static gchar *__generate_configurator_params(guint32 configurator_id, const char *ssid,
481                 const char *net_role, const char *akm, const char *pass)
482 {
483         gchar ssid_hex[65] = {0,};
484         gchar pass_hex[129] = {0,};
485         gchar *ret = NULL;
486
487         gchar *conf_str = NULL;
488
489         netconfig_convert_bytes_to_hexstr(ssid, strlen(ssid), ssid_hex);
490         conf_str = g_strdup_printf(" ssid=%s conf=%s-%s", ssid_hex, net_role, akm);
491
492         if (pass) {
493                 netconfig_convert_bytes_to_hexstr(pass, strlen(pass), pass_hex);
494                 ret = g_strdup_printf("%s pass=%s", conf_str, pass_hex);
495         } else {
496                 ret = g_strdup_printf(" configurator=%u%s", configurator_id, conf_str);
497         }
498         g_free(conf_str);
499
500         return ret;
501 }
502
503 static gboolean __netconfig_wifi_invoke_dpp_set_configurator_params(guint configurator_id,
504                 const char *ssid, const char *net_role, const char *akm, const char *pass)
505 {
506         char *if_path = NULL;
507         GVariant *message = NULL;
508         GVariant *params = NULL;
509         gchar *configurator_param_str = NULL;
510
511         DBG("[TizenMW-->WPAS]: DPP Set configurator params Request: ");
512
513         if_path = __netconfig_dpp_get_supplicant_interface();
514         if (if_path == NULL) {
515                 ERR("Fail to get wpa_supplicant DBus interface path");
516                 return FALSE;
517         }
518
519         configurator_param_str = __generate_configurator_params(
520                         configurator_id, ssid, net_role, akm, pass);
521         if (!configurator_param_str) {
522                 ERR(" DPP : Failed to gen conf params");
523                 g_free(if_path);
524                 return FALSE;
525         }
526         params = g_variant_new("(ssv)", SUPPLICANT_INTERFACE ".Interface",
527                         "DPPConfiguratorParams", g_variant_new_string(configurator_param_str));
528
529         message = netconfig_invoke_dbus_method(SUPPLICANT_SERVICE,
530                         if_path, DBUS_INTERFACE_PROPERTIES, "Set", params);
531         g_free(if_path);
532         g_free(configurator_param_str);
533         if (message == NULL) {
534                 ERR(" DPP : Failed to set configurator params !!!");
535                 return FALSE;
536         }
537
538         g_variant_unref(message);
539         return TRUE;
540 }
541
542 static gboolean __netconfig_wifi_invoke_dpp_listen(guint32 freq, const gchar *dev_role)
543 {
544         char *if_path = NULL;
545         GVariantBuilder *builder = NULL;
546         GVariant *params = NULL;
547         GVariant *message = NULL;
548
549         DBG("[TizenMW-->WPAS]: DPP Listen Request: ");
550
551         if_path = __netconfig_dpp_get_supplicant_interface();
552         if (if_path == NULL) {
553                 ERR("Fail to get wpa_supplicant DBus interface path");
554                 return FALSE;
555         }
556         builder = g_variant_builder_new(G_VARIANT_TYPE("a{sv}"));
557         g_variant_builder_add(builder, "{sv}", "freq", g_variant_new_uint32(freq));
558         g_variant_builder_add(builder, "{sv}", "role", g_variant_new_string(dev_role));
559         params = g_variant_new("(@a{sv})", g_variant_builder_end(builder));
560         g_variant_builder_unref(builder);
561
562         message = netconfig_invoke_dbus_method(SUPPLICANT_SERVICE,
563                         if_path, SUPPLICANT_INTERFACE ".Interface.DPP", "Listen", params);
564         g_free(if_path);
565         if (message == NULL) {
566                 ERR(" DPP : Failed to start DPP listen !!!");
567                 return FALSE;
568         }
569
570         g_variant_unref(message);
571         return TRUE;
572 }
573
574 static gboolean __netconfig_wifi_invoke_auth_init_enrollee(guint32 peer_id)
575 {
576         char *if_path = NULL;
577         GVariantBuilder *builder = NULL;
578         GVariant *params = NULL;
579         GVariant *message = NULL;
580
581         DBG("[TizenMW-->WPAS]: DPP AuthInit Request: ");
582
583         if_path = __netconfig_dpp_get_supplicant_interface();
584         if (if_path == NULL) {
585                 ERR("Fail to get wpa_supplicant DBus interface path");
586                 return FALSE;
587         }
588         builder = g_variant_builder_new(G_VARIANT_TYPE("a{sv}"));
589         g_variant_builder_add(builder, "{sv}", "peer", g_variant_new_uint32(peer_id));
590         g_variant_builder_add(builder, "{sv}", "role", g_variant_new_string("enrollee"));
591         params = g_variant_new("(@a{sv})", g_variant_builder_end(builder));
592         g_variant_builder_unref(builder);
593
594         message = netconfig_invoke_dbus_method(SUPPLICANT_SERVICE,
595                         if_path, SUPPLICANT_INTERFACE ".Interface.DPP", "AuthInit", params);
596         g_free(if_path);
597         if (message == NULL) {
598                 ERR(" DPP : Failed to start DPP AuthInit !!!");
599                 return FALSE;
600         }
601
602         g_variant_unref(message);
603         return TRUE;
604 }
605
606 static gboolean __netconfig_wifi_invoke_auth_init_configurator(guint32 peer_id,
607                 guint32 configurator_id, const char *conf, const char *ssid, const char *pass)
608 {
609         char *if_path = NULL;
610         GVariantBuilder *builder = NULL;
611         GVariant *params = NULL;
612         GVariant *message = NULL;
613         gchar ssid_hex[65] = {0,};
614         gchar pass_hex[129] = {0,};
615
616         DBG("[TizenMW-->WPAS]: DPP AuthInit Request: ");
617
618         if_path = __netconfig_dpp_get_supplicant_interface();
619         if (if_path == NULL) {
620                 ERR("Fail to get wpa_supplicant DBus interface path");
621                 return FALSE;
622         }
623         builder = g_variant_builder_new(G_VARIANT_TYPE("a{sv}"));
624         g_variant_builder_add(builder, "{sv}", "peer", g_variant_new_uint32(peer_id));
625         g_variant_builder_add(builder, "{sv}", "configurator", g_variant_new_uint32(configurator_id));
626         g_variant_builder_add(builder, "{sv}", "role", g_variant_new_string("configurator"));
627         g_variant_builder_add(builder, "{sv}", "conf", g_variant_new_string(conf));
628         if (ssid) {
629                 netconfig_convert_bytes_to_hexstr(ssid, strlen(ssid), ssid_hex);
630                 g_variant_builder_add(builder, "{sv}", "ssid", g_variant_new_string(ssid_hex));
631         }
632         if (pass) {
633                 netconfig_convert_bytes_to_hexstr(pass, strlen(pass), pass_hex);
634                 g_variant_builder_add(builder, "{sv}", "passphrase", g_variant_new_string(pass_hex));
635         }
636         params = g_variant_new("(@a{sv})", g_variant_builder_end(builder));
637         g_variant_builder_unref(builder);
638
639         message = netconfig_invoke_dbus_method(SUPPLICANT_SERVICE,
640                         if_path, SUPPLICANT_INTERFACE ".Interface.DPP", "AuthInit", params);
641         g_free(if_path);
642         if (message == NULL) {
643                 ERR(" DPP : Failed to start DPP AuthInit !!!");
644                 return FALSE;
645         }
646
647         g_variant_unref(message);
648         return TRUE;
649 }
650
651 static void __netconfig_wifi_invoke_dpp_stop_listen()
652 {
653         char *if_path = NULL;
654         GVariant *message = NULL;
655
656         DBG("[TizenMW-->WPAS]: DPP StopListen Request: ");
657
658         if_path = __netconfig_dpp_get_supplicant_interface();
659         if (if_path == NULL) {
660                 ERR("Fail to get wpa_supplicant DBus interface path");
661                 return;
662         }
663
664         message = netconfig_invoke_dbus_method(SUPPLICANT_SERVICE,
665                         if_path, SUPPLICANT_INTERFACE ".Interface.DPP", "StopListen", NULL);
666         g_free(if_path);
667         if (message == NULL) {
668                 ERR(" DPP : Failed to stop listen !!!");
669                 return;
670         }
671
672         g_variant_unref(message);
673         return;
674 }
675
676 static void __netconfig_wifi_invoke_dpp_remove_bootstrap(guint32 uri_id)
677 {
678         char *if_path = NULL;
679         GVariant *message = NULL;
680         GVariant *params = NULL;
681
682         if (uri_id == 0) {
683                 DBG("Invalid ID");
684                 return;
685         }
686
687         DBG("[TizenMW-->WPAS]: DPP RemoveBootstrap Request: ");
688
689         if_path = __netconfig_dpp_get_supplicant_interface();
690         if (if_path == NULL) {
691                 ERR("Fail to get wpa_supplicant DBus interface path");
692                 return;
693         }
694
695         params = g_variant_new("(u)", uri_id);
696         message = netconfig_invoke_dbus_method(SUPPLICANT_SERVICE,
697                         if_path, SUPPLICANT_INTERFACE ".Interface.DPP", "RemoveBootstrap", params);
698         g_free(if_path);
699         if (message == NULL) {
700                 ERR(" DPP : Failed to remove URI !!!");
701                 return;
702         }
703
704         g_variant_unref(message);
705         return;
706 }
707
708 static void __netconfig_wifi_invoke_dpp_remove_configurator(guint32 configurator_id)
709 {
710         char *if_path = NULL;
711         GVariant *message = NULL;
712         GVariant *params = NULL;
713
714         if (configurator_id == 0) {
715                 DBG("Invalid ID");
716                 return;
717         }
718
719         DBG("[TizenMW-->WPAS]: DPP RemoveConfigurator Request: ");
720
721         if_path = __netconfig_dpp_get_supplicant_interface();
722         if (if_path == NULL) {
723                 ERR("Fail to get wpa_supplicant DBus interface path");
724                 return;
725         }
726
727         params = g_variant_new("(u)", configurator_id);
728         message = netconfig_invoke_dbus_method(SUPPLICANT_SERVICE,
729                         if_path, SUPPLICANT_INTERFACE ".Interface.DPP", "RemoveConfigurator", params);
730         g_free(if_path);
731         if (message == NULL) {
732                 ERR(" DPP : Failed to remove configurator !!!");
733                 return;
734         }
735
736         g_variant_unref(message);
737         return;
738 }
739 /*
740 static void __wifi_dpp_connman_specific_scan_request_reply(GObject *source_object, GAsyncResult *res,
741                 gpointer user_data)
742 {
743         GDBusConnection *conn = NULL;
744         GError *error = NULL;
745         GVariant *reply;
746
747         conn = G_DBUS_CONNECTION(source_object);
748         reply = g_dbus_connection_call_finish(conn, res, &error);
749         if (error != NULL) {
750                 ERR("Scan failed. Error [%s]\n", error->message);
751                 g_error_free(error);
752         } else {
753                 DBG("Specific Scan Request success\n");
754         }
755
756         if (reply)
757                 g_variant_unref(reply);
758 }
759
760 static gboolean __netconfig_wifi_dpp_invoke_connman_specific_scan(gchar *ssid)
761 {
762         GVariant *params = NULL;
763         GVariantBuilder *builder;
764         gboolean ret;
765
766         builder = g_variant_builder_new(G_VARIANT_TYPE("a{sv}"));
767         g_variant_builder_add(builder, "{sv}", "SSID", g_variant_new_string(ssid));
768
769         params = g_variant_new("(@a{sv})", g_variant_builder_end(builder));
770         g_variant_builder_unref(builder);
771
772         ret = netconfig_invoke_dbus_method_nonblock(CONNMAN_SERVICE,
773                         CONNMAN_WIFI_TECHNOLOGY_PREFIX,
774                         CONNMAN_TECHNOLOGY_INTERFACE, "SpecificScan", params,
775                         __wifi_dpp_connman_specific_scan_request_reply);
776
777         return ret;
778 }
779 */
780 static void __wifi_dpp_connman_scan_request_reply(GObject *source_object, GAsyncResult *res,
781                 gpointer user_data)
782 {
783         GDBusConnection *conn = NULL;
784         GError *error = NULL;
785         GVariant *reply;
786
787         conn = G_DBUS_CONNECTION(source_object);
788         reply = g_dbus_connection_call_finish(conn, res, &error);
789         if (error != NULL) {
790                 ERR("Scan failed. Error [%s]\n", error->message);
791                 g_error_free(error);
792         } else {
793                 DBG("Scan Request success\n");
794         }
795
796         if (reply)
797                 g_variant_unref(reply);
798 }
799
800 static gboolean __netconfig_wifi_dpp_invoke_connman_scan()
801 {
802         return netconfig_invoke_dbus_method_nonblock(CONNMAN_SERVICE,
803                         CONNMAN_WIFI_TECHNOLOGY_PREFIX,
804                         CONNMAN_TECHNOLOGY_INTERFACE, "Scan", NULL,
805                         __wifi_dpp_connman_scan_request_reply, NULL);
806 }
807
808
809
810 static gboolean __netconfig_wifi_invoke_flush_bss()
811 {
812         GVariant *message = NULL;
813         char *if_path = NULL;
814         GVariant *params = NULL;
815
816         DBG("[TizenMW-->WPAS]: Wi-Fi Flush BSS Request: ");
817
818         if_path = netconfig_wifi_get_supplicant_interface_path(NULL);
819         if (if_path == NULL) {
820                 ERR("Fail to get wpa_supplicant DBus path");
821                 return FALSE;
822         }
823
824         params = g_variant_new("(u)", 0);
825         message = netconfig_invoke_dbus_method(SUPPLICANT_SERVICE,
826                         if_path, SUPPLICANT_INTERFACE ".Interface", "FlushBSS", params);
827
828         g_free(if_path);
829         if (message == NULL) {
830                 ERR(" Failed to flush BSS !!!");
831                 return FALSE;
832         }
833
834         g_variant_unref(message);
835         return TRUE;
836 }
837
838 static gboolean __netconfig_wifi_dpp_enter_peer_uri(GDBusMethodInvocation *context,
839                 guint32 peer_id, guint32 own_id, gboolean is_initiator, gchar *peer_uri)
840 {
841         wifi_dpp_s *p_dpp_info = NULL;
842         gboolean ret;
843
844         p_dpp_info = _get_dpp_info(peer_id, own_id);
845         if (!p_dpp_info) {
846                 ERR("Invalid parameter");
847                 return FALSE;
848         }
849
850         ret = __netconfig_wifi_invoke_dpp_qr_code(peer_uri, &(p_dpp_info->peer_id));
851         if (!ret)
852                 return FALSE;
853
854         __netconfig_wifi_notify_dpp_bootstrapped(p_dpp_info->peer_id);
855
856         return TRUE;
857 }
858
859 static gboolean __netconfig_wifi_dpp_generate_uri(GDBusMethodInvocation *context,
860                 guint32 peer_id, guint32 own_id, gboolean is_initiator, const gchar *key)
861 {
862         wifi_dpp_s *p_dpp_info = NULL;
863         guint32 id = 0;
864         gchar *generated_uri = NULL;
865         gboolean ret;
866
867         p_dpp_info = _get_dpp_info(peer_id, own_id);
868         if (!p_dpp_info) {
869                 ERR("Invalid parameter");
870                 return FALSE;
871         }
872
873         ret = __netconfig_wifi_invoke_dpp_add_bootstrap(key, &id);
874         if (!ret)
875                 return FALSE;
876
877         ret = __netconfig_wifi_invoke_dpp_get_bootstrap_uri(id, &generated_uri);
878         if (!ret) {
879                 __netconfig_wifi_invoke_dpp_remove_bootstrap(id);
880                 return FALSE;
881         }
882
883         p_dpp_info->own_id = id;
884         __netconfig_wifi_notify_dpp_uri_generated(id, generated_uri);
885         g_free(generated_uri);
886
887         return TRUE;
888 }
889
890 static gboolean __netconfig_wifi_dpp_start_configurator_initiator(GDBusMethodInvocation *context,
891                 const char *group_id, const char *ssid, const char *peer_uri, guint32 peer_id,
892                 const char *net_role, const char *akm, const char *configurator_key,
893                 const char *pass)
894 {
895         wifi_dpp_s *p_dpp_info = NULL;
896         guint32 id = 0;
897         char *conf_str = NULL;
898         gboolean ret = FALSE;
899
900         p_dpp_info = __create_dpp_info(TRUE);
901         if (!p_dpp_info) {
902                 INFO("Failed to create DPP info");
903                 return FALSE;
904         }
905
906         ret = __netconfig_wifi_invoke_dpp_qr_code(peer_uri, &(id));
907         if (!ret) {
908                 __destroy_dpp_info(p_dpp_info);
909                 return FALSE;
910         }
911
912         ret = __netconfig_wifi_invoke_dpp_add_configurator(configurator_key, &(p_dpp_info->configurator_id));
913         if (!ret) {
914                 __netconfig_wifi_invoke_dpp_remove_bootstrap(id);
915                 __destroy_dpp_info(p_dpp_info);
916                 return FALSE;
917         }
918         p_dpp_info->state = WIFI_DPP_STATE_BOOTSTRAPPED;
919         __netconfig_wifi_notify_dpp_bootstrapped(id);
920
921         conf_str = g_strdup_printf("%s-%s", net_role, akm);
922         ret = __netconfig_wifi_invoke_auth_init_configurator(id,
923                         p_dpp_info->configurator_id, conf_str, ssid, pass);
924         if (!ret) {
925                 __netconfig_wifi_invoke_dpp_remove_bootstrap(id);
926                 __destroy_dpp_info(p_dpp_info);
927                 g_free(conf_str);
928                 return FALSE;
929         }
930
931         p_dpp_info->is_initiator = TRUE;
932         p_dpp_info->peer_id = id;
933         __add_to_dpp_info_list(p_dpp_info);
934         p_dpp_info->state = WIFI_DPP_STATE_AUTHENTICATING;
935         __netconfig_wifi_notify_dpp_authenticating(id, p_dpp_info->own_id);
936
937         g_free(conf_str);
938
939         return TRUE;
940 }
941
942 static gboolean __netconfig_wifi_dpp_start_configurator_responder(GDBusMethodInvocation *context,
943                 const char *group_id, const char *ssid, const char *net_role,
944                 const char *akm, const char *auth_key, const char *configurator_key,
945                 const char *pass)
946 {
947         wifi_dpp_s *p_dpp_info = NULL;
948         gboolean ret = FALSE;
949         guint32 id = 0;
950         gchar *generated_uri = NULL;
951
952         p_dpp_info = __create_dpp_info(FALSE);
953         if (!p_dpp_info) {
954                 INFO("Failed to create DPP info");
955                 return FALSE;
956         }
957
958         ret = __netconfig_wifi_invoke_dpp_add_configurator(configurator_key, &(p_dpp_info->configurator_id));
959         if (!ret) {
960                 __destroy_dpp_info(p_dpp_info);
961                 return FALSE;
962         }
963
964         ret = __netconfig_wifi_invoke_dpp_set_configurator_params(p_dpp_info->configurator_id, ssid, net_role, akm, pass);
965         if (!ret) {
966                 __netconfig_wifi_invoke_dpp_remove_configurator(p_dpp_info->configurator_id);
967                 __destroy_dpp_info(p_dpp_info);
968                 return FALSE;
969         }
970
971         ret = __netconfig_wifi_invoke_dpp_add_bootstrap(auth_key, &id);
972         if (!ret) {
973                 __netconfig_wifi_invoke_dpp_remove_configurator(p_dpp_info->configurator_id);
974                 __destroy_dpp_info(p_dpp_info);
975                 return FALSE;
976         }
977
978         ret = __netconfig_wifi_invoke_dpp_get_bootstrap_uri(id, &generated_uri);
979         if (!ret) {
980                 __netconfig_wifi_invoke_dpp_remove_configurator(p_dpp_info->configurator_id);
981                 __netconfig_wifi_invoke_dpp_remove_bootstrap(id);
982                 __destroy_dpp_info(p_dpp_info);
983                 return FALSE;
984         }
985
986         __netconfig_wifi_notify_dpp_uri_generated(id, generated_uri);
987
988         ret = __netconfig_wifi_invoke_dpp_listen(DEFAULT_DPP_FREQ, "configurator");
989         if (!ret) {
990                 __netconfig_wifi_invoke_dpp_remove_configurator(p_dpp_info->configurator_id);
991                 __netconfig_wifi_invoke_dpp_remove_bootstrap(id);
992                 g_free(generated_uri);
993                 __destroy_dpp_info(p_dpp_info);
994                 return FALSE;
995         }
996
997         p_dpp_info->is_initiator = FALSE;
998         p_dpp_info->own_id = id;
999         __add_to_dpp_info_list(p_dpp_info);
1000         p_dpp_info->state = WIFI_DPP_STATE_AWAITING;
1001         __netconfig_wifi_notify_dpp_awaiting(id);
1002
1003         g_free(generated_uri);
1004
1005         return TRUE;
1006 }
1007
1008 static gboolean __netconfig_wifi_dpp_start_enrollee_initiator(GDBusMethodInvocation *context,
1009                 const char *peer_uri, guint32 peer_id)
1010 {
1011         wifi_dpp_s *p_dpp_info = NULL;
1012         guint32 id = 0;
1013         gboolean ret = FALSE;
1014
1015         p_dpp_info = __create_dpp_info(TRUE);
1016         if (!p_dpp_info) {
1017                 INFO("Failed to create DPP info");
1018                 return FALSE;
1019         }
1020
1021         ret = __netconfig_wifi_invoke_dpp_set_dpp_config_processing();
1022         if (!ret) {
1023                 __destroy_dpp_info(p_dpp_info);
1024                 return FALSE;
1025         }
1026
1027         ret = __netconfig_wifi_invoke_dpp_qr_code(peer_uri, &id);
1028         if (!ret) {
1029                 __destroy_dpp_info(p_dpp_info);
1030                 return FALSE;
1031         }
1032         p_dpp_info->state = WIFI_DPP_STATE_BOOTSTRAPPED;
1033         __netconfig_wifi_notify_dpp_bootstrapped(id);
1034
1035         ret = __netconfig_wifi_invoke_auth_init_enrollee(id);
1036         if (!ret) {
1037                 __netconfig_wifi_invoke_dpp_remove_bootstrap(id);
1038                 __destroy_dpp_info(p_dpp_info);
1039                 return FALSE;
1040         }
1041
1042         p_dpp_info->is_initiator = TRUE;
1043         p_dpp_info->peer_id = id;
1044         __add_to_dpp_info_list(p_dpp_info);
1045         p_dpp_info->state = WIFI_DPP_STATE_AUTHENTICATING;
1046         __netconfig_wifi_notify_dpp_authenticating(id, p_dpp_info->own_id);
1047
1048         return TRUE;
1049 }
1050
1051 static gboolean __netconfig_wifi_dpp_start_enrollee_responder(GDBusMethodInvocation *context,
1052                 const char *auth_key)
1053 {
1054         wifi_dpp_s *p_dpp_info = NULL;
1055         gboolean ret = FALSE;
1056         guint32 id = 0;
1057         gchar *generated_uri = NULL;
1058
1059         p_dpp_info = __create_dpp_info(FALSE);
1060         if (!p_dpp_info) {
1061                 INFO("Failed to create DPP info");
1062                 return FALSE;
1063         }
1064
1065         ret = __netconfig_wifi_invoke_dpp_set_dpp_config_processing();
1066         if (!ret) {
1067                 __destroy_dpp_info(p_dpp_info);
1068                 return FALSE;
1069         }
1070
1071         ret = __netconfig_wifi_invoke_dpp_add_bootstrap(auth_key, &id);
1072         if (!ret) {
1073                 __destroy_dpp_info(p_dpp_info);
1074                 return FALSE;
1075         }
1076
1077         ret = __netconfig_wifi_invoke_dpp_get_bootstrap_uri(id, &generated_uri);
1078         if (!ret) {
1079                 __netconfig_wifi_invoke_dpp_remove_bootstrap(id);
1080                 __destroy_dpp_info(p_dpp_info);
1081                 return FALSE;
1082         }
1083
1084         __netconfig_wifi_notify_dpp_uri_generated(id, generated_uri);
1085
1086         ret = __netconfig_wifi_invoke_dpp_listen(DEFAULT_DPP_FREQ, "enrollee");
1087         if (!ret) {
1088                 __netconfig_wifi_invoke_dpp_remove_bootstrap(id);
1089                 __destroy_dpp_info(p_dpp_info);
1090                 return FALSE;
1091         }
1092
1093         p_dpp_info->is_initiator = FALSE;
1094         p_dpp_info->own_id = id;
1095         __add_to_dpp_info_list(p_dpp_info);
1096         p_dpp_info->state = WIFI_DPP_STATE_AWAITING;
1097         __netconfig_wifi_notify_dpp_awaiting(id);
1098
1099         g_free(generated_uri);
1100
1101         return TRUE;
1102 }
1103
1104 static gboolean __netconfig_wifi_dpp_stop(GDBusMethodInvocation *context,
1105                 guint32 peer_id, guint32 own_id)
1106 {
1107         wifi_dpp_s *p_dpp_info = NULL;
1108
1109         p_dpp_info = _get_dpp_info(peer_id, own_id);
1110         if (!p_dpp_info) {
1111                 ERR("Invalid parameter");
1112                 return FALSE;
1113         }
1114
1115         __netconfig_wifi_invoke_dpp_stop_listen();
1116         __netconfig_wifi_invoke_dpp_remove_bootstrap(p_dpp_info->peer_id);
1117
1118         if (p_dpp_info->own_id != 0)
1119                 __netconfig_wifi_invoke_dpp_remove_bootstrap(p_dpp_info->own_id);
1120
1121         if (p_dpp_info->configurator_id != 0)
1122                 __netconfig_wifi_invoke_dpp_remove_configurator(p_dpp_info->configurator_id);
1123
1124         __remove_from_dpp_info_list(p_dpp_info);
1125         __destroy_dpp_info(p_dpp_info);
1126         __netconfig_wifi_notify_dpp_removed(peer_id, own_id);
1127
1128         return TRUE;
1129 }
1130
1131
1132 void netconfig_wifi_dpp_auth_success_event(GVariant *message)
1133 {
1134         wifi_dpp_s *p_dpp_info = NULL;
1135         GVariantBuilder *builder = NULL;
1136
1137         p_dpp_info = _get_dpp_in_progress();
1138         if (!p_dpp_info) {
1139                 ERR("DPP :there's no DPP in progress");
1140                 return;
1141         }
1142
1143         builder = g_variant_builder_new(G_VARIANT_TYPE("a{sv}"));
1144         g_variant_builder_add(builder, "{sv}", "peer_id", g_variant_new_uint32(p_dpp_info->peer_id));
1145         g_variant_builder_add(builder, "{sv}", "own_id", g_variant_new_uint32(p_dpp_info->own_id));
1146
1147         p_dpp_info->state = WIFI_DPP_STATE_AUTHENTICATED;
1148         wifi_emit_dpp_auth_success((Wifi *)get_wifi_object(), g_variant_builder_end(builder));
1149         g_variant_builder_unref(builder);
1150
1151
1152         return;
1153 }
1154
1155 static void __clear_dpp_process(wifi_dpp_s *p_dpp_info)
1156 {
1157         g_in_progress = FALSE;
1158         __netconfig_wifi_invoke_dpp_stop_listen();
1159
1160         __netconfig_wifi_invoke_dpp_remove_bootstrap(p_dpp_info->peer_id);
1161
1162         if (p_dpp_info->own_id != 0)
1163                 __netconfig_wifi_invoke_dpp_remove_bootstrap(p_dpp_info->own_id);
1164
1165         if (p_dpp_info->configurator_id != 0)
1166                 __netconfig_wifi_invoke_dpp_remove_configurator(p_dpp_info->configurator_id);
1167
1168         __remove_from_dpp_info_list(p_dpp_info);
1169         __netconfig_wifi_notify_dpp_removed(p_dpp_info->peer_id, p_dpp_info->own_id);
1170         __destroy_dpp_info(p_dpp_info);
1171 }
1172
1173 static void __resume_dpp_responder(wifi_dpp_s *p_dpp_info)
1174 {
1175         gchar *device_role = NULL;
1176         gboolean ret;
1177
1178         __netconfig_wifi_invoke_dpp_stop_listen();
1179
1180         if (p_dpp_info->configurator_id)
1181                 device_role = "configurator";
1182         else
1183                 device_role = "enrollee";
1184
1185         ret = __netconfig_wifi_invoke_dpp_listen(DEFAULT_DPP_FREQ, device_role);
1186         if (!ret) {
1187                 __clear_dpp_process(p_dpp_info);
1188         } else {
1189                 p_dpp_info->state = WIFI_DPP_STATE_AWAITING;
1190                 __netconfig_wifi_notify_dpp_awaiting(p_dpp_info->own_id);
1191         }
1192 }
1193
1194 static void __netconfig_wifi_dpp_wrap_up(wifi_dpp_s *p_dpp_info)
1195 {
1196         if (p_dpp_info->is_initiator)
1197                 __clear_dpp_process(p_dpp_info);
1198         else
1199                 __resume_dpp_responder(p_dpp_info);
1200 }
1201
1202 static void __netconfig_wifi_dpp_notify_dpp_failed(wifi_dpp_s *p_dpp_info)
1203 {
1204         GVariantBuilder *builder = NULL;
1205
1206         builder = g_variant_builder_new(G_VARIANT_TYPE("a{sv}"));
1207         g_variant_builder_add(builder, "{sv}", "peer_id", g_variant_new_uint32(p_dpp_info->peer_id));
1208         g_variant_builder_add(builder, "{sv}", "own_id", g_variant_new_uint32(p_dpp_info->own_id));
1209
1210         wifi_emit_dpp_auth_failed((Wifi *)get_wifi_object(), g_variant_builder_end(builder));
1211         g_variant_builder_unref(builder);
1212
1213         __netconfig_wifi_dpp_wrap_up(p_dpp_info);
1214 }
1215
1216 void netconfig_wifi_dpp_auth_failed_event(GVariant *message)
1217 {
1218         wifi_dpp_s *p_dpp_info = NULL;
1219         p_dpp_info = _get_dpp_in_progress();
1220         if (!p_dpp_info) {
1221                 ERR("DPP :there's no DPP in progress");
1222                 return;
1223         }
1224
1225         __netconfig_wifi_dpp_notify_dpp_failed(p_dpp_info);
1226
1227         return;
1228 }
1229
1230 void netconfig_wifi_dpp_not_compatible_event(GVariant *message)
1231 {
1232         wifi_dpp_s *p_dpp_info = NULL;
1233         GVariantBuilder *builder = NULL;
1234
1235         p_dpp_info = _get_dpp_in_progress();
1236         if (!p_dpp_info) {
1237                 ERR("DPP :there's no DPP in progress");
1238                 return;
1239         }
1240
1241         builder = g_variant_builder_new(G_VARIANT_TYPE("a{sv}"));
1242         g_variant_builder_add(builder, "{sv}", "peer_id", g_variant_new_uint32(p_dpp_info->peer_id));
1243         g_variant_builder_add(builder, "{sv}", "own_id", g_variant_new_uint32(p_dpp_info->own_id));
1244
1245         wifi_emit_dpp_not_compatible((Wifi *)get_wifi_object(), g_variant_builder_end(builder));
1246         g_variant_builder_unref(builder);
1247
1248         __netconfig_wifi_dpp_wrap_up(p_dpp_info);
1249
1250         return;
1251 }
1252
1253 void netconfig_wifi_dpp_conf_failed_event(GVariant *message)
1254 {
1255         wifi_dpp_s *p_dpp_info = NULL;
1256         GVariantBuilder *builder = NULL;
1257
1258         p_dpp_info = _get_dpp_in_progress();
1259         if (!p_dpp_info) {
1260                 ERR("DPP :there's no DPP in progress");
1261                 return;
1262         }
1263
1264         builder = g_variant_builder_new(G_VARIANT_TYPE("a{sv}"));
1265         g_variant_builder_add(builder, "{sv}", "peer_id", g_variant_new_uint32(p_dpp_info->peer_id));
1266         g_variant_builder_add(builder, "{sv}", "own_id", g_variant_new_uint32(p_dpp_info->own_id));
1267
1268         wifi_emit_dpp_conf_failed((Wifi *)get_wifi_object(), g_variant_builder_end(builder));
1269         g_variant_builder_unref(builder);
1270
1271         __netconfig_wifi_dpp_wrap_up(p_dpp_info);
1272
1273         return;
1274 }
1275
1276 void netconfig_wifi_dpp_scan_peer_qr_event(GVariant *message)
1277 {
1278         wifi_dpp_s *p_dpp_info = NULL;
1279         GVariantBuilder *builder = NULL;
1280
1281         p_dpp_info = _get_dpp_in_progress();
1282         if (!p_dpp_info) {
1283                 ERR("DPP :there's no DPP in progress");
1284                 return;
1285         }
1286
1287         builder = g_variant_builder_new(G_VARIANT_TYPE("a{sv}"));
1288         g_variant_builder_add(builder, "{sv}", "peer_id", g_variant_new_uint32(p_dpp_info->peer_id));
1289         g_variant_builder_add(builder, "{sv}", "own_id", g_variant_new_uint32(p_dpp_info->own_id));
1290
1291         wifi_emit_dpp_scan_peer_qr((Wifi *)get_wifi_object(), g_variant_builder_end(builder));
1292         g_variant_builder_unref(builder);
1293
1294         p_dpp_info->state = WIFI_DPP_STATE_PEER_QR_REQUESTED;
1295
1296         return;
1297 }
1298
1299 void netconfig_wifi_dpp_network_id_event(GVariant *message)
1300 {
1301         wifi_dpp_s *p_dpp_info = NULL;
1302         GVariantBuilder *builder = NULL;
1303
1304         p_dpp_info = _get_dpp_in_progress();
1305         if (!p_dpp_info) {
1306                 ERR("DPP :there's no DPP in progress");
1307                 return;
1308         }
1309
1310         builder = g_variant_builder_new(G_VARIANT_TYPE("a{sv}"));
1311         g_variant_builder_add(builder, "{sv}", "peer_id", g_variant_new_uint32(p_dpp_info->peer_id));
1312         g_variant_builder_add(builder, "{sv}", "own_id", g_variant_new_uint32(p_dpp_info->own_id));
1313
1314         wifi_emit_dpp_network_id((Wifi *)get_wifi_object(), g_variant_builder_end(builder));
1315         g_variant_builder_unref(builder);
1316
1317         return;
1318 }
1319
1320 void netconfig_wifi_dpp_conf_sent_event(GVariant *message)
1321 {
1322         wifi_dpp_s *p_dpp_info = NULL;
1323         GVariantBuilder *builder = NULL;
1324
1325         p_dpp_info = _get_dpp_in_progress();
1326         if (!p_dpp_info) {
1327                 ERR("DPP :there's no DPP in progress");
1328                 return;
1329         }
1330
1331         builder = g_variant_builder_new(G_VARIANT_TYPE("a{sv}"));
1332         g_variant_builder_add(builder, "{sv}", "peer_id", g_variant_new_uint32(p_dpp_info->peer_id));
1333         g_variant_builder_add(builder, "{sv}", "own_id", g_variant_new_uint32(p_dpp_info->own_id));
1334
1335         wifi_emit_dpp_conf_sent((Wifi *)get_wifi_object(), g_variant_builder_end(builder));
1336         g_variant_builder_unref(builder);
1337
1338         __netconfig_wifi_dpp_wrap_up(p_dpp_info);
1339
1340         return;
1341 }
1342
1343 void netconfig_wifi_dpp_conf_received_event(GVariant *message)
1344 {
1345         wifi_dpp_s *p_dpp_info = NULL;
1346         GVariantBuilder *builder = NULL;
1347
1348         p_dpp_info = _get_dpp_in_progress();
1349         if (!p_dpp_info) {
1350                 ERR("DPP :there's no DPP in progress");
1351                 return;
1352         }
1353
1354         builder = g_variant_builder_new(G_VARIANT_TYPE("a{sv}"));
1355         g_variant_builder_add(builder, "{sv}", "peer_id", g_variant_new_uint32(p_dpp_info->peer_id));
1356         g_variant_builder_add(builder, "{sv}", "own_id", g_variant_new_uint32(p_dpp_info->own_id));
1357
1358         wifi_emit_dpp_conf_received((Wifi *)get_wifi_object(), g_variant_builder_end(builder));
1359         g_variant_builder_unref(builder);
1360
1361         p_dpp_info->state = WIFI_DPP_STATE_CONFIGURED;
1362
1363         return;
1364 }
1365
1366 static wifi_dpp_akm_e __get_dpp_akm(const gchar *akm_str)
1367 {
1368         if (g_strcmp0(akm_str, "psk") == 0)
1369                 return WIFI_DPP_AKM_PSK;
1370         else if (g_strcmp0(akm_str, "sae") == 0)
1371                 return WIFI_DPP_AKM_SAE;
1372         else if (g_strcmp0(akm_str, "dpp") == 0)
1373                 return WIFI_DPP_AKM_DPP;
1374
1375         return WIFI_DPP_AKM_UNKNOWN;
1376 }
1377
1378 static gboolean __is_configuration_valid(wifi_dpp_akm_e akm, const gchar *passphrase,
1379                 const gchar *connector, const gchar *c_sign_key, const gchar *net_access_key)
1380 {
1381         if ((akm == WIFI_DPP_AKM_PSK || akm == WIFI_DPP_AKM_SAE) && passphrase)
1382                 return TRUE;
1383         else if (akm == WIFI_DPP_AKM_DPP && connector && c_sign_key && net_access_key)
1384                 return TRUE;
1385         return FALSE;
1386 }
1387
1388 gboolean __save_passphrase(GKeyFile *keyfile, gchar *group_name, gchar *key, gchar *value)
1389 {
1390         gchar *enc_data = NULL;
1391         gboolean ret = TRUE;
1392
1393         if (!value)
1394                 return ret;
1395
1396         enc_data = _netconfig_encrypt_passphrase(value);
1397         if (!enc_data) {
1398                 ERR("Failed to encrypt the passphrase");
1399                 ret = FALSE;
1400         } else {
1401                 g_key_file_set_string(keyfile, group_name, key, enc_data);
1402                 g_free(enc_data);
1403         }
1404
1405         return ret;
1406 }
1407
1408 gboolean __save_credentials(GKeyFile *keyfile, gchar *group_name, wifi_dpp_conf_obj *conf_obj)
1409 {
1410         gboolean ret;
1411
1412         ret = __save_passphrase(keyfile, group_name,
1413                         "Passphrase", conf_obj->passphrase);
1414         if (!ret)
1415                 return FALSE;
1416
1417         ret = __save_passphrase(keyfile, group_name,
1418                         "Connector", conf_obj->connector);
1419         if (!ret)
1420                 return FALSE;
1421
1422         ret = __save_passphrase(keyfile, group_name,
1423                         "CSignKey", conf_obj->c_sign_key);
1424         if (!ret)
1425                 return FALSE;
1426
1427         ret = __save_passphrase(keyfile, group_name,
1428                         "NetAccessKey", conf_obj->net_access_key);
1429         if (!ret)
1430                 return FALSE;
1431
1432         return TRUE;
1433 }
1434
1435
1436 static gboolean __save_configuration_object(const char *interface_name,
1437                 wifi_dpp_conf_obj *conf_obj)
1438 {
1439         gchar ssid_hex[65] = {0,};
1440         gchar *config_id = NULL;
1441         gchar *group_name = NULL;
1442         GKeyFile *keyfile = NULL;
1443         gboolean ret;
1444
1445         if (!conf_obj->ssid) {
1446                 ERR("DPP :there's no SSID in configuration");
1447                 return FALSE;
1448         }
1449
1450         if (!__is_configuration_valid(__get_dpp_akm(conf_obj->akm),
1451                         conf_obj->passphrase,
1452                         conf_obj->connector,
1453                         conf_obj->c_sign_key,
1454                         conf_obj->net_access_key)) {
1455                 ERR("DPP :Invalid AKM information in configuration");
1456                 return FALSE;
1457         }
1458
1459         netconfig_convert_bytes_to_hexstr(conf_obj->ssid, strlen(conf_obj->ssid), ssid_hex);
1460         config_id = g_strdup_printf("%s_managed_%s", ssid_hex, conf_obj->akm);
1461         ret = wifi_config_get_group_name("wifi_", interface_name, config_id, &group_name);
1462         if (!ret) {
1463                 ERR("Failed to get Wi-Fi config group name");
1464                 g_free(config_id);
1465                 return FALSE;
1466         }
1467
1468         keyfile = g_key_file_new();
1469         g_key_file_set_string(keyfile, group_name, "Name", conf_obj->ssid);
1470         g_key_file_set_string(keyfile, group_name, "SSID", ssid_hex);
1471
1472         if (!__save_credentials(keyfile, group_name, conf_obj)) {
1473                 g_key_file_free(keyfile);
1474                 g_free(config_id);
1475                 g_free(group_name);
1476                 return FALSE;
1477         }
1478
1479         g_key_file_set_boolean(keyfile, group_name, "Favorite", TRUE);
1480         g_key_file_set_boolean(keyfile, group_name, "AutoConnect", TRUE);
1481
1482         ret = wifi_config_save_configuration(interface_name, config_id, keyfile);
1483         if (ret == TRUE)
1484                 INFO("Success to save configuration [%s]", config_id);
1485         else
1486                 INFO("Fail to save configuration [%s]", config_id);
1487
1488         g_key_file_free(keyfile);
1489         g_free(config_id);
1490         g_free(group_name);
1491
1492         return ret;
1493
1494 }
1495
1496 void netconfig_wifi_dpp_conf_obj_event(const char *interface_name, GVariant *message)
1497 {
1498         GVariantIter *iter = NULL;
1499         gchar *key = NULL;
1500         GVariant *value = NULL;
1501         wifi_dpp_s *p_dpp_info = NULL;
1502         wifi_dpp_conf_obj conf_obj = {0,};
1503
1504         p_dpp_info = _get_dpp_in_progress();
1505         if (!p_dpp_info) {
1506                 ERR("DPP :there's no DPP in progress");
1507                 return;
1508         }
1509
1510         g_variant_get(message, "(a{sv})", &iter);
1511         while (g_variant_iter_loop(iter, "{sv}", &key, &value)) {
1512                 if (g_strcmp0(key, "ssid") == 0)
1513                         g_variant_get(value, "&s", &conf_obj.ssid);
1514                 else if (g_strcmp0(key, "akm") == 0)
1515                         g_variant_get(value, "&s", &conf_obj.akm);
1516                 else if (g_strcmp0(key, "passphrase") == 0)
1517                         g_variant_get(value, "&s", &conf_obj.passphrase);
1518                 else if (g_strcmp0(key, "connector") == 0)
1519                         g_variant_get(value, "&s", &conf_obj.connector);
1520                 else if (g_strcmp0(key, "c_sign_key") == 0)
1521                         g_variant_get(value, "&s", &conf_obj.c_sign_key);
1522                 else if (g_strcmp0(key, "net_access_key") == 0)
1523                         g_variant_get(value, "&s", &conf_obj.net_access_key);
1524         }
1525
1526         if (!__save_configuration_object(interface_name, &conf_obj) || !__netconfig_wifi_invoke_flush_bss()) {
1527                 g_variant_iter_free(iter);
1528                 __netconfig_wifi_dpp_notify_dpp_failed(p_dpp_info);
1529                 return;
1530         }
1531
1532         g_variant_iter_free(iter);
1533         __clear_dpp_process(p_dpp_info);
1534         __netconfig_wifi_dpp_invoke_connman_scan();
1535         return;
1536 }
1537
1538 gboolean handle_dpp_enter_peer_uri(Wifi *wifi, GDBusMethodInvocation *context, GVariant *dpp_info)
1539 {
1540         gboolean ret = FALSE;
1541         GVariantIter *iter;
1542         GVariant *value;
1543         gchar *field;
1544         guint32 peer_id = 0;
1545         guint32 own_id = 0;
1546         gboolean is_initiator = FALSE;
1547         gchar *uri = NULL;
1548
1549         INFO("Received DPP enter peer uri Request");
1550         if ((wifi == NULL) || (dpp_info == NULL)) {
1551                 ERR("Invalid arguments");
1552                 netconfig_error_dbus_method_return(context,
1553                                 NETCONFIG_ERROR_INVALID_PARAMETER, "InvalidArguments");
1554                 return TRUE;
1555         }
1556
1557         g_variant_get(dpp_info, "a{sv}", &iter);
1558         while (g_variant_iter_loop(iter, "{sv}", &field, &value)) {
1559                 if (g_strcmp0(field, "peer_id") == 0 &&
1560                                 g_variant_is_of_type(value, G_VARIANT_TYPE_UINT32)) {
1561                         peer_id = g_variant_get_uint32(value);
1562                 } else if (g_strcmp0(field, "own_id") == 0 &&
1563                                 g_variant_is_of_type(value, G_VARIANT_TYPE_UINT32)) {
1564                         own_id = g_variant_get_uint32(value);
1565
1566                 } else if (g_strcmp0(field, "uri") == 0 &&
1567                                 g_variant_is_of_type(value, G_VARIANT_TYPE_STRING)) {
1568                         g_free(uri);
1569                         uri = g_strdup(g_variant_get_string(value, NULL));
1570                 }
1571         }
1572
1573         if (!own_id || !uri){
1574                 g_variant_iter_free(iter);
1575                 g_free(uri);
1576                 ERR("Invalid arguments");
1577                 netconfig_error_dbus_method_return(context,
1578                                 NETCONFIG_ERROR_INVALID_PARAMETER, "InvalidArguments");
1579                 return TRUE;
1580         }
1581         wifi_complete_dpp_enter_peer_uri(wifi, context);
1582
1583         ret = __netconfig_wifi_dpp_enter_peer_uri(context, peer_id, own_id,
1584                         is_initiator, uri);
1585         if (ret == TRUE)
1586                 INFO("Success to enter peer uri");
1587         else
1588                 __netconfig_wifi_notify_dpp_failed();
1589
1590         g_variant_iter_free(iter);
1591         g_free(uri);
1592
1593         return TRUE;
1594 }
1595
1596 gboolean handle_dpp_generate_uri(Wifi *wifi, GDBusMethodInvocation *context, GVariant *dpp_info)
1597 {
1598         gboolean ret = FALSE;
1599         GVariantIter *iter;
1600         GVariant *value;
1601         gchar *field;
1602         guint32 peer_id = 0;
1603         guint32 own_id = 0;
1604         gboolean is_initiator = FALSE;
1605         gchar *key = NULL;
1606
1607         INFO("Received DPP gen own uri Request");
1608         if ((wifi == NULL) || (dpp_info == NULL)) {
1609                 ERR("Invalid arguments");
1610                 netconfig_error_dbus_method_return(context,
1611                                 NETCONFIG_ERROR_INVALID_PARAMETER, "InvalidArguments");
1612                 return TRUE;
1613         }
1614
1615         g_variant_get(dpp_info, "a{sv}", &iter);
1616         while (g_variant_iter_loop(iter, "{sv}", &field, &value)) {
1617                 if (g_strcmp0(field, "peer_id") == 0 &&
1618                                 g_variant_is_of_type(value, G_VARIANT_TYPE_UINT32)) {
1619                         peer_id = g_variant_get_uint32(value);
1620                 } else if (g_strcmp0(field, "own_id") == 0 &&
1621                                 g_variant_is_of_type(value, G_VARIANT_TYPE_UINT32)) {
1622                         own_id = g_variant_get_uint32(value);
1623
1624                 } else if (g_strcmp0(field, "is_initiator") == 0 &&
1625                                 g_variant_is_of_type(value, G_VARIANT_TYPE_BOOLEAN)) {
1626                         is_initiator = g_variant_get_boolean(value);
1627                 } else if (g_strcmp0(field, "key") == 0 &&
1628                                 g_variant_is_of_type(value, G_VARIANT_TYPE_STRING)) {
1629                         __free_critical(key);
1630                         key = g_strdup(g_variant_get_string(value, NULL));
1631                 }
1632         }
1633
1634         if (!peer_id){
1635                 __free_critical(key);
1636                 g_variant_iter_free(iter);
1637                 ERR("Invalid arguments");
1638                 netconfig_error_dbus_method_return(context,
1639                                 NETCONFIG_ERROR_INVALID_PARAMETER, "InvalidArguments");
1640                 return TRUE;
1641         }
1642         wifi_complete_dpp_generate_uri(wifi, context);
1643
1644         ret = __netconfig_wifi_dpp_generate_uri(context, peer_id, own_id,
1645                         is_initiator, key);
1646         if (ret == TRUE)
1647                 INFO("Success to generate uri");
1648         else
1649                 __netconfig_wifi_notify_dpp_failed();
1650
1651         g_variant_iter_free(iter);
1652         __free_critical(key);
1653
1654         return TRUE;
1655 }
1656
1657 gboolean handle_dpp_start_configurator_initiator(Wifi *wifi, GDBusMethodInvocation *context, GVariant *dpp_info)
1658 {
1659         GVariantIter *iter;
1660         GVariant *value;
1661         gchar *field;
1662         gchar *group_id = NULL;
1663         gchar *ssid = NULL;
1664         gchar *peer_uri = NULL;
1665         guint32 peer_id = 0;
1666         gchar *net_role = NULL;
1667         gchar *akm = NULL;
1668         gchar *configurator_key = NULL;
1669         gchar *pass = NULL;
1670
1671         INFO("Received DPP start configurator initiator");
1672         if ((wifi == NULL) || (dpp_info == NULL)) {
1673                 ERR("Invalid arguments");
1674                 netconfig_error_dbus_method_return(context,
1675                                 NETCONFIG_ERROR_INVALID_PARAMETER, "InvalidArguments");
1676                 return TRUE;
1677         }
1678         if (g_in_progress) {
1679                 ERR("DPP in progress");;
1680                 netconfig_error_inprogress(context);
1681                 return TRUE;
1682         }
1683
1684         g_variant_get(dpp_info, "a{sv}", &iter);
1685         while (g_variant_iter_loop(iter, "{sv}", &field, &value)) {
1686                 if (g_strcmp0(field, "group_id") == 0 &&
1687                                 g_variant_is_of_type(value, G_VARIANT_TYPE_STRING)) {
1688                         g_free(group_id);
1689                         group_id = g_strdup(g_variant_get_string(value, NULL));
1690                 } else if (g_strcmp0(field, "ssid") == 0 &&
1691                                 g_variant_is_of_type(value, G_VARIANT_TYPE_STRING)) {
1692                         g_free(ssid);
1693                         ssid = g_strdup(g_variant_get_string(value, NULL));
1694                 } else if (g_strcmp0(field, "peer_uri") == 0 &&
1695                                 g_variant_is_of_type(value, G_VARIANT_TYPE_STRING)) {
1696                         g_free(peer_uri);
1697                         peer_uri = g_strdup(g_variant_get_string(value, NULL));
1698                 } else if (g_strcmp0(field, "peer_id") == 0 &&
1699                                 g_variant_is_of_type(value, G_VARIANT_TYPE_UINT32)) {
1700                         peer_id = g_variant_get_uint32(value);
1701                 } else if (g_strcmp0(field, "net_role") == 0 &&
1702                                 g_variant_is_of_type(value, G_VARIANT_TYPE_STRING)) {
1703                         g_free(net_role);
1704                         net_role = g_strdup(g_variant_get_string(value, NULL));
1705                 } else if (g_strcmp0(field, "akm") == 0 &&
1706                                 g_variant_is_of_type(value, G_VARIANT_TYPE_STRING)) {
1707                         g_free(akm);
1708                         akm = g_strdup(g_variant_get_string(value, NULL));
1709                 } else if (g_strcmp0(field, "configurator_key") == 0 &&
1710                                 g_variant_is_of_type(value, G_VARIANT_TYPE_STRING)) {
1711                         __free_critical(configurator_key);
1712                         configurator_key = g_strdup(g_variant_get_string(value, NULL));
1713                 } else if (g_strcmp0(field, "pass") == 0 &&
1714                                 g_variant_is_of_type(value, G_VARIANT_TYPE_STRING)) {
1715                         __free_critical(pass);
1716                         pass = g_strdup(g_variant_get_string(value, NULL));
1717                 }
1718         }
1719
1720         if (!ssid || !akm || !net_role || !peer_uri){
1721                 g_variant_iter_free(iter);
1722                 g_free(group_id);
1723                 g_free(ssid);
1724                 g_free(peer_uri);
1725                 g_free(net_role);
1726                 g_free(akm);
1727                 __free_critical(configurator_key);
1728                 __free_critical(pass);
1729                 ERR("Invalid arguments");
1730                 netconfig_error_dbus_method_return(context,
1731                                 NETCONFIG_ERROR_INVALID_PARAMETER, "InvalidArguments");
1732                 return TRUE;
1733         }
1734
1735         wifi_complete_dpp_start_configurator_initiator(wifi, context);
1736
1737         g_in_progress = __netconfig_wifi_dpp_start_configurator_initiator(context, group_id,
1738                         ssid, peer_uri, peer_id, net_role, akm, configurator_key, pass);
1739         if (g_in_progress)
1740                 INFO("Success to dpp start configurator initiator");
1741         else
1742                 __netconfig_wifi_notify_dpp_failed();
1743
1744         g_variant_iter_free(iter);
1745         g_free(group_id);
1746         g_free(ssid);
1747         g_free(peer_uri);
1748         g_free(net_role);
1749         g_free(akm);
1750         __free_critical(configurator_key);
1751         __free_critical(pass);
1752         return TRUE;
1753 }
1754
1755 gboolean handle_dpp_start_enrollee_initiator(Wifi *wifi, GDBusMethodInvocation *context, GVariant *dpp_info)
1756 {
1757         GVariantIter *iter;
1758         GVariant *value;
1759         gchar *field;
1760         gchar *peer_uri = NULL;
1761         guint32 peer_id = 0;
1762
1763         INFO("Received DPP start enrollee initiator");
1764         if ((wifi == NULL) || (dpp_info == NULL)) {
1765                 ERR("Invalid arguments");
1766                 netconfig_error_dbus_method_return(context,
1767                                 NETCONFIG_ERROR_INVALID_PARAMETER, "InvalidArguments");
1768                 return TRUE;
1769         }
1770         if (g_in_progress) {
1771                 ERR("DPP in progress");;
1772                 netconfig_error_inprogress(context);
1773                 return TRUE;
1774         }
1775
1776         g_variant_get(dpp_info, "a{sv}", &iter);
1777         while (g_variant_iter_loop(iter, "{sv}", &field, &value)) {
1778
1779                 if (g_strcmp0(field, "peer_uri") == 0 &&
1780                                 g_variant_is_of_type(value, G_VARIANT_TYPE_STRING)) {
1781                         g_free(peer_uri);
1782                         peer_uri = g_strdup(g_variant_get_string(value, NULL));
1783                 } else if (g_strcmp0(field, "peer_id") == 0 &&
1784                                 g_variant_is_of_type(value, G_VARIANT_TYPE_UINT32)) {
1785                         peer_id = g_variant_get_uint32(value);
1786                 }
1787         }
1788
1789         if (!peer_uri){
1790                 g_variant_iter_free(iter);
1791                 ERR("Invalid arguments");
1792                 netconfig_error_dbus_method_return(context,
1793                                 NETCONFIG_ERROR_INVALID_PARAMETER, "InvalidArguments");
1794                 return FALSE;
1795         }
1796         wifi_complete_dpp_start_enrollee_initiator(wifi, context);
1797
1798         g_in_progress = __netconfig_wifi_dpp_start_enrollee_initiator(context, peer_uri, peer_id);
1799         if (g_in_progress)
1800                 INFO("Success to dpp start enrollee initiator");
1801         else
1802                 __netconfig_wifi_notify_dpp_failed();
1803
1804         g_variant_iter_free(iter);
1805         g_free(peer_uri);
1806
1807         return TRUE;
1808 }
1809
1810 gboolean handle_dpp_start_configurator_responder(Wifi *wifi, GDBusMethodInvocation *context, GVariant *dpp_info)
1811 {
1812         GVariantIter *iter;
1813         GVariant *value;
1814         gchar *field;
1815         gchar *group_id = NULL;
1816         gchar *ssid = NULL;
1817         gchar *net_role = NULL;
1818         gchar *akm = NULL;
1819         gchar *auth_key = NULL;
1820         gchar *configurator_key = NULL;
1821         gchar *pass = NULL;
1822
1823         INFO("Received DPP start configurator responder");
1824         if ((wifi == NULL) || (dpp_info == NULL)) {
1825                 ERR("Invalid arguments");
1826                 netconfig_error_dbus_method_return(context,
1827                                 NETCONFIG_ERROR_INVALID_PARAMETER, "InvalidArguments");
1828                 return TRUE;
1829         }
1830         if (g_in_progress) {
1831                 ERR("DPP in progress");;
1832                 netconfig_error_inprogress(context);
1833                 return TRUE;
1834         }
1835
1836         g_variant_get(dpp_info, "a{sv}", &iter);
1837         while (g_variant_iter_loop(iter, "{sv}", &field, &value)) {
1838                 if (g_strcmp0(field, "group_id") == 0 &&
1839                                 g_variant_is_of_type(value, G_VARIANT_TYPE_STRING)) {
1840                         g_free(group_id);
1841                         group_id = g_strdup(g_variant_get_string(value, NULL));
1842                 } else if (g_strcmp0(field, "ssid") == 0 &&
1843                                 g_variant_is_of_type(value, G_VARIANT_TYPE_STRING)) {
1844                         g_free(ssid);
1845                         ssid = g_strdup(g_variant_get_string(value, NULL));
1846                 } else if (g_strcmp0(field, "net_role") == 0 &&
1847                                 g_variant_is_of_type(value, G_VARIANT_TYPE_STRING)) {
1848                         g_free(net_role);
1849                         net_role = g_strdup(g_variant_get_string(value, NULL));
1850                 } else if (g_strcmp0(field, "akm") == 0 &&
1851                                 g_variant_is_of_type(value, G_VARIANT_TYPE_STRING)) {
1852                         g_free(akm);
1853                         akm = g_strdup(g_variant_get_string(value, NULL));
1854                 } else if (g_strcmp0(field, "auth_key") == 0 &&
1855                                 g_variant_is_of_type(value, G_VARIANT_TYPE_STRING)) {
1856                         __free_critical(auth_key);
1857                         auth_key = g_strdup(g_variant_get_string(value, NULL));
1858                 } else if (g_strcmp0(field, "configurator_key") == 0 &&
1859                                 g_variant_is_of_type(value, G_VARIANT_TYPE_STRING)) {
1860                         __free_critical(configurator_key);
1861                         configurator_key = g_strdup(g_variant_get_string(value, NULL));
1862                 } else if (g_strcmp0(field, "pass") == 0 &&
1863                                 g_variant_is_of_type(value, G_VARIANT_TYPE_STRING)) {
1864                         __free_critical(pass);
1865                         pass = g_strdup(g_variant_get_string(value, NULL));
1866                 }
1867         }
1868
1869         if (!ssid || !akm || !net_role){
1870                 g_variant_iter_free(iter);
1871                 g_free(group_id);
1872                 g_free(ssid);
1873                 g_free(net_role);
1874                 g_free(akm);
1875                 __free_critical(auth_key);
1876                 __free_critical(configurator_key);
1877                 __free_critical(pass);
1878                 ERR("Invalid arguments");
1879                 netconfig_error_dbus_method_return(context,
1880                                 NETCONFIG_ERROR_INVALID_PARAMETER, "InvalidArguments");
1881                 return FALSE;
1882         }
1883         wifi_complete_dpp_start_configurator_responder(wifi, context);
1884
1885         g_in_progress = __netconfig_wifi_dpp_start_configurator_responder(context, group_id,
1886                         ssid, net_role, akm, auth_key, configurator_key, pass);
1887         if (g_in_progress)
1888                 INFO("Success to dpp start configurator responder");
1889         else
1890                 __netconfig_wifi_notify_dpp_failed();
1891
1892         g_variant_iter_free(iter);
1893         g_free(group_id);
1894         g_free(ssid);
1895         g_free(net_role);
1896         g_free(akm);
1897         __free_critical(auth_key);
1898         __free_critical(configurator_key);
1899         __free_critical(pass);
1900
1901         return TRUE;
1902 }
1903
1904 gboolean handle_dpp_start_enrollee_responder(Wifi *wifi, GDBusMethodInvocation *context, GVariant *dpp_info)
1905 {
1906         GVariantIter *iter;
1907         GVariant *value;
1908         gchar *field;
1909         gchar *auth_key = NULL;
1910
1911         INFO("Received DPP start enrollee responder");
1912         if ((wifi == NULL) || (dpp_info == NULL)) {
1913                 ERR("Invalid arguments");
1914                 netconfig_error_dbus_method_return(context,
1915                                 NETCONFIG_ERROR_INVALID_PARAMETER, "InvalidArguments");
1916                 return TRUE;
1917         }
1918         if (g_in_progress) {
1919                 ERR("DPP in progress");;
1920                 netconfig_error_inprogress(context);
1921                 return TRUE;
1922         }
1923
1924         g_variant_get(dpp_info, "a{sv}", &iter);
1925         while (g_variant_iter_loop(iter, "{sv}", &field, &value)) {
1926                 if (g_strcmp0(field, "auth_key") == 0 &&
1927                                 g_variant_is_of_type(value, G_VARIANT_TYPE_STRING)) {
1928                         __free_critical(auth_key);
1929                         auth_key = g_strdup(g_variant_get_string(value, NULL));
1930                 }
1931         }
1932         wifi_complete_dpp_start_enrollee_responder(wifi, context);
1933
1934         g_in_progress = __netconfig_wifi_dpp_start_enrollee_responder(context, auth_key);
1935         if (g_in_progress)
1936                 INFO("Success to dpp start enrolee responder");
1937         else
1938                 __netconfig_wifi_notify_dpp_failed();
1939
1940         g_variant_iter_free(iter);
1941         __free_critical(auth_key);
1942
1943         return TRUE;
1944 }
1945
1946 gboolean handle_dpp_stop(Wifi *wifi, GDBusMethodInvocation *context, GVariant *dpp_info)
1947 {
1948         GVariantIter *iter;
1949         GVariant *value;
1950         gchar *field;
1951         guint32 peer_id = 0;
1952         guint32 own_id = 0;
1953
1954         INFO("Received DPP stop Request");
1955         if ((wifi == NULL) || (dpp_info == NULL)) {
1956                 ERR("Invalid arguments");
1957                 netconfig_error_dbus_method_return(context,
1958                                 NETCONFIG_ERROR_INVALID_PARAMETER, "InvalidArguments");
1959                 return TRUE;
1960         }
1961
1962         g_variant_get(dpp_info, "a{sv}", &iter);
1963
1964         g_variant_get(dpp_info, "a{sv}", &iter);
1965         while (g_variant_iter_loop(iter, "{sv}", &field, &value)) {
1966                 if (g_strcmp0(field, "peer_id") == 0 &&
1967                                 g_variant_is_of_type(value, G_VARIANT_TYPE_UINT32)) {
1968                         peer_id = g_variant_get_uint32(value);
1969                 } else if (g_strcmp0(field, "own_id") == 0 &&
1970                                 g_variant_is_of_type(value, G_VARIANT_TYPE_UINT32)) {
1971                         own_id = g_variant_get_uint32(value);
1972                 }
1973         }
1974         if (!peer_id && !own_id){
1975                 g_variant_iter_free(iter);
1976                 ERR("Invalid arguments");
1977                 netconfig_error_dbus_method_return(context,
1978                                 NETCONFIG_ERROR_INVALID_PARAMETER, "InvalidArguments");
1979                 return FALSE;
1980         }
1981         wifi_complete_dpp_stop(wifi, context);
1982
1983         g_in_progress = !(__netconfig_wifi_dpp_stop(context, peer_id, own_id));
1984         if (!g_in_progress)
1985                 INFO("Success to dpp stop");
1986         else
1987                 __netconfig_wifi_notify_dpp_failed();
1988
1989         g_variant_iter_free(iter);
1990
1991         return TRUE;
1992 }