Fix memory leak
[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                 g_variant_builder_add(&builder, "{sv}", key, g_variant_new_string(value));
229
230         return g_variant_builder_end(&builder);
231 }
232
233 static GVariant *__g_hash_keys_to_g_variant(GHashTable *hash)
234 {
235         GVariantBuilder builder;
236
237         g_variant_builder_init(&builder, G_VARIANT_TYPE("as"));
238
239         GHashTableIter iter;
240         gpointer key, value;
241
242         g_hash_table_iter_init(&iter, hash);
243         while (g_hash_table_iter_next(&iter, &key, &value))
244                 g_variant_builder_add(&builder, "s", key);
245
246         return g_variant_builder_end(&builder);
247 }
248
249 GVariant *__asp_tech_p2p_dbus_method_call_sync_debug(const gchar* interface_name,
250                                                   const gchar* method,
251                                                   GVariant *params,
252                                                   GError **error,
253                                                   const gchar *calling_func)
254 {
255         GVariant *reply = NULL;
256
257         if (g_wfd_gdbus_conn == NULL) {
258                 ASP_LOGE("GDBusconnection is NULL");
259                 return reply;
260         }
261
262         ASP_LOGD("[%s][%s.%s]", calling_func, interface_name, method);
263         DBUS_DEBUG_VARIANT(params);
264
265         reply = g_dbus_connection_call_sync(g_wfd_gdbus_conn,
266                                             WFD_MANAGER_SERVICE, /* bus name */
267                                             WFD_MANAGER_PATH, /* object path */
268                                             interface_name, /* interface name */
269                                             method, /* method name */
270                                             params, /* GVariant *params */
271                                             NULL, /* reply_type */
272                                             G_DBUS_CALL_FLAGS_NONE, /* flags */
273                                             DBUS_REPLY_TIMEOUT_SYNC, /* timeout */
274                                             NULL, /* cancellable */
275                                             error); /* error */
276         DBUS_DEBUG_VARIANT(reply);
277         return reply;
278 }
279
280 void asp_tech_p2p_process_activation(GDBusConnection *connection,
281                 const gchar *object_path, GVariant *parameters)
282 {
283         __ASP_LOG_FUNC_ENTER__;
284
285         ASP_LOGE("Wi-Fi Direct activated");
286
287         __ASP_LOG_FUNC_EXIT__;
288         return;
289 }
290
291 void asp_tech_p2p_process_deactivation(GDBusConnection *connection,
292                 const gchar *object_path, GVariant *parameters)
293 {
294         __ASP_LOG_FUNC_ENTER__;
295
296         ASP_LOGE("Wi-Fi Direct deactivated");
297
298         __ASP_LOG_FUNC_EXIT__;
299         return;
300 }
301
302 static void __service_info_to_g_hash(const gchar *service_info,
303                 GHashTable *service_info_map)
304 {
305         const gchar *key = NULL;
306         const gchar *value = NULL;
307         gsize pos = 0;
308         gsize key_length = 0;
309         gsize value_length = 0;
310         gsize info_length = 0;
311
312         info_length = strlen(service_info);
313
314         while (service_info[pos] != '\0' && pos < info_length) {
315                 key = &service_info[pos];
316                 while (service_info[pos] != '=' && pos < info_length) {
317                         key_length++;
318                         pos++;
319                 }
320
321                 if (pos >= info_length - 1) {
322                         g_hash_table_replace(service_info_map, g_strndup(key, key_length),
323                                         g_strdup(""));
324                         break;
325                 }
326
327                 pos++;
328                 value = &service_info[pos];
329                 while (service_info[pos] != ',' && pos < info_length) {
330                         value_length++;
331                         pos++;
332                 }
333
334                 g_hash_table_replace(service_info_map, g_strndup(key, key_length),
335                                 g_strndup(value, value_length));
336                 ASP_LOGD("Insert (%s, %s) to hash.", key, value);
337
338                 if (service_info[pos] == ',' && pos == info_length)
339                         break;
340         }
341         return;
342 }
343
344 void asp_tech_p2p_process_search_result(GDBusConnection *connection,
345                 const gchar *object_path, GVariant *parameters)
346 {
347         __ASP_LOG_FUNC_ENTER__;
348
349         GVariantIter *iter = NULL;
350         GVariant *var = NULL;
351         GHashTable *service_info_map = NULL;
352         asp_event_data event;
353         const gchar *service_mac = NULL;
354         const gchar *key = NULL;
355         const gchar *str = NULL;
356         long long unsigned search_id = 0;
357         gchar *device_name = NULL;
358         guint32 advertisement_id = 0;
359         guint32 config_method = 0;
360         gchar *instance_name = NULL;
361         guint8 status = 0;
362
363         if (!parameters) {
364                 __ASP_LOG_FUNC_EXIT__;
365                 return;
366         }
367
368         g_variant_get(parameters, "(a{sv})", &iter);
369         while (g_variant_iter_loop(iter, "{sv}", &key, &var)) {
370                 if (!g_strcmp0(key, "search_id")) {
371                         g_variant_get(var, "t", &search_id);
372                 } else if (!g_strcmp0(key, "service_mac")) {
373                         g_variant_get(var, "&s", &service_mac);
374                 } else if (!g_strcmp0(key, "device_name")) {
375                         g_variant_get(var, "&s", &str);
376                         device_name = g_strndup(str, ASP_SERVICE_DEVICE_NAME_LEN);
377                 }  else if (!g_strcmp0(key, "advertisement_id")) {
378                         g_variant_get(var, "u", &advertisement_id);
379                 } else if (!g_strcmp0(key, "config_method")) {
380                         g_variant_get(var, "u", &config_method);
381                 }  else if (!g_strcmp0(key, "instance_name")) {
382                         g_variant_get(var, "&s", &str);
383                         instance_name = g_strdup(str);
384                 } else if (!g_strcmp0(key, "status")) {
385                         g_variant_get(var, "y", &status);
386                 }  else if (!g_strcmp0(key, "service_info")) {
387                         g_variant_get(var, "&s", &str);
388                         service_info_map = g_hash_table_new_full(g_str_hash,
389                                         g_str_equal, g_free, g_free);
390                         __service_info_to_g_hash(str, service_info_map);
391                 }   else {
392                                 ;/* Do Nothing */
393                 }
394         }
395
396         memset(&event, 0x0, sizeof(asp_event_data));
397         event.search_result.tech = ASP_TECH_P2P;
398         event.search_result.search_id = search_id;
399         event.search_result.advertisement_id = advertisement_id;
400         event.search_result.service_status = status;
401         if (service_mac)
402                 memcpy(event.search_result.service_mac, service_mac, MACSTR_LEN + 1);
403         event.search_result.device_name = device_name;
404         event.search_result.instance_name = instance_name;
405         event.search_result.service_info = service_info_map;
406         asp_manager_event(NULL, ASP_EVENT_SEARCH_RESULT, &event);
407
408         g_free(device_name);
409         g_free(instance_name);
410         g_hash_table_unref(service_info_map);
411         g_variant_iter_free(iter);
412
413         __ASP_LOG_FUNC_EXIT__;
414         return;
415 }
416
417 void asp_tech_p2p_process_session_request(GDBusConnection *connection,
418                 const gchar *object_path, GVariant *parameters)
419 {
420         __ASP_LOG_FUNC_ENTER__;
421
422         GVariantIter *iter = NULL;
423         GVariant *var = NULL;
424         const gchar *key = NULL;
425         const gchar *str = NULL;
426         guint8 session_mac[MAC_LEN] = {0,};
427         guint32 session_id = 0;
428         guint32 adv_id = 0;
429         gchar *device_name = NULL;
430         size_t name_length = 0;
431         guint8 *session_info = NULL;
432         size_t info_length = 0;
433         gboolean get_pin = FALSE;
434         guint32 pin = 0;
435
436         if (!parameters) {
437                 __ASP_LOG_FUNC_EXIT__;
438                 return;
439         }
440
441         g_variant_get(parameters, "(a{sv})", &iter);
442         while (g_variant_iter_loop(iter, "{sv}", &key, &var)) {
443                 if (!g_strcmp0(key, "adv_id")) {
444                         g_variant_get(var, "u", &adv_id);
445                 } else if (!g_strcmp0(key, "session_mac")) {
446                         if (asp_dbus_unpack_ay(session_mac, var, MAC_LEN) < 0) {
447                                 g_free(device_name);
448                                 g_free(session_info);
449                                 g_variant_iter_free(iter);
450                                 return;
451                         }
452                 }  else if (!g_strcmp0(key, "session_id")) {
453                         g_variant_get(var, "u", &session_id);
454                 }  else if (!g_strcmp0(key, "device_name")) {
455                         g_variant_get(var, "&s", &str);
456                         device_name = g_strndup(str, ASP_SERVICE_DEVICE_NAME_LEN);
457                         name_length = strlen(str);
458                 } else if (!g_strcmp0(key, "get_pin")) {
459                         g_variant_get(var, "b", &get_pin);
460                 } else if (!g_strcmp0(key, "pin")) {
461                         g_variant_get(var, "&s", &str);
462                         pin = (guint32)atoi(str);
463                 } else if (!g_strcmp0(key, "session_info")) {
464                         str = NULL;
465                         g_variant_get(var, "&s", &str);
466                         if (!str)
467                                 continue;
468                         info_length = strlen(str);
469                         g_free(session_info);
470                         session_info = g_try_malloc0(info_length + 1);
471                         if (session_info)
472                                 memcpy(session_info, str, info_length);
473                 } else {
474                                 ;/* Do Nothing */
475                 }
476         }
477
478         if (asp_tech_p2p_ops.session_request_cb) {
479                 asp_tech_p2p_ops.session_request_cb(0, session_mac, session_id,
480                                 adv_id, device_name, name_length,
481                                 session_info, info_length, get_pin, pin,
482                                 asp_tech_p2p_ops.session_request_cb_user_data);
483         }
484
485         g_variant_iter_free(iter);
486         g_free(device_name);
487         g_free(session_info);
488
489         __ASP_LOG_FUNC_EXIT__;
490         return;
491 }
492
493 void asp_tech_p2p_process_session_config_request(GDBusConnection *connection,
494                 const gchar *object_path, GVariant *parameters)
495 {
496         __ASP_LOG_FUNC_ENTER__;
497
498         GVariantIter *iter = NULL;
499         GVariant *var = NULL;
500         const gchar *key = NULL;
501         const gchar *str = NULL;
502         const guint8 session_mac[MAC_LEN] = {0,};
503         guint32 session_id = 0;
504         gboolean get_pin = FALSE;
505         guint32 pin = 0;
506
507         if (!parameters) {
508                 __ASP_LOG_FUNC_EXIT__;
509                 return;
510         }
511
512         g_variant_get(parameters, "(a{sv})", &iter);
513         while (g_variant_iter_loop(iter, "{sv}", &key, &var)) {
514                 if (!g_strcmp0(key, "session_id")) {
515                         g_variant_get(var, "u", &session_id);
516                 } else if (!g_strcmp0(key, "get_pin")) {
517                         g_variant_get(var, "b", &get_pin);
518                 } else if (!g_strcmp0(key, "pin")) {
519                         g_variant_get(var, "&s", &str);
520                         pin = (guint32)atoi(str);
521                 } else {
522                         ;/* Do Nothing */
523                 }
524         }
525
526         if (asp_tech_p2p_ops.session_config_request_cb) {
527                 asp_tech_p2p_ops.session_config_request_cb(0,
528                                 session_mac, session_id, get_pin, pin,
529                                 asp_tech_p2p_ops.session_config_request_cb_user_data);
530         }
531         g_variant_iter_free(iter);
532
533         __ASP_LOG_FUNC_EXIT__;
534         return;
535 }
536
537 void asp_tech_p2p_process_connect_status(GDBusConnection *connection,
538                 const gchar *object_path, GVariant *parameters)
539 {
540         __ASP_LOG_FUNC_ENTER__;
541
542         GVariantIter *iter = NULL;
543         GVariant *var = NULL;
544         const gchar *key = NULL;
545         const gchar *str = NULL;
546         guint8 session_mac[MAC_LEN] = {0,};
547         guint32 session_id = 0;
548         guint32 status = 0;
549         gchar *deferred = NULL;
550
551         if (!parameters) {
552                 __ASP_LOG_FUNC_EXIT__;
553                 return;
554         }
555
556         g_variant_get(parameters, "(a{sv})", &iter);
557         while (g_variant_iter_loop(iter, "{sv}", &key, &var)) {
558                 if (!g_strcmp0(key, "session_mac")) {
559                         if (asp_dbus_unpack_ay(session_mac, var, MAC_LEN) < 0) {
560                                 g_variant_iter_free(iter);
561                                 g_free(deferred);
562                                 return;
563                         }
564                 } else if (!g_strcmp0(key, "session_id")) {
565                         g_variant_get(var, "u", &session_id);
566                 } else if (!g_strcmp0(key, "status")) {
567                         g_variant_get(var, "i", &status);
568                 } else if (!g_strcmp0(key, "deferred")) {
569                         g_variant_get(var, "&s", &str);
570                         g_free(deferred);
571                         deferred = g_strdup(str);
572                 } else {
573                         ;/* Do Nothing */
574                 }
575         }
576
577         if (asp_tech_p2p_ops.connect_status_cb) {
578                 asp_tech_p2p_ops.connect_status_cb(0,
579                                 session_mac, session_id, status,
580                                 asp_tech_p2p_ops.connect_status_cb_user_data);
581         }
582
583         g_variant_iter_free(iter);
584         g_free(deferred);
585
586         __ASP_LOG_FUNC_EXIT__;
587         return;
588 }
589
590 void asp_tech_p2p_process_session_peer_ip(GDBusConnection *connection,
591                 const gchar *object_path, GVariant *parameters)
592 {
593         __ASP_LOG_FUNC_ENTER__;
594
595         GVariantIter *iter = NULL;
596         GVariant *var = NULL;
597         const gchar *key = NULL;
598         guint8 session_mac[MAC_LEN] = {0,};
599         guint8 service_mac[MAC_LEN] = {0,};
600         guint32 session_id = 0;
601         gchar *peer_ip = NULL;
602
603         if (!parameters) {
604                 __ASP_LOG_FUNC_EXIT__;
605                 return;
606         }
607
608         g_variant_get(parameters, "(a{sv})", &iter);
609         while (g_variant_iter_loop(iter, "{sv}", &key, &var)) {
610                 if (!g_strcmp0(key, "session_mac")) {
611                         if (asp_dbus_unpack_ay(session_mac, var, MAC_LEN) < 0) {
612                                 g_variant_iter_free(iter);
613                                 return;
614                         }
615                 } else if (!g_strcmp0(key, "session_id")) {
616                         g_variant_get(var, "u", &session_id);
617                 } else if (!g_strcmp0(key, "service_mac")) {
618                         if (asp_dbus_unpack_ay(service_mac, var, MAC_LEN) < 0) {
619                                 g_variant_iter_free(iter);
620                                 return;
621                         }
622
623                 } else if (!g_strcmp0(key, "assigned_ip_address")) {
624                         g_variant_get(var, "&s", &peer_ip);
625                 } else {
626                         ;/* Do Nothing */
627                 }
628         }
629
630         if (peer_ip == NULL) {
631                 ASP_LOGE("Invalid peer IP address");
632                 g_variant_iter_free(iter);
633                 return;
634         }
635
636         if (asp_tech_p2p_ops.ip_assigned_cb) {
637                 asp_tech_p2p_ops.ip_assigned_cb(0,
638                                 session_mac, session_id, service_mac, peer_ip,
639                                 strlen(peer_ip), asp_tech_p2p_ops.ip_assigned_cb_user_data);
640         }
641
642         g_variant_iter_free(iter);
643
644         __ASP_LOG_FUNC_EXIT__;
645         return;
646 }
647
648 gint32 asp_tech_p2p_advertise(asp_service_advertise_s *service, gint32 replace)
649 {
650         __ASP_LOG_FUNC_ENTER__;
651         GVariantBuilder *builder = NULL;
652         GVariant *params = NULL;
653         GError *error = NULL;
654         GVariant *reply = NULL;
655         gint32 result = 0;
656
657         if (!service || !g_wfd_gdbus_conn) {
658                 ASP_LOGE("Invalid parameter!");
659                 __ASP_LOG_FUNC_EXIT__;
660                 return -1;
661         }
662
663         builder = g_variant_builder_new(G_VARIANT_TYPE("a{sv}"));
664         g_variant_builder_add(builder, "{sv}", "adv_id", g_variant_new("u", service->adv_id));
665         g_variant_builder_add(builder, "{sv}", "discovery_tech", g_variant_new("i", service->discovery_tech));
666         g_variant_builder_add(builder, "{sv}", "preferred_connection", g_variant_new("y", service->preferred_connection));
667         g_variant_builder_add(builder, "{sv}", "auto_accept", g_variant_new("i", service->auto_accept));
668         g_variant_builder_add(builder, "{sv}", "status", g_variant_new("y", service->status));
669         g_variant_builder_add(builder, "{sv}", "role", g_variant_new("y", service->role));
670         g_variant_builder_add(builder, "{sv}", "replace", g_variant_new("i", replace));
671         g_variant_builder_add(builder, "{sv}", "config_method", g_variant_new("u", service->config_method));
672
673         if (service->instance_name)
674                 g_variant_builder_add(builder, "{sv}", "instance_name", g_variant_new("s", service->instance_name));
675         if (service->service_type)
676                 g_variant_builder_add(builder, "{sv}", "service_type", g_variant_new("s", service->service_type));
677         if (service->service_info_map != NULL)
678                 g_variant_builder_add(builder, "{sv}", "service_info",
679                                 __g_hash_table_to_g_variant(service->service_info_map));
680         if (service->rsp_info)
681                 g_variant_builder_add(builder, "{sv}", "rsp_info", g_variant_new("s", service->rsp_info));
682         params = g_variant_new("(a{sv})", builder);
683         g_variant_builder_unref(builder);
684
685         reply = asp_tech_p2p_dbus_method_call_sync(WFD_MANAGER_ASP_INTERFACE,
686                                                   "AdvertiseService", params, &error);
687         if (error != NULL) {
688                 result = __net_wifidirect_gerror_to_enum(error);
689                 g_error_free(error);
690                 __ASP_LOG_FUNC_EXIT__;
691                 return result;
692         }
693
694         g_variant_get(reply, "(i)", &result);
695         g_variant_unref(reply);
696
697         ASP_LOGD("%s() return : [%d]", __func__, result);
698
699         __ASP_LOG_FUNC_EXIT__;
700         return result;
701 }
702
703 gint32 asp_tech_p2p_cancel_advertise(asp_service_advertise_s *service)
704 {
705         __ASP_LOG_FUNC_ENTER__;
706         GVariant *params = NULL;
707         GError *error = NULL;
708         GVariant *reply = NULL;
709         gint32 result = 0;
710
711         if (!service || !g_wfd_gdbus_conn) {
712                 ASP_LOGE("Invalid parameter!");
713                 __ASP_LOG_FUNC_EXIT__;
714                 return -1;
715         }
716
717         params = g_variant_new("(u)", service->adv_id);
718         reply = asp_tech_p2p_dbus_method_call_sync(WFD_MANAGER_ASP_INTERFACE,
719                                                   "CancelAdvertiseService", params, &error);
720         if (error != NULL) {
721                 result = __net_wifidirect_gerror_to_enum(error);
722                 g_error_free(error);
723                 __ASP_LOG_FUNC_EXIT__;
724                 return result;
725         }
726
727         g_variant_get(reply, "(i)", &result);
728         g_variant_unref(reply);
729
730         ASP_LOGD("%s() return : [%d]", __func__, result);
731
732         __ASP_LOG_FUNC_EXIT__;
733         return result;
734 }
735
736 gint32 asp_tech_p2p_seek(asp_service_seek_s *service)
737 {
738         __ASP_LOG_FUNC_ENTER__;
739         GVariantBuilder *builder = NULL;
740         GVariant *params = NULL;
741         GError *error = NULL;
742         GVariant *reply = NULL;
743         gint32 result = 0;
744
745         if (!service || !g_wfd_gdbus_conn) {
746                 ASP_LOGE("Invalid parameter!");
747                 __ASP_LOG_FUNC_EXIT__;
748                 return -1;
749         }
750
751
752         builder = g_variant_builder_new(G_VARIANT_TYPE("a{sv}"));
753         g_variant_builder_add(builder, "{sv}", "discovery_tech", g_variant_new("i", service->discovery_tech));
754         g_variant_builder_add(builder, "{sv}", "preferred_connection", g_variant_new("y", service->preferred_connection));
755         g_variant_builder_add(builder, "{sv}", "search_id", g_variant_new("t", service->search_id));
756         g_variant_builder_add(builder, "{sv}", "service_type", g_variant_new("s", service->service_type));
757         if (service->service_info_map != NULL)
758                 g_variant_builder_add(builder, "{sv}", "service_info", __g_hash_keys_to_g_variant(service->service_info_map));
759         params = g_variant_new("(a{sv})", builder);
760         g_variant_builder_unref(builder);
761         ASP_LOGI("instance name (%s)", service->instance_name);
762
763         reply = asp_tech_p2p_dbus_method_call_sync(WFD_MANAGER_ASP_INTERFACE,
764                                                   "SeekService", params, &error);
765         if (error != NULL) {
766                 result = __net_wifidirect_gerror_to_enum(error);
767                 g_error_free(error);
768                 __ASP_LOG_FUNC_EXIT__;
769                 return result;
770         }
771
772         g_variant_get(reply, "(i)", &result);
773         g_variant_unref(reply);
774
775         ASP_LOGD("%s() return : [%d]", __func__, result);
776
777         __ASP_LOG_FUNC_EXIT__;
778         return result;
779 }
780
781 gint32 asp_tech_p2p_cancel_seek(asp_service_seek_s *service)
782 {
783         __ASP_LOG_FUNC_ENTER__;
784         GVariant *params = NULL;
785         GError *error = NULL;
786         GVariant *reply = NULL;
787         gint32 result = 0;
788
789         if (!service || !g_wfd_gdbus_conn) {
790                 ASP_LOGE("Invalid parameter!");
791                 __ASP_LOG_FUNC_EXIT__;
792                 return -1;
793         }
794
795         params = g_variant_new("(t)", service->search_id);
796         reply = asp_tech_p2p_dbus_method_call_sync(WFD_MANAGER_ASP_INTERFACE,
797                                                   "CancelSeekService", params, &error);
798         if (error != NULL) {
799                 result = __net_wifidirect_gerror_to_enum(error);
800                 g_error_free(error);
801                 __ASP_LOG_FUNC_EXIT__;
802                 return result;
803         }
804
805         g_variant_get(reply, "(i)", &result);
806         g_variant_unref(reply);
807
808         ASP_LOGD("%s() return : [%d]", __func__, result);
809
810         __ASP_LOG_FUNC_EXIT__;
811         return result;
812 }
813
814 gint32 asp_tech_p2p_init()
815 {
816         __ASP_LOG_FUNC_ENTER__;
817         GError* error = NULL;
818         GVariant *reply = NULL;
819         g_wfd_gdbus_conn = NULL;
820         asp_s *asp = NULL;
821         const gchar *str = NULL;
822         gint32 result = 0;
823
824         asp = asp_get_manager();
825         if (asp == NULL) {
826                 ASP_LOGE("Failed to get asp");
827                 __ASP_LOG_FUNC_EXIT__;
828                 return -1;
829         }
830
831         g_wfd_gdbus_conn = g_bus_get_sync(G_BUS_TYPE_SYSTEM, NULL, &error);
832         if (g_wfd_gdbus_conn == NULL) {
833                 ASP_LOGE("Failed to get connection, Error[%s]", error->message);
834                 g_error_free(error);
835                 __ASP_LOG_FUNC_EXIT__;
836                 return -1;
837         }
838
839         /* subscribe signal handler */
840         g_wfd_signal_id = g_dbus_connection_signal_subscribe(g_wfd_gdbus_conn,
841                         WFD_MANAGER_SERVICE, /* bus name */
842                         NULL, /* interface */
843                         NULL, /* member */
844                         WFD_MANAGER_PATH, /* object_path */
845                         NULL, /* arg0 */
846                         G_DBUS_SIGNAL_FLAGS_NONE,
847                         __asp_tech_p2p_dbus_signal_cb,
848                         NULL,
849                         NULL);
850         ASP_LOGI("Subscribed dbus signals [%d]", g_wfd_signal_id);
851
852         /* Get local P2P device address*/
853         reply = asp_tech_p2p_dbus_method_call_sync(WFD_MANAGER_CONFIG_INTERFACE,
854                                                   "GetMacAddress", NULL, &error);
855         if (error != NULL) {
856                 result = __net_wifidirect_gerror_to_enum(error);
857                 g_error_free(error);
858                 __ASP_LOG_FUNC_EXIT__;
859                 return result;
860         }
861         g_variant_get(reply, "(i&s)", &result, &str);
862         g_strlcpy(asp->p2p_local_address_str, str, MACSTR_LEN + 1);
863         macaddr_atoe(str, asp->p2p_local_address);
864
865         g_variant_unref(reply);
866
867         /* Get local P2P Device Name*/
868         reply = asp_tech_p2p_dbus_method_call_sync(WFD_MANAGER_CONFIG_INTERFACE,
869                                                   "GetDeviceName", NULL, &error);
870         if (error != NULL) {
871                 result = __net_wifidirect_gerror_to_enum(error);
872                 g_error_free(error);
873                 __ASP_LOG_FUNC_EXIT__;
874                 return result;
875         }
876         g_variant_get(reply, "(i&s)", &result, &str);
877         g_strlcpy(asp->p2p_device_name, str, DEVICE_NAME_LEN + 1);
878
879         g_variant_unref(reply);
880
881         __ASP_LOG_FUNC_EXIT__;
882         return result;
883 }
884
885 gint32 asp_tech_p2p_deinit()
886 {
887         __ASP_LOG_FUNC_ENTER__;
888         gint32 result = 0;
889
890         if (g_wfd_gdbus_conn == NULL)
891                 return -1;
892
893         /* unsubscribe signal handler */
894         g_dbus_connection_signal_unsubscribe(g_wfd_gdbus_conn, g_wfd_signal_id);
895         g_wfd_signal_id = 0;
896
897         /* unref gdbus connection */
898         g_object_unref(g_wfd_gdbus_conn);
899         g_wfd_gdbus_conn = NULL;
900
901         __ASP_LOG_FUNC_EXIT__;
902         return result;
903 }
904
905 gint32 asp_tech_p2p_get_peer_role(const guint8 *mac_addr, gint32 *is_connected, gint32 *role)
906 {
907         __ASP_LOG_FUNC_ENTER__;
908         GVariant *params = NULL;
909         GVariant *reply = NULL;
910         GError* error = NULL;
911
912         GVariantIter *iter_peer = NULL;
913         GVariant *var = NULL;
914         gchar *key = NULL;
915         gchar mac_address[18] = {0,};
916         gboolean is_group_client = FALSE;
917         gboolean is_group_owner = FALSE;
918         gboolean is_in_group = FALSE;
919         gint32 result = 0;
920
921         /* Get P2P peer info*/
922         g_snprintf(mac_address, MACSTR_LEN + 1, MACSTR, MAC2STR(mac_addr));
923         params = g_variant_new("(s)", mac_address);
924         reply = asp_tech_p2p_dbus_method_call_sync(WFD_MANAGER_MANAGE_INTERFACE,
925                                                   "GetPeerInfo", params, &error);
926         if (error != NULL) {
927                 result = __net_wifidirect_gerror_to_enum(error);
928                 g_error_free(error);
929                 __ASP_LOG_FUNC_EXIT__;
930                 return result;
931         }
932
933         g_variant_get(reply, "(ia{sv})", &result, &iter_peer);
934         if (result != 0) {
935                 __ASP_LOG_FUNC_EXIT__;
936                 return -1;
937         }
938
939         while (g_variant_iter_loop(iter_peer, "{sv}", &key, &var)) {
940                 if (!g_strcmp0(key, "IsConnected"))
941                         is_group_client = g_variant_get_boolean(var);
942
943                 else if (!g_strcmp0(key, "IsGroupOwner"))
944                         is_group_owner = g_variant_get_boolean(var);
945
946                 else if (!g_strcmp0(key, "IsInGroup"))
947                         is_in_group = g_variant_get_boolean(var);
948
949                 else
950                         ;/* Do Nothing */
951         }
952
953         g_variant_iter_free(iter_peer);
954         g_variant_unref(reply);
955         if (is_group_owner)
956                 *role = ASP_TECH_P2P_ROLE_GO;
957         if (is_group_client)
958                 *role = ASP_TECH_P2P_ROLE_GC;
959
960         if (is_in_group)
961                 *is_connected = is_in_group;
962
963         __ASP_LOG_FUNC_EXIT__;
964         return result;
965 }
966
967 gint32 __asp_tech_p2p_send_prov(asp_tech_session_request_params_s *params)
968 {
969         GVariantBuilder *builder = NULL;
970         GVariant *variant_params = NULL;
971         GVariant *reply = NULL;
972         GError* error = NULL;
973         gchar mac_str[MACSTR_LEN + 1] = {0, };
974         gint32 result = 0;
975
976         builder = g_variant_builder_new(G_VARIANT_TYPE("a{sv}"));
977
978         g_snprintf(mac_str, MACSTR_LEN + 1, MACSTR, MAC2STR(params->service_mac));
979         g_variant_builder_add(builder, "{sv}", "service_mac", g_variant_new("s", mac_str));
980         g_variant_builder_add(builder, "{sv}", "adv_id", g_variant_new("u", params->advertisement_id));
981
982         g_snprintf(mac_str, MACSTR_LEN + 1, MACSTR, MAC2STR(params->session_mac));
983         g_variant_builder_add(builder, "{sv}", "session_mac", g_variant_new("s", mac_str));
984         g_variant_builder_add(builder, "{sv}", "session_id", g_variant_new("u", params->session_id));
985         g_variant_builder_add(builder, "{sv}", "role", g_variant_new("y", params->network_role));
986         g_variant_builder_add(builder, "{sv}", "config_method", g_variant_new("u", params->network_config));
987         if (params->session_information)
988                 g_variant_builder_add(builder, "{sv}", "session _info", g_variant_new("s", params->session_information));
989
990         variant_params = g_variant_new("(a{sv})", builder);
991         g_variant_builder_unref(builder);
992
993         /* Connect ASP session via P2P group */
994         reply = asp_tech_p2p_dbus_method_call_sync(WFD_MANAGER_ASP_INTERFACE,
995                                                   "ConnectSession", variant_params, &error);
996         if (error != NULL) {
997                 result = __net_wifidirect_gerror_to_enum(error);
998                 g_error_free(error);
999                 __ASP_LOG_FUNC_EXIT__;
1000                 return result;
1001         }
1002
1003         g_variant_get(reply, "(i)", &result);
1004         g_variant_unref(reply);
1005
1006         __ASP_LOG_FUNC_EXIT__;
1007         return result;
1008 }
1009
1010 gint32 asp_tech_p2p_connect_session(asp_tech_session_request_params_s *params)
1011 {
1012         __ASP_LOG_FUNC_ENTER__;
1013         gint32 is_connected = 0;
1014         gint32 role = ASP_TECH_P2P_ROLE_NEW;
1015         gint32 result = 0;
1016
1017         result = asp_tech_p2p_get_peer_role(params->service_mac, &is_connected, &role);
1018         if (result < 0) {
1019                 ASP_LOGE("get peer role failed");
1020                         __ASP_LOG_FUNC_EXIT__;
1021                         return ASP_ERROR_OPERATION_FAILED;
1022         }
1023
1024         if (params->network_role != ASP_TECH_P2P_ROLE_NEW &&
1025                         params->network_role == role) {
1026                 ASP_LOGE("Device can't be requested role");
1027                         __ASP_LOG_FUNC_EXIT__;
1028                         return ASP_ERROR_NETWORK_ROLE_REJECTED;
1029         }
1030         result = __asp_tech_p2p_send_prov(params);
1031
1032         __ASP_LOG_FUNC_EXIT__;
1033         return result;
1034 }
1035
1036 gint32 asp_tech_p2p_confirm_session(const guint8 *session_mac, gint32 session_id, gint32 confirm, guint32 pin)
1037 {
1038         __ASP_LOG_FUNC_ENTER__;
1039         GVariantBuilder *builder = NULL;
1040         GVariant *params = NULL;
1041         GVariant *reply = NULL;
1042         GError* error = NULL;
1043         guint8 *service_mac = NULL;
1044         guint32 adv_id = 0;
1045         gchar mac_str[MACSTR_LEN + 1] = {0, };
1046         gchar pin_str[PINSTR_LEN + 1] = {0, };
1047         gint32 result = 0;
1048
1049         builder = g_variant_builder_new(G_VARIANT_TYPE("a{sv}"));
1050
1051         g_snprintf(mac_str, MACSTR_LEN + 1, MACSTR, MAC2STR(session_mac));
1052         g_variant_builder_add(builder, "{sv}", "session_mac", g_variant_new("s", mac_str));
1053         g_variant_builder_add(builder, "{sv}", "session_id", g_variant_new("u", session_id));
1054         g_variant_builder_add(builder, "{sv}", "confirm", g_variant_new("i", confirm));
1055         if (pin != 0) {
1056                 g_snprintf(pin_str, PINSTR_LEN + 1, "%u", pin);
1057                 g_variant_builder_add(builder, "{sv}", "pin", g_variant_new("s", pin_str));
1058         }
1059         if (asp_session_get_advertisement_mac(session_mac, session_id, &service_mac)) {
1060                 g_snprintf(mac_str, MACSTR_LEN + 1, MACSTR, MAC2STR(service_mac));
1061                 g_variant_builder_add(builder, "{sv}", "service_mac", g_variant_new("s", mac_str));
1062         }
1063         if (asp_session_get_advertisement_id(session_mac, session_id, &adv_id))
1064                 g_variant_builder_add(builder, "{sv}", "adv_id", g_variant_new("u", adv_id));
1065
1066         params = g_variant_new("(a{sv})", builder);
1067         g_variant_builder_unref(builder);
1068
1069         /* Confirm session requested via P2P */
1070         reply = asp_tech_p2p_dbus_method_call_sync(WFD_MANAGER_ASP_INTERFACE,
1071                                                   "ConfirmSession", params, &error);
1072         if (error != NULL) {
1073                 result = __net_wifidirect_gerror_to_enum(error);
1074                 g_error_free(error);
1075                 __ASP_LOG_FUNC_EXIT__;
1076                 return result;
1077         }
1078
1079         g_variant_get(reply, "(i)", &result);
1080         g_variant_unref(reply);
1081
1082         __ASP_LOG_FUNC_EXIT__;
1083         return result;
1084 }
1085
1086 gint32 asp_tech_p2p_destroy_connection(const guint8 *peer_id, gint32 peer_id_length)
1087 {
1088         __ASP_LOG_FUNC_ENTER__;
1089         GVariant *reply = NULL;
1090         GError* error = NULL;
1091         gchar mac_str[MACSTR_LEN + 1] = {0, };
1092         gint32 result = 0;
1093
1094         g_snprintf(mac_str, MACSTR_LEN + 1, MACSTR, MAC2STR(peer_id));
1095         /* Destroy ASP P2P Group */
1096         reply = asp_tech_p2p_dbus_method_call_sync(WFD_MANAGER_GROUP_INTERFACE,
1097                                                   "DestroyGroup", NULL, &error);
1098         if (error != NULL) {
1099                 result = __net_wifidirect_gerror_to_enum(error);
1100                 g_error_free(error);
1101                 __ASP_LOG_FUNC_EXIT__;
1102                 return result;
1103         }
1104
1105         g_variant_get(reply, "(i)", &result);
1106         g_variant_unref(reply);
1107
1108         __ASP_LOG_FUNC_EXIT__;
1109         return result;
1110 }
1111
1112 gint32 asp_tech_p2p_is_peer_connected(const guint8 *peer_id, gint32 peer_id_length, gint32 *is_connected)
1113 {
1114         __ASP_LOG_FUNC_ENTER__;
1115         gint32 role = 0;
1116         gint32 result = 0;
1117
1118         result = asp_tech_p2p_get_peer_role(peer_id, is_connected, &role);
1119
1120         __ASP_LOG_FUNC_EXIT__;
1121         return result;
1122 }
1123
1124 asp_tech_ops_s asp_tech_p2p_ops = {
1125                 .init = asp_tech_p2p_init,
1126                 .deinit = asp_tech_p2p_deinit,
1127                 .advertise = asp_tech_p2p_advertise,
1128                 .cancel_advertise = asp_tech_p2p_cancel_advertise,
1129                 .seek = asp_tech_p2p_seek,
1130                 .cancel_seek = asp_tech_p2p_cancel_seek,
1131                 .connect_session = asp_tech_p2p_connect_session,
1132                 .confirm_session = asp_tech_p2p_confirm_session,
1133                 .destroy_connection = asp_tech_p2p_destroy_connection,
1134                 .is_peer_connected = asp_tech_p2p_is_peer_connected,
1135                 .session_request_cb = NULL,
1136                 .session_request_cb_user_data = NULL,
1137                 .session_config_request_cb = NULL,
1138                 .connect_status_cb = NULL,
1139                 .connect_status_cb_user_data = NULL,
1140                 .ip_assigned_cb = NULL,
1141                 .ip_assigned_cb_user_data = NULL,
1142 };