Fix memory leak - asp_tech_p2p_process_connect_status
[platform/core/connectivity/asp-manager.git] / src / tech / asp-tech-p2p.c
1 /*
2  * Copyright (c) 2016 Samsung Electronics Co., Ltd.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16
17 /*****************************************************************************
18  * Standard headers
19  *****************************************************************************/
20
21 #include <stdio.h>
22 #include <stdlib.h>
23 #include <string.h>
24 #include <time.h>
25
26 /*****************************************************************************
27  * System headers
28  *****************************************************************************/
29
30 #include <glib.h>
31 #include <dlog.h>
32 #include <gio/gio.h>
33
34 /*****************************************************************************
35  * Application Service Platform Daemon headers
36  *****************************************************************************/
37 #include "asp-manager.h"
38 #include "asp-manager-util.h"
39 #include "asp-service.h"
40 #include "asp-session.h"
41 #include "asp-tech.h"
42 #include "asp-tech-p2p.h"
43
44 /*****************************************************************************
45  * Macros and Typedefs
46  *****************************************************************************/
47
48 #define ASP_TECH_P2P_ROLE_NEW 1
49 #define ASP_TECH_P2P_ROLE_GC 2
50 #define ASP_TECH_P2P_ROLE_GO 4
51
52 #define WFD_MANAGER_SERVICE                     "net.wifidirect"
53 #define WFD_MANAGER_PATH                        "/net/wifidirect"
54 #define WFD_MANAGER_MANAGE_INTERFACE            WFD_MANAGER_SERVICE
55 #define WFD_MANAGER_CONFIG_INTERFACE            WFD_MANAGER_SERVICE ".config"
56 #define WFD_MANAGER_GROUP_INTERFACE             WFD_MANAGER_SERVICE ".group"
57 #define WFD_MANAGER_ASP_INTERFACE                        WFD_MANAGER_SERVICE ".asp"
58
59 #define DBUS_REPLY_TIMEOUT_SYNC     10 * 1000
60 #define DBUS_OBJECT_PATH_MAX                    150
61
62 #define WFD_MANAGER_QUARK (g_quark_from_string("wifi-direct-manager"))
63
64 #define asp_tech_p2p_dbus_method_call_sync(interface_name, method, params, error) \
65         __asp_tech_p2p_dbus_method_call_sync_debug(interface_name, method, params, error, __func__)
66
67 #define DBUS_DEBUG_VARIANT(parameters) \
68         do {\
69                 gchar *parameters_debug_str = NULL;\
70                 if (parameters)\
71                         parameters_debug_str = g_variant_print(parameters, TRUE);\
72                 ASP_LOGD("signal params [%s]", parameters_debug_str ? parameters_debug_str : "NULL");\
73                 g_free(parameters_debug_str);\
74         } while (0)
75
76 asp_tech_ops_s asp_tech_p2p_ops;
77
78 void asp_tech_p2p_process_activation(GDBusConnection *connection,
79                 const gchar *object_path, GVariant *parameters);
80
81 void asp_tech_p2p_process_deactivation(GDBusConnection *connection,
82                 const gchar *object_path, GVariant *parameters);
83
84 void asp_tech_p2p_process_search_result(GDBusConnection *connection,
85                 const gchar *object_path, GVariant *parameters);
86
87 void asp_tech_p2p_process_session_request(GDBusConnection *connection,
88                 const gchar *object_path, GVariant *parameters);
89
90 void asp_tech_p2p_process_session_config_request(GDBusConnection *connection,
91                 const gchar *object_path, GVariant *parameters);
92
93 void asp_tech_p2p_process_connect_status(GDBusConnection *connection,
94                 const gchar *object_path, GVariant *parameters);
95
96 void asp_tech_p2p_process_session_peer_ip(GDBusConnection *connection,
97                 const gchar *object_path, GVariant *parameters);
98
99 /*****************************************************************************
100  * Global Variables
101  *****************************************************************************/
102
103 static GDBusConnection *g_wfd_gdbus_conn;
104 static guint g_wfd_signal_id;
105
106 static struct {
107         const gchar *interface;
108         const gchar *member;
109         void (*function) (GDBusConnection *connection,
110                           const gchar *object_path,
111                           GVariant *parameters);
112 } asp_tech_p2p_dbus_signal_map[] = {
113                 {
114                                 WFD_MANAGER_MANAGE_INTERFACE,
115                                 "Activation",
116                                 asp_tech_p2p_process_activation
117                 },
118                 {
119                                 WFD_MANAGER_MANAGE_INTERFACE,
120                                 "Deactivation",
121                                 asp_tech_p2p_process_deactivation
122                 },
123                 {
124                                 WFD_MANAGER_ASP_INTERFACE,
125                                 "SearchResult",
126                                 asp_tech_p2p_process_search_result
127                 },
128                 {
129                                 WFD_MANAGER_ASP_INTERFACE,
130                                 "SessionRequest",
131                                 asp_tech_p2p_process_session_request
132                 },
133                 {
134                                 WFD_MANAGER_ASP_INTERFACE,
135                                 "SessionConfigRequest",
136                                 asp_tech_p2p_process_session_config_request
137                 },
138                 {
139                                 WFD_MANAGER_ASP_INTERFACE,
140                                 "ConnectStatus",
141                                 asp_tech_p2p_process_connect_status
142                 },
143                 {
144                                 WFD_MANAGER_ASP_INTERFACE,
145                                 "SessionPeerIPAssigned",
146                                 asp_tech_p2p_process_session_peer_ip
147                 },
148                 {
149                                 NULL,
150                                 NULL,
151                                 NULL
152                 }
153 };
154
155 /*****************************************************************************
156  * Local Functions Definition
157  *****************************************************************************/
158
159 static gint32 __net_wifidirect_gerror_to_enum(GError* error)
160 {
161         gint32 res = 0;
162         if (error == NULL) {
163                 ASP_LOGI("GError is NULL!!");
164                 return res;
165         }
166
167         ASP_LOGE("wifi_direct_dbus_method_call_sync() failed. error [%d: %s]",
168                         error->code, error->message);
169
170         res = -1;
171         /*
172         if (NULL == strstr(error->message, "net.wifidirect.Error")) {
173                 if (NULL != strstr(error->message, ".AccessDenied")) {
174                         ASP_LOGE("Client doesn't have wifidirect privilege");
175                         res = -1;
176                 } else {
177                         ASP_LOGE("DBus failure");
178                         res = -1;
179                 }
180         } else {
181                 if (NULL != strstr(error->message, "InvalidParameter"))
182                         res = -1;
183                 else if (NULL != strstr(error->message, "NotPermitted"))
184                         res = -1;
185                 else if (NULL != strstr(error->message, "OperationFailed"))
186                         res = -1;
187                 else if (NULL != strstr(error->message, "TooManyClient"))
188                         res = -1;
189                 else
190                         res = -1;
191         }
192         */
193         return res;
194 }
195
196
197 static void __asp_tech_p2p_dbus_signal_cb(GDBusConnection *connection,
198                 const gchar *sender, const gchar *object_path,
199                 const gchar *interface, const gchar *signal,
200                 GVariant *parameters, gpointer user_data)
201 {
202         gint32 i = 0;
203
204         ASP_LOGD("Signal Name [%s]", signal);
205         DBUS_DEBUG_VARIANT(parameters);
206
207         for (i = 0; asp_tech_p2p_dbus_signal_map[i].member != NULL; i++) {
208                 if (!g_strcmp0(signal, asp_tech_p2p_dbus_signal_map[i].member) &&
209                     !g_strcmp0(interface, asp_tech_p2p_dbus_signal_map[i].interface) &&
210                     asp_tech_p2p_dbus_signal_map[i].function != NULL) {
211                         asp_tech_p2p_dbus_signal_map[i].function(connection, object_path, parameters);
212                         break;
213                 }
214         }
215 }
216
217 static GVariant *__g_hash_table_to_g_variant(GHashTable *hash)
218 {
219         GVariantBuilder builder;
220
221         g_variant_builder_init(&builder, G_VARIANT_TYPE("a{sv}"));
222
223         GHashTableIter iter;
224         gpointer key, value;
225
226         g_hash_table_iter_init(&iter, hash);
227         while (g_hash_table_iter_next(&iter, &key, &value)) {
228                 ASP_LOGD("%s %s", key, value);
229                 g_variant_builder_add(&builder, "{sv}", key, g_variant_new_string(value));
230         }
231
232         return g_variant_builder_end(&builder);
233 }
234
235 static GVariant *__g_hash_keys_to_g_variant(GHashTable *hash)
236 {
237         GVariantBuilder builder;
238
239         g_variant_builder_init(&builder, G_VARIANT_TYPE("as"));
240
241         GHashTableIter iter;
242         gpointer key, value;
243
244         g_hash_table_iter_init(&iter, hash);
245         while (g_hash_table_iter_next(&iter, &key, &value))
246                 g_variant_builder_add(&builder, "s", key);
247
248         return g_variant_builder_end(&builder);
249 }
250
251 GVariant *__asp_tech_p2p_dbus_method_call_sync_debug(const gchar* interface_name,
252                                                   const gchar* method,
253                                                   GVariant *params,
254                                                   GError **error,
255                                                   const gchar *calling_func)
256 {
257         GVariant *reply = NULL;
258
259         if (g_wfd_gdbus_conn == NULL) {
260                 ASP_LOGE("GDBusconnection is NULL");
261                 return reply;
262         }
263
264         ASP_LOGD("[%s][%s.%s]", calling_func, interface_name, method);
265         DBUS_DEBUG_VARIANT(params);
266
267         reply = g_dbus_connection_call_sync(g_wfd_gdbus_conn,
268                                             WFD_MANAGER_SERVICE, /* bus name */
269                                             WFD_MANAGER_PATH, /* object path */
270                                             interface_name, /* interface name */
271                                             method, /* method name */
272                                             params, /* GVariant *params */
273                                             NULL, /* reply_type */
274                                             G_DBUS_CALL_FLAGS_NONE, /* flags */
275                                             DBUS_REPLY_TIMEOUT_SYNC, /* timeout */
276                                             NULL, /* cancellable */
277                                             error); /* error */
278         DBUS_DEBUG_VARIANT(reply);
279         return reply;
280 }
281
282 void asp_tech_p2p_process_activation(GDBusConnection *connection,
283                 const gchar *object_path, GVariant *parameters)
284 {
285         __ASP_LOG_FUNC_ENTER__;
286
287         ASP_LOGE("Wi-Fi Direct activated");
288
289         __ASP_LOG_FUNC_EXIT__;
290         return;
291 }
292
293 void asp_tech_p2p_process_deactivation(GDBusConnection *connection,
294                 const gchar *object_path, GVariant *parameters)
295 {
296         __ASP_LOG_FUNC_ENTER__;
297
298         ASP_LOGE("Wi-Fi Direct deactivated");
299
300         __ASP_LOG_FUNC_EXIT__;
301         return;
302 }
303
304 static void __service_info_to_g_hash(const gchar *service_info,
305                 GHashTable *service_info_map)
306 {
307         const gchar *key = NULL;
308         const gchar *value = NULL;
309         gsize pos = 0;
310         gsize key_length = 0;
311         gsize value_length = 0;
312         gsize info_length = 0;
313
314         info_length = strlen(service_info);
315
316         while (service_info[pos] != '\0' && pos < info_length) {
317                 key = &service_info[pos];
318                 while (service_info[pos] != '=' && pos < info_length) {
319                         key_length++;
320                         pos++;
321                 }
322
323                 if (pos >= info_length - 1) {
324                         g_hash_table_replace(service_info_map, g_strndup(key, key_length),
325                                         g_strdup(""));
326                         break;
327                 }
328
329                 pos++;
330                 value = &service_info[pos];
331                 while (service_info[pos] != ',' && pos < info_length) {
332                         value_length++;
333                         pos++;
334                 }
335
336                 g_hash_table_replace(service_info_map, g_strndup(key, key_length),
337                                 g_strndup(value, value_length));
338                 ASP_LOGD("Insert (%s, %s) to hash.", key, value);
339
340                 if (service_info[pos] == ',' && pos == info_length)
341                         break;
342         }
343         return;
344 }
345
346 void asp_tech_p2p_process_search_result(GDBusConnection *connection,
347                 const gchar *object_path, GVariant *parameters)
348 {
349         __ASP_LOG_FUNC_ENTER__;
350
351         GVariantIter *iter = NULL;
352         GVariant *var = NULL;
353         GHashTable *service_info_map = NULL;
354         asp_event_data event;
355         const gchar *service_mac = NULL;
356         const gchar *key = NULL;
357         const gchar *str = NULL;
358         long long unsigned search_id = 0;
359         gchar *device_name = NULL;
360         guint32 advertisement_id = 0;
361         guint32 config_method = 0;
362         gchar *instance_name = NULL;
363         guint8 status = 0;
364
365         if (!parameters) {
366                 __ASP_LOG_FUNC_EXIT__;
367                 return;
368         }
369
370         g_variant_get(parameters, "(a{sv})", &iter);
371         while (g_variant_iter_loop(iter, "{sv}", &key, &var)) {
372                 if (!g_strcmp0(key, "search_id")) {
373                         g_variant_get(var, "t", &search_id);
374                 } else if (!g_strcmp0(key, "service_mac")) {
375                         g_variant_get(var, "&s", &service_mac);
376                 } else if (!g_strcmp0(key, "device_name")) {
377                         g_variant_get(var, "&s", &str);
378                         device_name = g_strndup(str, ASP_SERVICE_DEVICE_NAME_LEN);
379                 }  else if (!g_strcmp0(key, "advertisement_id")) {
380                         g_variant_get(var, "u", &advertisement_id);
381                 } else if (!g_strcmp0(key, "config_method")) {
382                         g_variant_get(var, "u", &config_method);
383                 }  else if (!g_strcmp0(key, "instance_name")) {
384                         g_variant_get(var, "&s", &str);
385                         instance_name = g_strdup(str);
386                 } else if (!g_strcmp0(key, "status")) {
387                         g_variant_get(var, "y", &status);
388                 }  else if (!g_strcmp0(key, "service_info")) {
389                         g_variant_get(var, "&s", &str);
390                         service_info_map = g_hash_table_new_full(g_str_hash,
391                                         g_str_equal, g_free, g_free);
392                         __service_info_to_g_hash(str, service_info_map);
393                 }   else {
394                                 ;/* Do Nothing */
395                 }
396         }
397
398         memset(&event, 0x0, sizeof(asp_event_data));
399         event.search_result.tech = ASP_TECH_P2P;
400         event.search_result.search_id = search_id;
401         event.search_result.advertisement_id = advertisement_id;
402         event.search_result.service_status = status;
403         if (service_mac)
404                 memcpy(event.search_result.service_mac, service_mac, MACSTR_LEN + 1);
405         event.search_result.device_name = device_name;
406         event.search_result.instance_name = instance_name;
407         event.search_result.service_info = service_info_map;
408         asp_manager_event(NULL, ASP_EVENT_SEARCH_RESULT, &event);
409
410         g_free(device_name);
411         g_free(instance_name);
412         g_hash_table_unref(service_info_map);
413         g_variant_iter_free(iter);
414
415         __ASP_LOG_FUNC_EXIT__;
416         return;
417 }
418
419 void asp_tech_p2p_process_session_request(GDBusConnection *connection,
420                 const gchar *object_path, GVariant *parameters)
421 {
422         __ASP_LOG_FUNC_ENTER__;
423
424         GVariantIter *iter = NULL;
425         GVariant *var = NULL;
426         const gchar *key = NULL;
427         const gchar *str = NULL;
428         guint8 session_mac[MAC_LEN] = {0,};
429         guint32 session_id = 0;
430         guint32 adv_id = 0;
431         gchar *device_name = NULL;
432         size_t name_length = 0;
433         guint8 *session_info = NULL;
434         size_t info_length = 0;
435         gboolean get_pin = FALSE;
436         guint32 pin = 0;
437
438         if (!parameters) {
439                 __ASP_LOG_FUNC_EXIT__;
440                 return;
441         }
442
443         g_variant_get(parameters, "(a{sv})", &iter);
444         while (g_variant_iter_loop(iter, "{sv}", &key, &var)) {
445                 if (!g_strcmp0(key, "adv_id")) {
446                         g_variant_get(var, "u", &adv_id);
447                 } else if (!g_strcmp0(key, "session_mac")) {
448                         if (asp_dbus_unpack_ay(session_mac, var, MAC_LEN) < 0) {
449                                 g_free(device_name);
450                                 g_free(session_info);
451                                 g_variant_iter_free(iter);
452                                 return;
453                         }
454                 }  else if (!g_strcmp0(key, "session_id")) {
455                         g_variant_get(var, "u", &session_id);
456                 }  else if (!g_strcmp0(key, "device_name")) {
457                         g_variant_get(var, "&s", &str);
458                         device_name = g_strndup(str, ASP_SERVICE_DEVICE_NAME_LEN);
459                         name_length = strlen(str);
460                 } else if (!g_strcmp0(key, "get_pin")) {
461                         g_variant_get(var, "b", &get_pin);
462                 } else if (!g_strcmp0(key, "pin")) {
463                         g_variant_get(var, "&s", &str);
464                         pin = (guint32)atoi(str);
465                 } else if (!g_strcmp0(key, "session_info")) {
466                         str = NULL;
467                         g_variant_get(var, "&s", &str);
468                         if (!str)
469                                 continue;
470                         info_length = strlen(str);
471                         g_free(session_info);
472                         session_info = g_try_malloc0(info_length + 1);
473                         memcpy(session_info, str, info_length);
474                 } else {
475                                 ;/* Do Nothing */
476                 }
477         }
478
479         if (asp_tech_p2p_ops.session_request_cb) {
480                 asp_tech_p2p_ops.session_request_cb(0, session_mac, session_id,
481                                 adv_id, device_name, name_length,
482                                 session_info, info_length, get_pin, pin,
483                                 asp_tech_p2p_ops.session_request_cb_user_data);
484         }
485
486         g_variant_iter_free(iter);
487         g_free(device_name);
488         g_free(session_info);
489
490         __ASP_LOG_FUNC_EXIT__;
491         return;
492 }
493
494 void asp_tech_p2p_process_session_config_request(GDBusConnection *connection,
495                 const gchar *object_path, GVariant *parameters)
496 {
497         __ASP_LOG_FUNC_ENTER__;
498
499         GVariantIter *iter = NULL;
500         GVariant *var = NULL;
501         const gchar *key = NULL;
502         const gchar *str = NULL;
503         const guint8 session_mac[MAC_LEN] = {0,};
504         guint32 session_id = 0;
505         gboolean get_pin = FALSE;
506         guint32 pin = 0;
507
508         if (!parameters) {
509                 __ASP_LOG_FUNC_EXIT__;
510                 return;
511         }
512
513         g_variant_get(parameters, "(a{sv})", &iter);
514         while (g_variant_iter_loop(iter, "{sv}", &key, &var)) {
515                 if (!g_strcmp0(key, "session_id")) {
516                         g_variant_get(var, "u", &session_id);
517                 } else if (!g_strcmp0(key, "get_pin")) {
518                         g_variant_get(var, "b", &get_pin);
519                 } else if (!g_strcmp0(key, "pin")) {
520                         g_variant_get(var, "&s", &str);
521                         pin = (guint32)atoi(str);
522                 } else {
523                         ;/* Do Nothing */
524                 }
525         }
526
527         if (asp_tech_p2p_ops.session_config_request_cb) {
528                 asp_tech_p2p_ops.session_config_request_cb(0,
529                                 session_mac, session_id, get_pin, pin,
530                                 asp_tech_p2p_ops.session_config_request_cb_user_data);
531         }
532         g_variant_iter_free(iter);
533
534         __ASP_LOG_FUNC_EXIT__;
535         return;
536 }
537
538 void asp_tech_p2p_process_connect_status(GDBusConnection *connection,
539                 const gchar *object_path, GVariant *parameters)
540 {
541         __ASP_LOG_FUNC_ENTER__;
542
543         GVariantIter *iter = NULL;
544         GVariant *var = NULL;
545         const gchar *key = NULL;
546         const gchar *str = NULL;
547         guint8 session_mac[MAC_LEN] = {0,};
548         guint32 session_id = 0;
549         guint32 status = 0;
550         gchar *deferred = NULL;
551
552         if (!parameters) {
553                 __ASP_LOG_FUNC_EXIT__;
554                 return;
555         }
556
557         g_variant_get(parameters, "(a{sv})", &iter);
558         while (g_variant_iter_loop(iter, "{sv}", &key, &var)) {
559                 if (!g_strcmp0(key, "session_mac")) {
560                         if (asp_dbus_unpack_ay(session_mac, var, MAC_LEN) < 0) {
561                                 g_variant_iter_free(iter);
562                                 g_free(deferred);
563                                 return;
564                         }
565                 } else if (!g_strcmp0(key, "session_id")) {
566                         g_variant_get(var, "u", &session_id);
567                 } else if (!g_strcmp0(key, "status")) {
568                         g_variant_get(var, "i", &status);
569                 } else if (!g_strcmp0(key, "deferred")) {
570                         g_variant_get(var, "&s", &str);
571                         g_free(deferred);
572                         deferred = g_strdup(str);
573                 } else {
574                         ;/* Do Nothing */
575                 }
576         }
577
578         if (asp_tech_p2p_ops.connect_status_cb) {
579                 asp_tech_p2p_ops.connect_status_cb(0,
580                                 session_mac, session_id, status,
581                                 asp_tech_p2p_ops.connect_status_cb_user_data);
582         }
583
584         g_variant_iter_free(iter);
585         g_free(deferred);
586
587         __ASP_LOG_FUNC_EXIT__;
588         return;
589 }
590
591 void asp_tech_p2p_process_session_peer_ip(GDBusConnection *connection,
592                 const gchar *object_path, GVariant *parameters)
593 {
594         __ASP_LOG_FUNC_ENTER__;
595
596         GVariantIter *iter = NULL;
597         GVariant *var = NULL;
598         const gchar *key = NULL;
599         guint8 session_mac[MAC_LEN] = {0,};
600         guint8 service_mac[MAC_LEN] = {0,};
601         guint32 session_id = 0;
602         gchar *peer_ip = NULL;
603
604         if (!parameters) {
605                 __ASP_LOG_FUNC_EXIT__;
606                 return;
607         }
608
609         g_variant_get(parameters, "(a{sv})", &iter);
610         while (g_variant_iter_loop(iter, "{sv}", &key, &var)) {
611                 if (!g_strcmp0(key, "session_mac")) {
612                         if (asp_dbus_unpack_ay(session_mac, var, MAC_LEN) < 0) {
613                                 g_variant_iter_free(iter);
614                                 return;
615                         }
616                 } else if (!g_strcmp0(key, "session_id")) {
617                         g_variant_get(var, "u", &session_id);
618                 } else if (!g_strcmp0(key, "service_mac")) {
619                         if (asp_dbus_unpack_ay(service_mac, var, MAC_LEN) < 0) {
620                                 g_variant_iter_free(iter);
621                                 return;
622                         }
623
624                 } else if (!g_strcmp0(key, "assigned_ip_address")) {
625                         g_variant_get(var, "&s", &peer_ip);
626                 } else {
627                         ;/* Do Nothing */
628                 }
629         }
630
631         if (peer_ip == NULL) {
632                 ASP_LOGE("Invalid peer IP address");
633                 g_variant_iter_free(iter);
634                 return;
635         }
636
637         if (asp_tech_p2p_ops.ip_assigned_cb) {
638                 asp_tech_p2p_ops.ip_assigned_cb(0,
639                                 session_mac, session_id, service_mac, peer_ip,
640                                 strlen(peer_ip), asp_tech_p2p_ops.ip_assigned_cb_user_data);
641         }
642
643         g_variant_iter_free(iter);
644
645         __ASP_LOG_FUNC_EXIT__;
646         return;
647 }
648
649 gint32 asp_tech_p2p_advertise(asp_service_advertise_s *service, gint32 replace)
650 {
651         __ASP_LOG_FUNC_ENTER__;
652         GVariantBuilder *builder = NULL;
653         GVariant *params = NULL;
654         GError *error = NULL;
655         GVariant *reply = NULL;
656         gint32 result = 0;
657
658         if (!service || !g_wfd_gdbus_conn) {
659                 ASP_LOGE("Invalid parameter!");
660                 __ASP_LOG_FUNC_EXIT__;
661                 return -1;
662         }
663
664         builder = g_variant_builder_new(G_VARIANT_TYPE("a{sv}"));
665         g_variant_builder_add(builder, "{sv}", "adv_id", g_variant_new("u", service->adv_id));
666         g_variant_builder_add(builder, "{sv}", "discovery_tech", g_variant_new("i", service->discovery_tech));
667         g_variant_builder_add(builder, "{sv}", "preferred_connection", g_variant_new("y", service->preferred_connection));
668         g_variant_builder_add(builder, "{sv}", "auto_accept", g_variant_new("i", service->auto_accept));
669         g_variant_builder_add(builder, "{sv}", "status", g_variant_new("y", service->status));
670         g_variant_builder_add(builder, "{sv}", "role", g_variant_new("y", service->role));
671         g_variant_builder_add(builder, "{sv}", "replace", g_variant_new("i", replace));
672         g_variant_builder_add(builder, "{sv}", "config_method", g_variant_new("u", service->config_method));
673
674         if (service->instance_name)
675                 g_variant_builder_add(builder, "{sv}", "instance_name", g_variant_new("s", service->instance_name));
676         if (service->service_type)
677                 g_variant_builder_add(builder, "{sv}", "service_type", g_variant_new("s", service->service_type));
678         if (service->service_info_map != NULL)
679                 g_variant_builder_add(builder, "{sv}", "service_info",
680                                 __g_hash_table_to_g_variant(service->service_info_map));
681         if (service->rsp_info)
682                 g_variant_builder_add(builder, "{sv}", "rsp_info", g_variant_new("s", service->rsp_info));
683         params = g_variant_new("(a{sv})", builder);
684         g_variant_builder_unref(builder);
685
686         reply = asp_tech_p2p_dbus_method_call_sync(WFD_MANAGER_ASP_INTERFACE,
687                                                   "AdvertiseService", params, &error);
688         if (error != NULL) {
689                 result = __net_wifidirect_gerror_to_enum(error);
690                 g_error_free(error);
691                 __ASP_LOG_FUNC_EXIT__;
692                 return result;
693         }
694
695         g_variant_get(reply, "(i)", &result);
696         g_variant_unref(reply);
697
698         ASP_LOGD("%s() return : [%d]", __func__, result);
699
700         __ASP_LOG_FUNC_EXIT__;
701         return result;
702 }
703
704 gint32 asp_tech_p2p_cancel_advertise(asp_service_advertise_s *service)
705 {
706         __ASP_LOG_FUNC_ENTER__;
707         GVariant *params = NULL;
708         GError *error = NULL;
709         GVariant *reply = NULL;
710         gint32 result = 0;
711
712         if (!service || !g_wfd_gdbus_conn) {
713                 ASP_LOGE("Invalid parameter!");
714                 __ASP_LOG_FUNC_EXIT__;
715                 return -1;
716         }
717
718         params = g_variant_new("(u)", service->adv_id);
719         reply = asp_tech_p2p_dbus_method_call_sync(WFD_MANAGER_ASP_INTERFACE,
720                                                   "CancelAdvertiseService", params, &error);
721         if (error != NULL) {
722                 result = __net_wifidirect_gerror_to_enum(error);
723                 g_error_free(error);
724                 __ASP_LOG_FUNC_EXIT__;
725                 return result;
726         }
727
728         g_variant_get(reply, "(i)", &result);
729         g_variant_unref(reply);
730
731         ASP_LOGD("%s() return : [%d]", __func__, result);
732
733         __ASP_LOG_FUNC_EXIT__;
734         return result;
735 }
736
737 gint32 asp_tech_p2p_seek(asp_service_seek_s *service)
738 {
739         __ASP_LOG_FUNC_ENTER__;
740         GVariantBuilder *builder = NULL;
741         GVariant *params = NULL;
742         GError *error = NULL;
743         GVariant *reply = NULL;
744         gint32 result = 0;
745
746         if (!service || !g_wfd_gdbus_conn) {
747                 ASP_LOGE("Invalid parameter!");
748                 __ASP_LOG_FUNC_EXIT__;
749                 return -1;
750         }
751
752
753         builder = g_variant_builder_new(G_VARIANT_TYPE("a{sv}"));
754         g_variant_builder_add(builder, "{sv}", "discovery_tech", g_variant_new("i", service->discovery_tech));
755         g_variant_builder_add(builder, "{sv}", "preferred_connection", g_variant_new("y", service->preferred_connection));
756         g_variant_builder_add(builder, "{sv}", "search_id", g_variant_new("t", service->search_id));
757         g_variant_builder_add(builder, "{sv}", "service_type", g_variant_new("s", service->service_type));
758         if (service->service_info_map != NULL)
759                 g_variant_builder_add(builder, "{sv}", "service_info", __g_hash_keys_to_g_variant(service->service_info_map));
760         params = g_variant_new("(a{sv})", builder);
761         g_variant_builder_unref(builder);
762         ASP_LOGI("instance name (%s)", service->instance_name);
763
764         reply = asp_tech_p2p_dbus_method_call_sync(WFD_MANAGER_ASP_INTERFACE,
765                                                   "SeekService", params, &error);
766         if (error != NULL) {
767                 result = __net_wifidirect_gerror_to_enum(error);
768                 g_error_free(error);
769                 __ASP_LOG_FUNC_EXIT__;
770                 return result;
771         }
772
773         g_variant_get(reply, "(i)", &result);
774         g_variant_unref(reply);
775
776         ASP_LOGD("%s() return : [%d]", __func__, result);
777
778         __ASP_LOG_FUNC_EXIT__;
779         return result;
780 }
781
782 gint32 asp_tech_p2p_cancel_seek(asp_service_seek_s *service)
783 {
784         __ASP_LOG_FUNC_ENTER__;
785         GVariant *params = NULL;
786         GError *error = NULL;
787         GVariant *reply = NULL;
788         gint32 result = 0;
789
790         if (!service || !g_wfd_gdbus_conn) {
791                 ASP_LOGE("Invalid parameter!");
792                 __ASP_LOG_FUNC_EXIT__;
793                 return -1;
794         }
795
796         params = g_variant_new("(t)", service->search_id);
797         reply = asp_tech_p2p_dbus_method_call_sync(WFD_MANAGER_ASP_INTERFACE,
798                                                   "CancelSeekService", params, &error);
799         if (error != NULL) {
800                 result = __net_wifidirect_gerror_to_enum(error);
801                 g_error_free(error);
802                 __ASP_LOG_FUNC_EXIT__;
803                 return result;
804         }
805
806         g_variant_get(reply, "(i)", &result);
807         g_variant_unref(reply);
808
809         ASP_LOGD("%s() return : [%d]", __func__, result);
810
811         __ASP_LOG_FUNC_EXIT__;
812         return result;
813 }
814
815 gint32 asp_tech_p2p_init()
816 {
817         __ASP_LOG_FUNC_ENTER__;
818         GError* error = NULL;
819         GVariant *reply = NULL;
820         g_wfd_gdbus_conn = NULL;
821         asp_s *asp = NULL;
822         const gchar *str = NULL;
823         gint32 result = 0;
824
825         asp = asp_get_manager();
826         if (asp == NULL) {
827                 ASP_LOGE("Failed to get asp");
828                 __ASP_LOG_FUNC_EXIT__;
829                 return -1;
830         }
831
832         g_wfd_gdbus_conn = g_bus_get_sync(G_BUS_TYPE_SYSTEM, NULL, &error);
833         if (g_wfd_gdbus_conn == NULL) {
834                 ASP_LOGE("Failed to get connection, Error[%s]", error->message);
835                 g_error_free(error);
836                 __ASP_LOG_FUNC_EXIT__;
837                 return -1;
838         }
839
840         /* subscribe signal handler */
841         g_wfd_signal_id = g_dbus_connection_signal_subscribe(g_wfd_gdbus_conn,
842                         WFD_MANAGER_SERVICE, /* bus name */
843                         NULL, /* interface */
844                         NULL, /* member */
845                         WFD_MANAGER_PATH, /* object_path */
846                         NULL, /* arg0 */
847                         G_DBUS_SIGNAL_FLAGS_NONE,
848                         __asp_tech_p2p_dbus_signal_cb,
849                         NULL,
850                         NULL);
851         ASP_LOGI("Subscribed dbus signals [%d]", g_wfd_signal_id);
852
853         /* Get local P2P device address*/
854         reply = asp_tech_p2p_dbus_method_call_sync(WFD_MANAGER_CONFIG_INTERFACE,
855                                                   "GetMacAddress", NULL, &error);
856         if (error != NULL) {
857                 result = __net_wifidirect_gerror_to_enum(error);
858                 g_error_free(error);
859                 __ASP_LOG_FUNC_EXIT__;
860                 return result;
861         }
862         g_variant_get(reply, "(i&s)", &result, &str);
863         g_strlcpy(asp->p2p_local_address_str, str, MACSTR_LEN + 1);
864         macaddr_atoe(str, asp->p2p_local_address);
865
866         g_variant_unref(reply);
867
868         /* Get local P2P Device Name*/
869         reply = asp_tech_p2p_dbus_method_call_sync(WFD_MANAGER_CONFIG_INTERFACE,
870                                                   "GetDeviceName", NULL, &error);
871         if (error != NULL) {
872                 result = __net_wifidirect_gerror_to_enum(error);
873                 g_error_free(error);
874                 __ASP_LOG_FUNC_EXIT__;
875                 return result;
876         }
877         g_variant_get(reply, "(i&s)", &result, &str);
878         g_strlcpy(asp->p2p_device_name, str, DEVICE_NAME_LEN + 1);
879
880         g_variant_unref(reply);
881
882         __ASP_LOG_FUNC_EXIT__;
883         return result;
884 }
885
886 gint32 asp_tech_p2p_deinit()
887 {
888         __ASP_LOG_FUNC_ENTER__;
889         gint32 result = 0;
890
891         if (g_wfd_gdbus_conn == NULL)
892                 return -1;
893
894         /* unsubscribe signal handler */
895         g_dbus_connection_signal_unsubscribe(g_wfd_gdbus_conn, g_wfd_signal_id);
896         g_wfd_signal_id = 0;
897
898         /* unref gdbus connection */
899         g_object_unref(g_wfd_gdbus_conn);
900         g_wfd_gdbus_conn = NULL;
901
902         __ASP_LOG_FUNC_EXIT__;
903         return result;
904 }
905
906 gint32 asp_tech_p2p_get_peer_role(const guint8 *mac_addr, gint32 *is_connected, gint32 *role)
907 {
908         __ASP_LOG_FUNC_ENTER__;
909         GVariant *params = NULL;
910         GVariant *reply = NULL;
911         GError* error = NULL;
912
913         GVariantIter *iter_peer = NULL;
914         GVariant *var = NULL;
915         gchar *key = NULL;
916         gchar mac_address[18] = {0,};
917         gboolean is_group_client = FALSE;
918         gboolean is_group_owner = FALSE;
919         gboolean is_in_group = FALSE;
920         gint32 result = 0;
921
922         /* Get P2P peer info*/
923         g_snprintf(mac_address, MACSTR_LEN + 1, MACSTR, MAC2STR(mac_addr));
924         params = g_variant_new("(s)", mac_address);
925         reply = asp_tech_p2p_dbus_method_call_sync(WFD_MANAGER_MANAGE_INTERFACE,
926                                                   "GetPeerInfo", params, &error);
927         if (error != NULL) {
928                 result = __net_wifidirect_gerror_to_enum(error);
929                 g_error_free(error);
930                 __ASP_LOG_FUNC_EXIT__;
931                 return result;
932         }
933
934         g_variant_get(reply, "(ia{sv})", &result, &iter_peer);
935         if (result != 0) {
936                 __ASP_LOG_FUNC_EXIT__;
937                 return -1;
938         }
939
940         while (g_variant_iter_loop(iter_peer, "{sv}", &key, &var)) {
941                 if (!g_strcmp0(key, "IsConnected"))
942                         is_group_client = g_variant_get_boolean(var);
943
944                 else if (!g_strcmp0(key, "IsGroupOwner"))
945                         is_group_owner = g_variant_get_boolean(var);
946
947                 else if (!g_strcmp0(key, "IsInGroup"))
948                         is_in_group = g_variant_get_boolean(var);
949
950                 else
951                         ;/* Do Nothing */
952         }
953
954         g_variant_iter_free(iter_peer);
955         g_variant_unref(reply);
956         if (is_group_owner)
957                 *role = ASP_TECH_P2P_ROLE_GO;
958         if (is_group_client)
959                 *role = ASP_TECH_P2P_ROLE_GC;
960
961         if (is_in_group)
962                 *is_connected = is_in_group;
963
964         __ASP_LOG_FUNC_EXIT__;
965         return result;
966 }
967
968 gint32 __asp_tech_p2p_send_prov(asp_tech_session_request_params_s *params)
969 {
970         GVariantBuilder *builder = NULL;
971         GVariant *variant_params = NULL;
972         GVariant *reply = NULL;
973         GError* error = NULL;
974         gchar mac_str[MACSTR_LEN + 1] = {0, };
975         gint32 result = 0;
976
977         builder = g_variant_builder_new(G_VARIANT_TYPE("a{sv}"));
978
979         g_snprintf(mac_str, MACSTR_LEN + 1, MACSTR, MAC2STR(params->service_mac));
980         g_variant_builder_add(builder, "{sv}", "service_mac", g_variant_new("s", mac_str));
981         g_variant_builder_add(builder, "{sv}", "adv_id", g_variant_new("u", params->advertisement_id));
982
983         g_snprintf(mac_str, MACSTR_LEN + 1, MACSTR, MAC2STR(params->session_mac));
984         g_variant_builder_add(builder, "{sv}", "session_mac", g_variant_new("s", mac_str));
985         g_variant_builder_add(builder, "{sv}", "session_id", g_variant_new("u", params->session_id));
986         g_variant_builder_add(builder, "{sv}", "role", g_variant_new("y", params->network_role));
987         g_variant_builder_add(builder, "{sv}", "config_method", g_variant_new("u", params->network_config));
988         if (params->session_information)
989                 g_variant_builder_add(builder, "{sv}", "session _info", g_variant_new("s", params->session_information));
990
991         variant_params = g_variant_new("(a{sv})", builder);
992         g_variant_builder_unref(builder);
993
994         /* Connect ASP session via P2P group */
995         reply = asp_tech_p2p_dbus_method_call_sync(WFD_MANAGER_ASP_INTERFACE,
996                                                   "ConnectSession", variant_params, &error);
997         if (error != NULL) {
998                 result = __net_wifidirect_gerror_to_enum(error);
999                 g_error_free(error);
1000                 __ASP_LOG_FUNC_EXIT__;
1001                 return result;
1002         }
1003
1004         g_variant_get(reply, "(i)", &result);
1005         g_variant_unref(reply);
1006
1007         __ASP_LOG_FUNC_EXIT__;
1008         return result;
1009 }
1010
1011 gint32 asp_tech_p2p_connect_session(asp_tech_session_request_params_s *params)
1012 {
1013         __ASP_LOG_FUNC_ENTER__;
1014         gint32 is_connected = 0;
1015         gint32 role = ASP_TECH_P2P_ROLE_NEW;
1016         gint32 result = 0;
1017
1018         result = asp_tech_p2p_get_peer_role(params->service_mac, &is_connected, &role);
1019         if (result < 0) {
1020                 ASP_LOGE("get peer role failed");
1021                         __ASP_LOG_FUNC_EXIT__;
1022                         return ASP_ERROR_OPERATION_FAILED;
1023         }
1024
1025         if (params->network_role != ASP_TECH_P2P_ROLE_NEW &&
1026                         params->network_role == role) {
1027                 ASP_LOGE("Device can't be requested role");
1028                         __ASP_LOG_FUNC_EXIT__;
1029                         return ASP_ERROR_NETWORK_ROLE_REJECTED;
1030         }
1031         result = __asp_tech_p2p_send_prov(params);
1032
1033         __ASP_LOG_FUNC_EXIT__;
1034         return result;
1035 }
1036
1037 gint32 asp_tech_p2p_confirm_session(const guint8 *session_mac, gint32 session_id, gint32 confirm, guint32 pin)
1038 {
1039         __ASP_LOG_FUNC_ENTER__;
1040         GVariantBuilder *builder = NULL;
1041         GVariant *params = NULL;
1042         GVariant *reply = NULL;
1043         GError* error = NULL;
1044         guint8 *service_mac = NULL;
1045         guint32 adv_id = 0;
1046         gchar mac_str[MACSTR_LEN + 1] = {0, };
1047         gchar pin_str[PINSTR_LEN + 1] = {0, };
1048         gint32 result = 0;
1049
1050         builder = g_variant_builder_new(G_VARIANT_TYPE("a{sv}"));
1051
1052         g_snprintf(mac_str, MACSTR_LEN + 1, MACSTR, MAC2STR(session_mac));
1053         g_variant_builder_add(builder, "{sv}", "session_mac", g_variant_new("s", mac_str));
1054         g_variant_builder_add(builder, "{sv}", "session_id", g_variant_new("u", session_id));
1055         g_variant_builder_add(builder, "{sv}", "confirm", g_variant_new("i", confirm));
1056         if (pin != 0) {
1057                 g_snprintf(pin_str, PINSTR_LEN + 1, "%u", pin);
1058                 g_variant_builder_add(builder, "{sv}", "pin", g_variant_new("s", pin_str));
1059         }
1060         if (asp_session_get_advertisement_mac(session_mac, session_id, &service_mac)) {
1061                 g_snprintf(mac_str, MACSTR_LEN + 1, MACSTR, MAC2STR(service_mac));
1062                 g_variant_builder_add(builder, "{sv}", "service_mac", g_variant_new("s", mac_str));
1063         }
1064         if (asp_session_get_advertisement_id(session_mac, session_id, &adv_id))
1065                 g_variant_builder_add(builder, "{sv}", "adv_id", g_variant_new("u", adv_id));
1066
1067         params = g_variant_new("(a{sv})", builder);
1068         g_variant_builder_unref(builder);
1069
1070         /* Confirm session requested via P2P */
1071         reply = asp_tech_p2p_dbus_method_call_sync(WFD_MANAGER_ASP_INTERFACE,
1072                                                   "ConfirmSession", params, &error);
1073         if (error != NULL) {
1074                 result = __net_wifidirect_gerror_to_enum(error);
1075                 g_error_free(error);
1076                 __ASP_LOG_FUNC_EXIT__;
1077                 return result;
1078         }
1079
1080         g_variant_get(reply, "(i)", &result);
1081         g_variant_unref(reply);
1082
1083         __ASP_LOG_FUNC_EXIT__;
1084         return result;
1085 }
1086
1087 gint32 asp_tech_p2p_destroy_connection(const guint8 *peer_id, gint32 peer_id_length)
1088 {
1089         __ASP_LOG_FUNC_ENTER__;
1090         GVariant *reply = NULL;
1091         GError* error = NULL;
1092         gchar mac_str[MACSTR_LEN + 1] = {0, };
1093         gint32 result = 0;
1094
1095         g_snprintf(mac_str, MACSTR_LEN + 1, MACSTR, MAC2STR(peer_id));
1096         /* Destroy ASP P2P Group */
1097         reply = asp_tech_p2p_dbus_method_call_sync(WFD_MANAGER_GROUP_INTERFACE,
1098                                                   "DestroyGroup", NULL, &error);
1099         if (error != NULL) {
1100                 result = __net_wifidirect_gerror_to_enum(error);
1101                 g_error_free(error);
1102                 __ASP_LOG_FUNC_EXIT__;
1103                 return result;
1104         }
1105
1106         g_variant_get(reply, "(i)", &result);
1107         g_variant_unref(reply);
1108
1109         __ASP_LOG_FUNC_EXIT__;
1110         return result;
1111 }
1112
1113 gint32 asp_tech_p2p_is_peer_connected(const guint8 *peer_id, gint32 peer_id_length, gint32 *is_connected)
1114 {
1115         __ASP_LOG_FUNC_ENTER__;
1116         gint32 role = 0;
1117         gint32 result = 0;
1118
1119         result = asp_tech_p2p_get_peer_role(peer_id, is_connected, &role);
1120
1121         __ASP_LOG_FUNC_EXIT__;
1122         return result;
1123 }
1124
1125 asp_tech_ops_s asp_tech_p2p_ops = {
1126                 .init = asp_tech_p2p_init,
1127                 .deinit = asp_tech_p2p_deinit,
1128                 .advertise = asp_tech_p2p_advertise,
1129                 .cancel_advertise = asp_tech_p2p_cancel_advertise,
1130                 .seek = asp_tech_p2p_seek,
1131                 .cancel_seek = asp_tech_p2p_cancel_seek,
1132                 .connect_session = asp_tech_p2p_connect_session,
1133                 .confirm_session = asp_tech_p2p_confirm_session,
1134                 .destroy_connection = asp_tech_p2p_destroy_connection,
1135                 .is_peer_connected = asp_tech_p2p_is_peer_connected,
1136                 .session_request_cb = NULL,
1137                 .session_request_cb_user_data = NULL,
1138                 .session_config_request_cb = NULL,
1139                 .connect_status_cb = NULL,
1140                 .connect_status_cb_user_data = NULL,
1141                 .ip_assigned_cb = NULL,
1142                 .ip_assigned_cb_user_data = NULL,
1143 };