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