wmesh-manager: Send authenticated info in get_station_info
[platform/core/connectivity/wifi-mesh-manager.git] / src / wmesh-service-interface.c
1 /*
2  * Network Configuration Module
3  *
4  * Copyright (c) 2017 Samsung Electronics Co., Ltd. All rights reserved.
5  *
6  * Licensed under the Apache License, Version 2.0 (the "License");
7  * you may not use this file except in compliance with the License.
8  * You may obtain a copy of the License at
9  *
10  * http://www.apache.org/licenses/LICENSE-2.0
11  *
12  * Unless required by applicable law or agreed to in writing, software
13  * distributed under the License is distributed on an "AS IS" BASIS,
14  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15  * See the License for the specific language governing permissions and
16  * limitations under the License.
17  *
18  */
19 #include <stdlib.h>
20 #include <string.h>
21
22 #include <glib.h>
23 #include <gio/gio.h>
24 #include <wifi-manager.h>
25
26 #include "wmesh.h"
27 #include "wmesh-log.h"
28 #include "wmesh-util.h"
29 #include "wmesh-gdbus.h"
30 #include "wmesh-service.h"
31 #include "wmesh-peer-monitor.h"
32 #include "wmesh-service-interface.h"
33 #include "wmesh-generated-code.h"
34
35 #include "wmesh-request.h"
36 #include "wmesh-interface.h"
37
38 static NetWmesh *meshd_dbus_object;
39 static Manager *meshd_activator_dbus_object;
40
41 /* global list to care resource handle for each client */
42 static GList *meshd_dbus_client_list;
43 static GMutex meshd_dbus_client_list_mutex;
44
45 typedef struct _meshd_dbus_client_s {
46         gchar *bus_name;
47 } meshd_dbus_client_s;
48
49 #define CASE_TO_STR(x) case x: return #x;
50
51 static const char* wifi_error_to_string(wifi_manager_error_e err)
52 {
53         switch (err) {
54         /* CHECK: List all enum values here */
55         CASE_TO_STR(WIFI_MANAGER_ERROR_NONE)
56         CASE_TO_STR(WIFI_MANAGER_ERROR_INVALID_PARAMETER)
57         CASE_TO_STR(WIFI_MANAGER_ERROR_OUT_OF_MEMORY)
58         CASE_TO_STR(WIFI_MANAGER_ERROR_INVALID_OPERATION)
59         CASE_TO_STR(WIFI_MANAGER_ERROR_ADDRESS_FAMILY_NOT_SUPPORTED)
60         CASE_TO_STR(WIFI_MANAGER_ERROR_OPERATION_FAILED)
61         CASE_TO_STR(WIFI_MANAGER_ERROR_NO_CONNECTION)
62         CASE_TO_STR(WIFI_MANAGER_ERROR_NOW_IN_PROGRESS)
63         CASE_TO_STR(WIFI_MANAGER_ERROR_ALREADY_EXISTS)
64         CASE_TO_STR(WIFI_MANAGER_ERROR_OPERATION_ABORTED)
65         CASE_TO_STR(WIFI_MANAGER_ERROR_DHCP_FAILED)
66         CASE_TO_STR(WIFI_MANAGER_ERROR_INVALID_KEY)
67         CASE_TO_STR(WIFI_MANAGER_ERROR_NO_REPLY)
68         CASE_TO_STR(WIFI_MANAGER_ERROR_SECURITY_RESTRICTED)
69         CASE_TO_STR(WIFI_MANAGER_ERROR_ALREADY_INITIALIZED)
70         CASE_TO_STR(WIFI_MANAGER_ERROR_PERMISSION_DENIED)
71         CASE_TO_STR(WIFI_MANAGER_ERROR_NOT_SUPPORTED)
72         default :
73                 return "WIFI_MANAGER_ERROR_UNKNOWN";
74         }
75 }
76
77 NetWmesh* wmeshd_dbus_get_object()
78 {
79         return meshd_dbus_object;
80 }
81
82 int64_t wmeshd_dbus_generate_signal_number()
83 {
84         static int64_t i = 0;
85
86         return i++;
87 }
88
89 static int _wmeshd_dbus_client_list_cleanup(GList *client_list)
90 {
91         meshd_dbus_client_s *client;
92
93         wmeshd_check_null_ret_error("client_list", client_list, FALSE);
94
95         client = client_list->data;
96
97         free(client->bus_name);
98         client->bus_name = NULL;
99         free(client);
100         g_list_free(client_list);
101
102         return WMESHD_ERROR_NONE;
103 }
104
105 static int _wmeshd_dbus_client_list_compare_bus_name(const void *a, const void *b)
106 {
107         const meshd_dbus_client_s *client = a;
108
109         return g_strcmp0(client->bus_name, b);
110 }
111
112 static inline GList* _wmeshd_dbus_client_list_find_client(const gchar *owner)
113 {
114         return g_list_find_custom(meshd_dbus_client_list, owner,
115                         _wmeshd_dbus_client_list_compare_bus_name);
116 }
117
118 static void _wmeshd_dbus_name_owner_changed_cb(GDBusConnection *conn,
119                 const gchar *sender_name,
120                 const gchar *object_path,
121                 const gchar *interface_name,
122                 const gchar *signal_name,
123                 GVariant *parameters,
124                 gpointer user_data)
125 {
126         int ret;
127         GList *client = NULL;
128         gchar *name, *old_owner, *new_owner;
129
130         NOTUSED(conn);
131         NOTUSED(sender_name);
132         NOTUSED(object_path);
133         NOTUSED(interface_name);
134         NOTUSED(signal_name);
135         NOTUSED(user_data);
136
137         g_variant_get(parameters, "(&s&s&s)", &name, &old_owner, &new_owner);
138
139         if (0 == strlen(new_owner)) {
140                 g_mutex_lock(&meshd_dbus_client_list_mutex);
141                 client = _wmeshd_dbus_client_list_find_client(old_owner);
142                 if (client) { /* found bus name in our bus list */
143                         WMESH_LOGD("bus(%s) stopped", old_owner);
144                         meshd_dbus_client_list = g_list_remove_link(meshd_dbus_client_list, client);
145                 }
146                 g_mutex_unlock(&meshd_dbus_client_list_mutex);
147
148                 if (client) {
149                         ret = _wmeshd_dbus_client_list_cleanup(client);
150                         if (WMESHD_ERROR_NONE != ret)
151                                 WMESH_LOGE("_wmeshd_dbus_client_list_cleanup() Fail(%d)", ret);
152                 }
153         }
154 }
155
156 static int _wmeshd_dbus_subscribe_name_owner_changed(GDBusConnection *conn)
157 {
158         unsigned int id;
159
160         id = g_dbus_connection_signal_subscribe(conn,
161                         "org.freedesktop.DBus", /* bus name */
162                         "org.freedesktop.DBus", /* interface */
163                         "NameOwnerChanged", /* member */
164                         "/org/freedesktop/DBus", /* path */
165                         NULL, /* arg0 */
166                         G_DBUS_SIGNAL_FLAGS_NONE,
167                         _wmeshd_dbus_name_owner_changed_cb,
168                         NULL,
169                         NULL);
170         if (0 == id) {
171                 WMESH_LOGE("g_dbus_connection_signal_subscribe() Fail");
172                 return WMESHD_ERROR_IO_ERROR;
173         }
174
175         return WMESHD_ERROR_NONE;
176 }
177
178 static gboolean _wmeshd_dbus_handle_enable(Manager *object,
179                 GDBusMethodInvocation *invocation,
180                 gpointer user_data)
181 {
182         int ret = WMESHD_ERROR_NONE;
183         wmesh_service *service = (wmesh_service *)user_data;
184         wmesh_interface_s *info = service->interface_info;
185
186         wifi_manager_h wifi_handle = NULL;
187         bool wifi_activated = false;
188
189         /* Initialize Wi-Fi driver */
190         ret = wifi_manager_initialize(&wifi_handle);
191         if (WIFI_MANAGER_ERROR_NONE != ret)
192                 WMESH_LOGE("Failed to get wifi manager handle ! [%s(%X)]",
193                         wifi_error_to_string(ret), ret);
194
195         wifi_manager_is_activated(wifi_handle, &wifi_activated);
196         if (false == wifi_activated) {
197                 ret = wifi_manager_activate(wifi_handle, NULL, NULL);
198                 if (WIFI_MANAGER_ERROR_NONE != ret)
199                         WMESH_LOGE("Failed to activate wifi ! [%s(%X)]",
200                                 wifi_error_to_string(ret), ret);
201         }
202         wifi_manager_deinitialize(wifi_handle);
203
204         if (service->mesh_activated) {
205                 /* Already activated */
206                 manager_complete_enable(object, invocation, WMESHD_ERROR_NONE);
207                 goto FINISH;
208         }
209
210         /* Do API response first */
211         manager_complete_enable(object, invocation, ret);
212         service->mesh_activated = TRUE;
213
214         wmeshd_check_null_ret_error("info", info, FALSE);
215
216         /* Register event handler first */
217         ret = wmesh_request_register_event_handler(service);
218         if (WMESHD_ERROR_IN_PROGRESS == ret) {
219                 WMESH_LOGE("Currently set netlink event handler !! [%d]", ret);
220                 ret = WMESHD_ERROR_NONE;
221         } else if (WMESHD_ERROR_NONE != ret) {
222                 WMESH_LOGE("Failed to register mesh event handler !! [%d]", ret);
223         }
224
225         ret = wmesh_interface_initialize(service->interface_info);
226         if (WMESHD_ERROR_NONE != ret) {
227                 WMESH_LOGE("Failed to wmesh_interface_initialize [%d]", ret);
228                 goto FINISH;
229         }
230
231 FINISH:
232         net_wmesh_emit_mesh_enabled(wmeshd_dbus_get_object(), ret);
233
234         return TRUE;
235 }
236
237 static gboolean _wmeshd_dbus_handle_disable(Manager *object,
238                 GDBusMethodInvocation *invocation,
239                 gpointer user_data)
240 {
241         int ret = WMESHD_ERROR_NONE;
242         wmesh_service *service = (wmesh_service *)user_data;
243         wmesh_interface_s *info = service->interface_info;
244
245         wmeshd_check_null_ret_error("info", info, FALSE);
246
247         /* Make response first */
248         manager_complete_disable(object, invocation, ret);
249
250         ret = wmesh_request_unregister_event_handler();
251         if (WMESHD_ERROR_NONE != ret)
252                 WMESH_LOGE("Failed to unregister mesh event handler !! [%d]", ret);
253
254         /* Terminate daemon */
255         wmeshd_service_exit(service);
256
257         return TRUE;
258 }
259
260 static gboolean _wmeshd_dbus_handle_scan(NetWmesh *object,
261                 GDBusMethodInvocation *invocation,
262                 gpointer user_data)
263 {
264         int ret = WMESHD_ERROR_NONE;
265         wmesh_service *service = (wmesh_service *)user_data;
266         wmesh_interface_s *info = service->interface_info;
267
268         wmeshd_check_null_ret_error("info", info, FALSE);
269
270         ret = wmesh_request_scan(service);
271         if (WMESHD_ERROR_NONE != ret)
272                 WMESH_LOGE("Failed to wmesh_request_scan !");
273
274         net_wmesh_complete_scan(object, invocation, ret);
275
276         return TRUE;
277 }
278
279 static gboolean _wmeshd_dbus_handle_specific_scan(NetWmesh *object,
280                 GDBusMethodInvocation *invocation,
281                 gchar *mesh_id,
282                 gint channel,
283                 gpointer user_data)
284 {
285         int ret = WMESHD_ERROR_NONE;
286         wmesh_service *service = (wmesh_service *)user_data;
287         wmesh_interface_s *info = service->interface_info;
288
289         wmeshd_check_null_ret_error("info", info, FALSE);
290
291         ret = wmesh_request_specific_scan(service, mesh_id, channel);
292         if (WMESHD_ERROR_NONE != ret)
293                 WMESH_LOGE("Failed to wmesh_request_specific_scan !");
294
295         net_wmesh_complete_specific_scan(object, invocation, ret);
296
297         return TRUE;
298 }
299
300 static gboolean _wmeshd_dbus_handle_cancel_scan(NetWmesh *object,
301                 GDBusMethodInvocation *invocation,
302                 gpointer user_data)
303 {
304         int ret = WMESHD_ERROR_NONE;
305         wmesh_service *service = (wmesh_service *)user_data;
306
307         ret = wmesh_request_cancel_scan(service);
308         if (WMESHD_ERROR_NONE != ret)
309                 WMESH_LOGE("Failed to wmesh_request_cancel_scan");
310
311         net_wmesh_complete_cancel_scan(object, invocation, ret);
312
313         return TRUE;
314 }
315
316 static void _on_scan_result_destroy(gpointer data)
317 {
318         wmesh_scan_result_s *scan_item = (wmesh_scan_result_s *)data;
319
320         if (scan_item) {
321                 g_free(scan_item->mesh_id);
322                 g_free(scan_item->bssid);
323                 g_free(scan_item->object_path);
324         }
325         g_free(scan_item);
326 }
327
328 static void _on_peer_info_destroy(gpointer data)
329 {
330         wmesh_peer_info_s *peer = (wmesh_peer_info_s *)data;
331         if (peer)
332                 g_free(peer->address);
333         g_free(peer);
334 }
335
336 static void _on_station_list_destroy(gpointer data)
337 {
338         wmesh_station_info_s *info = (wmesh_station_info_s*)data;
339
340         if (info) {
341                 g_free(info->bssid);
342                 g_free(info);
343         }
344 }
345
346 static void _on_mpath_list_destroy(gpointer data)
347 {
348         wmesh_mpath_info_s *info = (wmesh_mpath_info_s*)data;
349
350         if (info) {
351                 g_free(info->dest_addr);
352                 g_free(info->next_hop);
353                 g_free(info->interface);
354                 g_free(info);
355         }
356 }
357
358 static gboolean _wmeshd_dbus_handle_get_found_mesh_networks(NetWmesh *object,
359                 GDBusMethodInvocation *invocation,
360                 gpointer user_data)
361 {
362         int ret = WMESHD_ERROR_NONE;
363         wmesh_service *service = (wmesh_service *)user_data;
364
365         GVariantBuilder builder;
366         GVariant* networks;
367         GList *iter = NULL;
368         wmesh_scan_result_s *scan_item = NULL;
369
370         WMESH_LOGD("Request to get scanned mesh network list");
371
372         ret = wmesh_request_get_networks(service);
373         if (WMESHD_ERROR_NONE != ret)
374                 WMESH_LOGE("Failed to wmesh_request_get_networks");
375
376         g_variant_builder_init(&builder, G_VARIANT_TYPE("aa{sv}"));
377
378         /* scanned_mesh_network would be filled above request */
379         iter = service->scanned_mesh_network;
380         while (iter != NULL) {
381                 scan_item = (wmesh_scan_result_s*)iter->data;
382
383                 g_variant_builder_open(&builder, G_VARIANT_TYPE_VARDICT);
384                 g_variant_builder_add(&builder, "{sv}", "mesh_id",
385                                 g_variant_new_string(scan_item->mesh_id));
386                 g_variant_builder_add(&builder, "{sv}", "bssid",
387                                 g_variant_new_string(scan_item->bssid));
388                 g_variant_builder_add(&builder, "{sv}", "rssi",
389                                 g_variant_new_int32(scan_item->rssi));
390                 g_variant_builder_add(&builder, "{sv}", "channel",
391                                 g_variant_new_uint32(scan_item->channel));
392                 g_variant_builder_add(&builder, "{sv}", "data_rate",
393                                 g_variant_new_int32(scan_item->data_rate));
394                 g_variant_builder_add(&builder, "{sv}", "security",
395                                 g_variant_new_uint32((int)scan_item->security));
396                 g_variant_builder_add(&builder, "{sv}", "state",
397                                 g_variant_new_uint32(scan_item->state));
398                 g_variant_builder_close(&builder);
399
400                 iter = g_list_next(iter);
401         }
402
403         networks = g_variant_builder_end(&builder);
404
405         net_wmesh_complete_get_found_mesh_networks(object, invocation, networks, ret);
406
407         return TRUE;
408 }
409
410 static gboolean _wmeshd_dbus_handle_enable_mesh(NetWmesh *object,
411                 GDBusMethodInvocation *invocation,
412                 gpointer user_data)
413 {
414         int ret = WMESHD_ERROR_NONE;
415         wmesh_service *service = (wmesh_service *)user_data;
416
417         /* It handles creating virtual network and bridge */
418         ret = wmesh_request_enable_network(service);
419         if (WMESHD_ERROR_NONE != ret)
420                 WMESH_LOGE("Failed to wmesh_request_enable_network [%d]", ret);
421
422         wmesh_start_monitor_service(service);
423
424         net_wmesh_complete_enable_mesh(object, invocation, ret);
425
426         return TRUE;
427 }
428
429 static gboolean _wmeshd_dbus_handle_disable_mesh(NetWmesh *object,
430                 GDBusMethodInvocation *invocation,
431                 gpointer user_data)
432 {
433         int ret = WMESHD_ERROR_NONE;
434         wmesh_service *service = (wmesh_service *)user_data;
435         wmesh_interface_s *info = service->interface_info;
436
437         wmeshd_check_null_ret_error("info", info, FALSE);
438
439         if (FALSE == service->mesh_activated) {
440                 WMESH_LOGD("Mesh network is not activated yet");
441                 ret = WMESHD_ERROR_OPERATION_FAILED;
442                 net_wmesh_complete_disable_mesh(object, invocation, ret);
443                 return TRUE;
444         }
445
446         ret = wmesh_request_disable_network(service);
447         if (WMESHD_ERROR_NONE != ret)
448                 WMESH_LOGE("Failed to disable mesh network !");
449
450         /* Stop Mesh Node Monitoring Service */
451         wmesh_stop_monitor_service(service);
452         /* Make response */
453         net_wmesh_complete_disable_mesh(object, invocation, ret);
454
455         return TRUE;
456 }
457
458 static gboolean _wmeshd_dbus_handle_is_mesh_enabled(NetWmesh *object,
459                 GDBusMethodInvocation *invocation,
460                 gpointer user_data)
461 {
462         int ret = WMESHD_ERROR_NONE;
463         gboolean state = TRUE;
464         wmesh_service *service = (wmesh_service *)user_data;
465
466         /* It handles creating virtual network and bridge */
467         ret = wmesh_interface_check(service->interface_info->mesh_interface);
468         if (WMESHD_ERROR_NONE != ret) {
469                 WMESH_LOGE("Mesh Interface doesn't exists");
470                 state = FALSE;
471         }
472
473         net_wmesh_complete_is_mesh_enabled(object, invocation, state);
474
475         return TRUE;
476 }
477
478 static gboolean _wmeshd_dbus_handle_is_joined(NetWmesh *object,
479                 GDBusMethodInvocation *invocation,
480                 gpointer user_data)
481 {
482         int ret = WMESHD_ERROR_NONE;
483         gboolean state = FALSE;
484         wmesh_service *service = (wmesh_service *)user_data;
485
486         ret = wmesh_request_get_joined_network(service);
487         if (WMESHD_ERROR_NONE == ret) {
488                 if (service->joined_network)
489                         state = TRUE;
490         }
491
492         net_wmesh_complete_is_joined(object, invocation, state, ret);
493
494         return TRUE;
495 }
496
497 static gboolean _wmeshd_dbus_handle_get_joined_mesh_network(NetWmesh *object,
498                 GDBusMethodInvocation *invocation,
499                 gpointer user_data)
500 {
501         int ret = WMESHD_ERROR_NONE;
502         wmesh_service *service = (wmesh_service *)user_data;
503         wmesh_network_info_s *joined = NULL;
504
505         ret = wmesh_request_get_joined_network(service);
506         if (WMESHD_ERROR_NONE == ret) {
507                 joined = service->joined_network;
508                 if (joined) {
509                         net_wmesh_complete_get_joined_mesh_network(object, invocation,
510                                 joined->mesh_id, joined->bssid,
511                                 joined->channel, (int)joined->security,
512                                 joined->state, joined->ipv4_type, joined->ipv4_address,
513                                 joined->ipv4_netmask, ret);
514                 } else {
515                         net_wmesh_complete_get_joined_mesh_network(object, invocation,
516                                 "", "", 0, 0, 0, 0, "", "", WMESHD_ERROR_NO_DATA);
517                 }
518         } else {
519                 net_wmesh_complete_get_joined_mesh_network(object, invocation,
520                         "", "", 0, 0, 0, 0, "", "", ret);
521         }
522
523         return TRUE;
524 }
525
526 static gboolean _wmeshd_dbus_handle_get_connected_peers(NetWmesh *object,
527                 GDBusMethodInvocation *invocation,
528                 gpointer user_data)
529 {
530         int ret = WMESHD_ERROR_NONE;
531         wmesh_service *service = (wmesh_service *)user_data;
532
533         GVariantBuilder builder;
534         GVariant* peer_list;
535         GList *iter = NULL;
536         wmesh_peer_info_s *peer = NULL;
537
538         WMESH_LOGD("Request to get connected peers");
539
540         ret = wmesh_request_get_connected_peers(service);
541         if (WMESHD_ERROR_NONE != ret)
542                 WMESH_LOGE("Failed to wmesh_request_get_connected_peers");
543         g_variant_builder_init(&builder, G_VARIANT_TYPE("aa{sv}"));
544
545         iter = service->connected_mesh_peers;
546         while (iter != NULL) {
547                 peer = (wmesh_peer_info_s*)iter->data;
548
549                 g_variant_builder_open(&builder, G_VARIANT_TYPE_VARDICT);
550                 g_variant_builder_add(&builder, "{sv}", "Address",
551                                 g_variant_new_string(peer->address));
552                 g_variant_builder_close(&builder);
553
554                 iter = g_list_next(iter);
555         }
556
557         peer_list = g_variant_builder_end(&builder);
558
559         net_wmesh_complete_get_connected_peers(object, invocation, peer_list, ret);
560
561         return TRUE;
562 }
563
564 static gboolean _wmeshd_dbus_handle_set_gate(NetWmesh *object,
565                 GDBusMethodInvocation *invocation, gint16 gate_announce, guint hwmp_root_mode,
566                 gboolean stp, gpointer user_data)
567 {
568         int ret = WMESHD_ERROR_NONE;
569         wmesh_service *service = (wmesh_service *)user_data;
570         wmesh_interface_s *info = service->interface_info;
571
572         WMESH_LOGD("gate_announce = %d", gate_announce);
573         WMESH_LOGD("HWMP_Root_Mode = %d", hwmp_root_mode);
574         WMESH_LOGD("STP = %d", stp);
575
576         info->gate_announce = gate_announce;
577         info->hwmp_root_mode = hwmp_root_mode;
578         info->stp = stp;
579
580         /* Set STP and gate_announce for connmand */
581         ret = wmesh_gdbus_set_mesh_gate(service);
582         if (WMESHD_ERROR_NONE != ret)
583                 WMESH_LOGE("Failed to wmesh_gdbus_set_mesh_gate [%d]", ret);
584
585         /* Set STP and gate_announce right now */
586         ret = wmesh_request_set_mesh_gate(info->bridge_interface,
587                         info->mesh_interface, info->external_interface);
588         if (WMESHD_ERROR_NONE != ret)
589                 WMESH_LOGE("Failed to wmesh_gdbus_set_mesh_gate [%d]", ret);
590
591
592         net_wmesh_complete_set_gate(object, invocation, ret);
593
594         return TRUE;
595 }
596
597 static gboolean _wmeshd_dbus_handle_unset_gate(NetWmesh *object,
598                 GDBusMethodInvocation *invocation,
599                 gpointer user_data)
600 {
601         int ret = WMESHD_ERROR_NONE;
602         wmesh_service *service = (wmesh_service *)user_data;
603         wmesh_interface_s *info = service->interface_info;
604
605         info->gate_announce = 0;
606         info->hwmp_root_mode = 0;
607         info->stp = 0;
608
609         /* Set STP and gate_announce for connmand */
610         ret = wmesh_gdbus_set_mesh_gate(service);
611         if (WMESHD_ERROR_NONE != ret)
612                 WMESH_LOGE("Failed to wmesh_gdbus_set_mesh_gate [%d]", ret);
613
614         /* Unset STP and Gate Annouce right now */
615         ret = wmesh_request_unset_mesh_gate(info->bridge_interface,
616                         info->mesh_interface, info->external_interface);
617         if (WMESHD_ERROR_NONE != ret)
618                 WMESH_LOGE("Failed to wmesh_request_unset_mesh_gate [%d]", ret);
619
620         net_wmesh_complete_unset_gate(object, invocation, ret);
621
622         return TRUE;
623 }
624
625 static gboolean _wmeshd_dbus_handle_set_softap(NetWmesh *object,
626                 GDBusMethodInvocation *invocation,
627                 gchar *ssid, gchar *passphrase,
628                 gchar *mode, gint channel, gint visibility, gint max_sta,
629                 gint security, gpointer user_data)
630 {
631         int ret = WMESHD_ERROR_NONE;
632         wmesh_service *service = (wmesh_service *)user_data;
633         wmesh_interface_s *info = service->interface_info;
634
635         WMESH_LOGD("SSID      : %s", ssid);
636         WMESH_LOGD("mode      : %s", mode);
637         WMESH_LOGD("channel   : %d", channel);
638         WMESH_LOGD("visibility: %d", visibility);
639         WMESH_LOGD("max_sta   : %d", max_sta);
640         WMESH_LOGD("security  : %d", security);
641
642         /* Save softAP information */
643         ret = wmesh_request_set_softap_config(info->softap_interface,
644                 ssid, mode, channel, visibility, max_sta,
645                 security, passphrase);
646         if (WMESHD_ERROR_NONE != ret)
647                 WMESH_LOGE("Failed to wmesh_request_set_softap_config [%d]", ret);
648
649         net_wmesh_complete_set_softap(object, invocation, ret);
650
651         return TRUE;
652 }
653
654 static gboolean _wmeshd_dbus_handle_get_softap(NetWmesh *object,
655                 GDBusMethodInvocation *invocation, gpointer user_data)
656 {
657         int ret = WMESHD_ERROR_NONE;
658         wmesh_service *service = (wmesh_service *)user_data;
659         char *interface, *ssid, *mode, *passphrase;
660         int channel, visibility, max_sta, security;
661         (void) service; // unused
662
663         /* Get softAP information */
664         ret = wmesh_request_get_softap_config(&interface, &ssid, &mode, &channel,
665                                                 &visibility, &max_sta, &security, &passphrase);
666         if (WMESHD_ERROR_NONE != ret) {
667                 WMESH_LOGE("Failed to wmesh_request_get_softap_config [%d]", ret);
668                 net_wmesh_complete_get_softap(object, invocation, "", "", 0, 0, 0, 0,
669                                                                 "", ret);
670                 return FALSE;
671         }
672
673         WMESH_LOGD("SSID      : %s", ssid);
674         WMESH_LOGD("mode      : %s", mode);
675         WMESH_LOGD("channel   : %d", channel);
676         WMESH_LOGD("visibility: %d", visibility);
677         WMESH_LOGD("max_sta   : %d", max_sta);
678         WMESH_LOGD("security  : %d", security);
679         WMESH_LOGD("Passphrase  : %s", passphrase ? passphrase : "NULL");
680
681         if (security == 1)
682                 net_wmesh_complete_get_softap(object, invocation, ssid, mode, channel,
683                                                                 visibility, max_sta, security, passphrase, ret);
684         else
685                 net_wmesh_complete_get_softap(object, invocation, ssid, mode, channel,
686                                                                 visibility, max_sta, security, "", ret);
687
688         return TRUE;
689 }
690
691 static gboolean _wmeshd_dbus_handle_enable_softap(NetWmesh *object,
692                 GDBusMethodInvocation *invocation, gpointer user_data)
693 {
694         int ret = WMESHD_ERROR_NONE;
695         wmesh_service *service = (wmesh_service *)user_data;
696         wmesh_interface_s *info = service->interface_info;
697
698         /* Check softAP interface and execute it */
699         ret = wmesh_request_enable_softap(info->bridge_interface, info->softap_interface);
700         if (WMESHD_ERROR_NONE != ret)
701                 WMESH_LOGE("Failed to wmesh_request_enable_softap [%d]", ret);
702
703         net_wmesh_complete_enable_softap(object, invocation, ret);
704
705         return TRUE;
706 }
707
708 static gboolean _wmeshd_dbus_handle_disable_softap(NetWmesh *object,
709                 GDBusMethodInvocation *invocation, gpointer user_data)
710 {
711         int ret = WMESHD_ERROR_NONE;
712         wmesh_service *service = (wmesh_service *)user_data;
713         wmesh_interface_s *info = service->interface_info;
714
715         /* Destroy softAP */
716         ret = wmesh_request_disable_softap(info->bridge_interface, info->softap_interface);
717         if (WMESHD_ERROR_NONE != ret)
718                 WMESH_LOGE("Failed to wmesh_request_disable_softap [%d]", ret);
719
720         net_wmesh_complete_disable_softap(object, invocation, ret);
721
722         return TRUE;
723 }
724
725 static gboolean _wmeshd_dbus_handle_is_softap_enabled(NetWmesh *object,
726                 GDBusMethodInvocation *invocation, gpointer user_data)
727 {
728         bool status;
729         (void) user_data;
730
731         /* Check SoftAP status */
732         status = wmesh_request_check_softap_status();
733         WMESH_LOGD("SoftAP is %s", status ? "enabled" : "disabled");
734
735         net_wmesh_complete_is_softap_enabled(object, invocation, status);
736
737         return TRUE;
738 }
739
740 static gboolean _wmeshd_dbus_handle_create_mesh_network(NetWmesh *object,
741                 GDBusMethodInvocation *invocation,
742                 gchar *mesh_id, gint channel, gint security,
743                 gpointer user_data)
744 {
745         int ret = WMESHD_ERROR_NONE;
746         wmesh_service *service = (wmesh_service *)user_data;
747         wmeshd_security_type_e sec = (1 == security) ? WMESHD_SECURITY_SAE : WMESHD_SECURITY_NONE;
748
749         ret = wmesh_request_create_mesh_network(service, mesh_id, channel, sec);
750
751         net_wmesh_complete_create_mesh_network(object, invocation, ret);
752
753         return TRUE;
754 }
755
756 static gboolean _wmeshd_dbus_handle_connect_mesh_network(NetWmesh *object,
757                 GDBusMethodInvocation *invocation,
758                 gchar *mesh_id, gint channel, gint security, gchar *passphrase,
759                 gpointer user_data)
760 {
761         int ret = WMESHD_ERROR_NONE;
762         wmesh_service *service = (wmesh_service *)user_data;
763         wmeshd_security_type_e sec = (1 == security) ? WMESHD_SECURITY_SAE : WMESHD_SECURITY_NONE;
764
765         ret = wmesh_request_connect_mesh_network(service, mesh_id, channel, sec, passphrase);
766
767         net_wmesh_complete_connect_mesh_network(object, invocation, ret);
768
769         return TRUE;
770 }
771 static gboolean _wmeshd_dbus_handle_disconnect_mesh_network(NetWmesh *object,
772                 GDBusMethodInvocation *invocation,
773                 gchar *mesh_id, gint channel, gint security,
774                 gpointer user_data)
775 {
776         int ret = WMESHD_ERROR_NONE;
777         wmesh_service *service = (wmesh_service *)user_data;
778         wmeshd_security_type_e sec = (1 == security) ? WMESHD_SECURITY_SAE : WMESHD_SECURITY_NONE;
779
780         ret = wmesh_request_disconnect_mesh_network(service, mesh_id, channel, sec);
781
782         net_wmesh_complete_disconnect_mesh_network(object, invocation, ret);
783
784         return TRUE;
785 }
786
787 static gboolean _wmeshd_dbus_handle_forget_mesh_network(NetWmesh *object,
788                 GDBusMethodInvocation *invocation,
789                 gchar *mesh_id, gint channel, gint security,
790                 gpointer user_data)
791 {
792         int ret = WMESHD_ERROR_NONE;
793         wmesh_service *service = (wmesh_service *)user_data;
794         wmeshd_security_type_e sec = (1 == security) ? WMESHD_SECURITY_SAE : WMESHD_SECURITY_NONE;
795
796         ret = wmesh_request_remove_mesh_network(service, mesh_id, channel, sec);
797
798         net_wmesh_complete_forget_mesh_network(object, invocation, ret);
799
800         return TRUE;
801 }
802
803 static gboolean _wmeshd_dbus_handle_set_interfaces(NetWmesh *object,
804                 GDBusMethodInvocation *invocation,
805                 gchar *mesh, gchar *gate, gchar *softap,
806                 gpointer user_data)
807 {
808         int ret = WMESHD_ERROR_NONE;
809         wmesh_service *service = (wmesh_service *)user_data;
810         wmesh_interface_s *info = service->interface_info;
811
812         g_free(info->mesh_interface);
813         info->mesh_interface = g_strdup(mesh);
814
815         g_free(info->external_interface);
816         info->external_interface = g_strdup(gate);
817
818         g_free(info->softap_interface);
819         info->softap_interface = g_strdup(softap);
820
821         WMESH_LOGD("Interface configuration for mesh network :");
822         WMESH_LOGD("  Base    : [%s]", info->base_interface);
823         WMESH_LOGD("  Mesh    : [%s]", info->mesh_interface);
824         WMESH_LOGD("  Bridge  : [%s]", info->bridge_interface);
825         WMESH_LOGD("  SoftAP  : [%s]", info->softap_interface);
826         WMESH_LOGD("  External: [%s]", info->external_interface);
827
828         net_wmesh_complete_set_interfaces(object, invocation, ret);
829
830         return TRUE;
831 }
832
833 static gboolean _wmeshd_dbus_handle_get_station_info(NetWmesh *object,
834                 GDBusMethodInvocation *invocation, gint station_type,
835                 gpointer user_data)
836 {
837         int ret = WMESHD_ERROR_NONE;
838
839         GVariantBuilder builder;
840         GVariant* station;
841         GList *iter = NULL;
842
843         wmesh_service *service = (wmesh_service *)user_data;
844         wmesh_interface_s *info = service->interface_info;
845
846         if (station_type == WMESHD_STATION_TYPE_MESH_POINT) {
847                 /* Clear mesh station list */
848                 g_list_free_full(service->station_list, _on_station_list_destroy);
849                 service->station_list = NULL;
850
851                 ret = wmesh_request_get_station_info(
852                                                                 info->mesh_interface, &service->station_list);
853         } else if (station_type == WMESHD_STATION_TYPE_SOFTAP) {
854                 /* Clear softAP station list */
855                 g_list_free_full(service->softap_station_list,
856                                                  _on_station_list_destroy);
857                 service->softap_station_list = NULL;
858
859                 ret = wmesh_request_get_station_info(
860                                                                 info->softap_interface,
861                                                                 &service->softap_station_list);
862         } else {
863                 WMESH_LOGE("Invalid station type");
864
865                 g_dbus_method_invocation_return_error(invocation,
866                                 G_DBUS_ERROR, G_DBUS_ERROR_FAILED, "Invalid station type");
867
868                 return FALSE;
869         }
870
871         if (WMESHD_ERROR_NONE != ret) {
872                 WMESH_LOGE("Failed to wmesh_request_get_station_info");
873
874                 g_dbus_method_invocation_return_error(invocation,
875                                 G_DBUS_ERROR, G_DBUS_ERROR_FAILED, "Request Failed");
876         } else {
877         /*
878          * sh-3.2#  iw mesh0 station dump
879          * Station 7c:dd:90:62:37:cf (on mesh0)
880          * inactive time:       1685 ms
881          * rx bytes:    34174
882          * rx packets:  1181
883          * tx bytes:    6877
884          * tx packets:  76
885          * tx retries:  0
886          * tx failed:   0
887          * beacon loss: 0
888          * signal:              -64 dBm
889          * signal avg:  -63 dBm
890          * tx bitrate:  54.0 MBit/s
891          * rx bitrate:  5.5 MBit/s
892          * mesh llid:   51731
893          * mesh plid:   35432
894          * mesh plink:  ESTAB
895          * mesh local PS mode:  ACTIVE
896          * mesh peer PS mode:   ACTIVE
897          * mesh non-peer PS mode:       ACTIVE
898          * authorized:  yes
899          * authenticated:       yes
900          * associated:  yes
901          * preamble:    long
902          * WMM/WME:     yes
903          * MFP:         no
904          * TDLS peer:   no
905          * DTIM period: 0
906          * beacon interval:1000
907          * short slot time:yes
908          * connected time:      256 seconds
909          */
910                 /* Get station information and make variant data */
911                 g_variant_builder_init(&builder, G_VARIANT_TYPE("aa{sv}"));
912
913                 if (station_type == WMESHD_STATION_TYPE_MESH_POINT)
914                         iter = service->station_list;
915                 else
916                         iter = service->softap_station_list;
917
918                 while (iter != NULL) {
919                         wmesh_station_info_s *item = (wmesh_station_info_s*)iter->data;
920
921                         g_variant_builder_open(&builder, G_VARIANT_TYPE_VARDICT);
922                         g_variant_builder_add(&builder, "{sv}", "bssid",
923                                                 g_variant_new_string(item->bssid));
924                         g_variant_builder_add(&builder, "{sv}", "inactive_time",
925                                                 g_variant_new_uint32(item->inactive_time));
926                         g_variant_builder_add(&builder, "{sv}", "rx_bytes",
927                                                 g_variant_new_uint64(item->rx_bytes));
928                         g_variant_builder_add(&builder, "{sv}", "rx_packets",
929                                                 g_variant_new_uint32(item->rx_packets));
930                         g_variant_builder_add(&builder, "{sv}", "tx_bytes",
931                                                 g_variant_new_uint64(item->tx_bytes));
932                         g_variant_builder_add(&builder, "{sv}", "tx_packets",
933                                                 g_variant_new_uint32(item->tx_packets));
934                         g_variant_builder_add(&builder, "{sv}", "tx_retries",
935                                                 g_variant_new_uint32(item->tx_retries));
936                         g_variant_builder_add(&builder, "{sv}", "tx_failed",
937                                                 g_variant_new_uint32(item->tx_failed));
938                         g_variant_builder_add(&builder, "{sv}", "beacon_loss",
939                                                 g_variant_new_uint32(item->beacon_loss));
940                         g_variant_builder_add(&builder, "{sv}", "beacon_rx",
941                                                 g_variant_new_uint64(item->beacon_rx));
942                         g_variant_builder_add(&builder, "{sv}", "rx_drop_misc",
943                                                 g_variant_new_uint64(item->rx_drop_misc));
944                         g_variant_builder_add(&builder, "{sv}", "signal",
945                                                 g_variant_new_int32(item->rssi));
946                         g_variant_builder_add(&builder, "{sv}", "signal_avg",
947                                                 g_variant_new_int32(item->rssi_avg));
948                         g_variant_builder_add(&builder, "{sv}", "tx_bitrate",
949                                                 g_variant_new_uint32(item->tx_bitrate)); /* 10 times */
950                         g_variant_builder_add(&builder, "{sv}", "rx_bitrate",
951                                                 g_variant_new_uint32(item->rx_bitrate)); /* 10 times */
952                         if (station_type == WMESHD_STATION_TYPE_MESH_POINT) {
953                                 g_variant_builder_add(&builder, "{sv}", "mesh_llid",
954                                                                 g_variant_new_uint16(item->llid));
955                                 g_variant_builder_add(&builder, "{sv}", "mesh_plid",
956                                                                 g_variant_new_uint16(item->plid));
957                                 g_variant_builder_add(&builder, "{sv}", "mesh_plink",
958                                                                 g_variant_new_byte(item->mesh_plink)); /* 0 : DISCON, 1 : ESTAB */
959                                 g_variant_builder_add(&builder, "{sv}", "local_ps_mode",
960                                                                 g_variant_new_uint32(item->local_ps_mode)); /* 0 : INACTIVE, 1 : ACTIVE */
961                                 g_variant_builder_add(&builder, "{sv}", "peer_ps_mode",
962                                                                 g_variant_new_uint32(item->peer_ps_mode)); /* 0 : INACTIVE, 1 : ACTIVE */
963                                 g_variant_builder_add(&builder, "{sv}", "non_peer_ps_mode",
964                                                                 g_variant_new_uint32(item->non_peer_ps_mode)); /* 0 : INACTIVE, 1 : ACTIVE */
965                         }
966                         g_variant_builder_add(&builder, "{sv}", "authorized",
967                                                 g_variant_new_boolean(item->authorized));
968                         g_variant_builder_add(&builder, "{sv}", "authenticated",
969                                                 g_variant_new_boolean(item->authenticated));
970                         g_variant_builder_add(&builder, "{sv}", "associated",
971                                                 g_variant_new_boolean(item->associated));
972                         g_variant_builder_add(&builder, "{sv}", "preamble",
973                                                 g_variant_new_boolean(item->preamble));
974                         g_variant_builder_add(&builder, "{sv}", "WMM_WME",
975                                                 g_variant_new_boolean(item->wme));
976                         g_variant_builder_add(&builder, "{sv}", "MFP",
977                                                 g_variant_new_boolean(item->mfp));
978                         g_variant_builder_add(&builder, "{sv}", "TDLS_peer",
979                                                 g_variant_new_boolean(item->tdls_peer));
980                         g_variant_builder_add(&builder, "{sv}", "DTIM_period",
981                                                 g_variant_new_byte(item->dtim_period));
982                         g_variant_builder_add(&builder, "{sv}", "beacon_interval",
983                                                 g_variant_new_uint16(item->beacon_interval));
984                         g_variant_builder_add(&builder, "{sv}", "short_slot_time",
985                                                 g_variant_new_boolean(item->short_slot_time));
986                         g_variant_builder_add(&builder, "{sv}", "connected_time",
987                                                 g_variant_new_uint32(item->connected_time));
988                         g_variant_builder_close(&builder);
989
990                         iter = g_list_next(iter);
991                 }
992
993                 station = g_variant_builder_end(&builder);
994                 net_wmesh_complete_get_station_info(object, invocation, station, ret);
995
996                 g_object_unref(station);
997         }
998
999         return TRUE;
1000 }
1001
1002 static gboolean _wmeshd_dbus_handle_get_mpath_info(NetWmesh *object,
1003                 GDBusMethodInvocation *invocation,
1004                 gpointer user_data)
1005 {
1006         int ret = WMESHD_ERROR_NONE;
1007         GVariantBuilder builder;
1008         GVariant* mpath_data;
1009         GList *iter = NULL;
1010
1011         wmesh_service *service = (wmesh_service *)user_data;
1012         wmesh_interface_s *info = service->interface_info;
1013
1014         /* Clear mesh path list */
1015         g_list_free_full(service->mpath_list, _on_mpath_list_destroy);
1016         service->mpath_list = NULL;
1017
1018         ret = wmesh_request_get_mpath_info(
1019                                 info->mesh_interface, &service->mpath_list);
1020         if (WMESHD_ERROR_NONE != ret) {
1021                 WMESH_LOGE("Failed to wmesh_request_get_mpath_info");
1022
1023                 g_dbus_method_invocation_return_error(invocation,
1024                                 G_DBUS_ERROR, G_DBUS_ERROR_FAILED, "Request Failed");
1025         } else {
1026         /*
1027          * Example) sh-3.2# iw mesh0 mpath dump
1028          * DEST ADDR         NEXT HOP          IFACE    SN      METRIC  QLEN    EXPTIME         DTIM    DRET    FLAGS
1029          * 7c:dd:90:62:37:cf 7c:dd:90:62:37:cf mesh0    221     152             0               10                      100             0               0x5
1030          */
1031                 /* Get mesh path information and make variant data */
1032                 g_variant_builder_init(&builder, G_VARIANT_TYPE("aa{sv}"));
1033
1034                 iter = service->mpath_list;
1035                 while (iter != NULL) {
1036                         wmesh_mpath_info_s *item = (wmesh_mpath_info_s*)iter->data;
1037
1038                         g_variant_builder_open(&builder, G_VARIANT_TYPE_VARDICT);
1039                         g_variant_builder_add(&builder, "{sv}", "DEST_ADDR",
1040                                                 g_variant_new_string(item->dest_addr));
1041                         g_variant_builder_add(&builder, "{sv}", "NEXT_HOP",
1042                                                 g_variant_new_string(item->next_hop));
1043                         g_variant_builder_add(&builder, "{sv}", "IFACE",
1044                                                 g_variant_new_string(item->interface));
1045                         g_variant_builder_add(&builder, "{sv}", "SN",
1046                                                 g_variant_new_uint32(item->sn));
1047                         g_variant_builder_add(&builder, "{sv}", "METRIC",
1048                                                 g_variant_new_uint32(item->metric));
1049                         g_variant_builder_add(&builder, "{sv}", "QLEN",
1050                                                 g_variant_new_uint32(item->qlen));
1051                         g_variant_builder_add(&builder, "{sv}", "EXPTIME",
1052                                                 g_variant_new_uint32(item->exptime));
1053                         g_variant_builder_add(&builder, "{sv}", "DTIM",
1054                                                 g_variant_new_uint32(item->discovery_timeout));
1055                         g_variant_builder_add(&builder, "{sv}", "DRET",
1056                                                 g_variant_new_byte(item->discovery_retries));
1057                         g_variant_builder_add(&builder, "{sv}", "FLAGS",
1058                                                 g_variant_new_byte(item->flags));
1059                         g_variant_builder_close(&builder);
1060
1061                         iter = g_list_next(iter);
1062                 }
1063
1064                 mpath_data = g_variant_builder_end(&builder);
1065                 net_wmesh_complete_get_mpath_info(object, invocation, mpath_data, ret);
1066
1067                 g_object_unref(mpath_data);
1068         }
1069
1070         return TRUE;
1071 }
1072
1073 static gboolean _wmeshd_dbus_handle_get_meshconf_info(NetWmesh *object,
1074                 GDBusMethodInvocation *invocation,
1075                 gpointer user_data)
1076 {
1077         int ret = WMESHD_ERROR_NONE;
1078         GVariantBuilder builder;
1079         GVariant* meshconf_data;
1080         wmesh_meshconf_info_s *item;
1081
1082         wmesh_service *service = (wmesh_service *)user_data;
1083
1084         ret = wmesh_request_get_meshconf_info(service);
1085         if (WMESHD_ERROR_NONE != ret) {
1086                 WMESH_LOGE("Failed to wmesh_request_get_mpath_info");
1087
1088                 g_dbus_method_invocation_return_error(invocation,
1089                                 G_DBUS_ERROR, G_DBUS_ERROR_FAILED, "Request Failed");
1090         } else {
1091                 /* Get mesh path information and make variant data */
1092                 g_variant_builder_init(&builder, G_VARIANT_TYPE("a{sv}"));
1093
1094                 item = service->meshconf;
1095
1096                 g_variant_builder_add(&builder, "{sv}", "RETRY_TIMEOUT",
1097                                                           g_variant_new_uint16(item->retry_timeout));
1098                 g_variant_builder_add(&builder, "{sv}", "HWMP_MAX_PREQ_RETRIES",
1099                                                         g_variant_new_byte(item->hwmp_max_preq_retries));
1100                 g_variant_builder_add(&builder, "{sv}", "CONFIRM_TIMEOUT",
1101                                                           g_variant_new_uint16(item->confirm_timeout));
1102                 g_variant_builder_add(&builder, "{sv}", "PATH_REFRESH_TIME",
1103                                                           g_variant_new_uint32(item->path_refresh_time));
1104                 g_variant_builder_add(&builder, "{sv}", "HOLDING_TIMEOUT",
1105                                                           g_variant_new_uint16(item->holding_timeout));
1106                 g_variant_builder_add(&builder, "{sv}", "MIN_DISC_TIMEOUT",
1107                                                           g_variant_new_uint16(item->min_disc_timeout));
1108                 g_variant_builder_add(&builder, "{sv}", "MAX_PEER_LINKS",
1109                                                           g_variant_new_uint16(item->max_peer_links));
1110                 g_variant_builder_add(&builder, "{sv}", "HWMP_PREQ_MIN_INTERVAL",
1111                                                         g_variant_new_uint16(item->hwmp_preq_min_interval));
1112                 g_variant_builder_add(&builder, "{sv}", "TTL",
1113                                                           g_variant_new_byte(item->ttl));
1114                 g_variant_builder_add(&builder, "{sv}", "HWMP_ACTIVE_PATH_TIMEOUT",
1115                                                 g_variant_new_uint32(item->hwmp_active_path_timeout));
1116                 g_variant_builder_add(&builder, "{sv}", "ELEMENT_TTL",
1117                                                           g_variant_new_byte(item->element_ttl));
1118                 g_variant_builder_add(&builder, "{sv}", "HWMP_RANN_INTERVAL",
1119                                                           g_variant_new_uint16(item->hwmp_rann_interval));
1120                 g_variant_builder_add(&builder, "{sv}", "GATE_ANNOUNCEMENTS",
1121                                                           g_variant_new_byte(item->gate_announcements));
1122
1123
1124                 meshconf_data = g_variant_builder_end(&builder);
1125                 net_wmesh_complete_get_meshconf_info(object, invocation, meshconf_data,
1126                                                                         ret);
1127
1128                 g_object_unref(meshconf_data);
1129         }
1130
1131         g_free(service->meshconf);
1132
1133         return TRUE;
1134 }
1135
1136 static void _wmeshd_dbus_on_activator_bus_acquired(GDBusConnection *conn,
1137                 const gchar *name, gpointer user_data)
1138 {
1139         gboolean ret;
1140         GError *error = NULL;
1141         wmesh_service *service = (wmesh_service *)user_data;
1142
1143         NOTUSED(name);
1144
1145         meshd_activator_dbus_object = manager_skeleton_new();
1146         if (NULL == meshd_activator_dbus_object) {
1147                 WMESH_LOGE("manager_skeleton_new() Fail");
1148                 return;
1149         }
1150
1151         g_signal_connect(meshd_activator_dbus_object, "handle-enable",
1152                         G_CALLBACK(_wmeshd_dbus_handle_enable), service);
1153         g_signal_connect(meshd_activator_dbus_object, "handle-disable",
1154                         G_CALLBACK(_wmeshd_dbus_handle_disable), service);
1155
1156         ret = g_dbus_interface_skeleton_export(
1157                                 G_DBUS_INTERFACE_SKELETON(meshd_activator_dbus_object),
1158                                 conn, WMESH_DBUS_MANAGER_OBJPATH, &error);
1159         if (FALSE == ret) {
1160                 WMESH_LOGE("g_dbus_interface_skeleton_export() Fail(%s)", error->message);
1161                 g_error_free(error);
1162         }
1163 }
1164
1165 static void _wmeshd_dbus_on_bus_acquired(GDBusConnection *conn, const gchar *name,
1166                 gpointer user_data)
1167 {
1168         gboolean ret;
1169         GError *error = NULL;
1170         wmesh_service *service = (wmesh_service *)user_data;
1171
1172         NOTUSED(name);
1173
1174         meshd_dbus_object = net_wmesh_skeleton_new();
1175         if (NULL == meshd_dbus_object) {
1176                 WMESH_LOGE("net_wmesh_skeleton_new() Fail");
1177                 return;
1178         }
1179
1180         g_signal_connect(meshd_dbus_object, "handle-scan",
1181                         G_CALLBACK(_wmeshd_dbus_handle_scan), service);
1182         g_signal_connect(meshd_dbus_object, "handle-specific-scan",
1183                         G_CALLBACK(_wmeshd_dbus_handle_specific_scan), service);
1184         g_signal_connect(meshd_dbus_object, "handle-cancel-scan",
1185                         G_CALLBACK(_wmeshd_dbus_handle_cancel_scan), service);
1186         g_signal_connect(meshd_dbus_object, "handle-get-found-mesh-networks",
1187                         G_CALLBACK(_wmeshd_dbus_handle_get_found_mesh_networks), service);
1188         g_signal_connect(meshd_dbus_object, "handle-enable-mesh",
1189                         G_CALLBACK(_wmeshd_dbus_handle_enable_mesh), service);
1190         g_signal_connect(meshd_dbus_object, "handle-disable-mesh",
1191                         G_CALLBACK(_wmeshd_dbus_handle_disable_mesh), service);
1192         g_signal_connect(meshd_dbus_object, "handle-is-mesh-enabled",
1193                         G_CALLBACK(_wmeshd_dbus_handle_is_mesh_enabled), service);
1194         g_signal_connect(meshd_dbus_object, "handle-is-joined",
1195                         G_CALLBACK(_wmeshd_dbus_handle_is_joined), service);
1196         g_signal_connect(meshd_dbus_object, "handle-get-joined-mesh-network",
1197                         G_CALLBACK(_wmeshd_dbus_handle_get_joined_mesh_network), service);
1198         g_signal_connect(meshd_dbus_object, "handle-get-connected-peers",
1199                         G_CALLBACK(_wmeshd_dbus_handle_get_connected_peers), service);
1200         g_signal_connect(meshd_dbus_object, "handle-set-gate",
1201                         G_CALLBACK(_wmeshd_dbus_handle_set_gate), service);
1202         g_signal_connect(meshd_dbus_object, "handle-unset-gate",
1203                         G_CALLBACK(_wmeshd_dbus_handle_unset_gate), service);
1204         g_signal_connect(meshd_dbus_object, "handle-set-softap",
1205                         G_CALLBACK(_wmeshd_dbus_handle_set_softap), service);
1206         g_signal_connect(meshd_dbus_object, "handle-get-softap",
1207                         G_CALLBACK(_wmeshd_dbus_handle_get_softap), service);
1208         g_signal_connect(meshd_dbus_object, "handle-enable-softap",
1209                         G_CALLBACK(_wmeshd_dbus_handle_enable_softap), service);
1210         g_signal_connect(meshd_dbus_object, "handle-disable-softap",
1211                         G_CALLBACK(_wmeshd_dbus_handle_disable_softap), service);
1212         g_signal_connect(meshd_dbus_object, "handle-is-softap-enabled",
1213                         G_CALLBACK(_wmeshd_dbus_handle_is_softap_enabled), NULL);
1214         g_signal_connect(meshd_dbus_object, "handle-create-mesh-network",
1215                         G_CALLBACK(_wmeshd_dbus_handle_create_mesh_network), service);
1216         g_signal_connect(meshd_dbus_object, "handle-connect-mesh-network",
1217                         G_CALLBACK(_wmeshd_dbus_handle_connect_mesh_network), service);
1218         g_signal_connect(meshd_dbus_object, "handle-disconnect-mesh-network",
1219                         G_CALLBACK(_wmeshd_dbus_handle_disconnect_mesh_network), service);
1220         g_signal_connect(meshd_dbus_object, "handle-forget-mesh-network",
1221                         G_CALLBACK(_wmeshd_dbus_handle_forget_mesh_network), service);
1222         g_signal_connect(meshd_dbus_object, "handle-set-interfaces",
1223                         G_CALLBACK(_wmeshd_dbus_handle_set_interfaces), service);
1224         g_signal_connect(meshd_dbus_object, "handle-get-station-info",
1225                         G_CALLBACK(_wmeshd_dbus_handle_get_station_info), service);
1226         g_signal_connect(meshd_dbus_object, "handle-get-mpath-info",
1227                         G_CALLBACK(_wmeshd_dbus_handle_get_mpath_info), service);
1228         g_signal_connect(meshd_dbus_object, "handle-get-meshconf-info",
1229                         G_CALLBACK(_wmeshd_dbus_handle_get_meshconf_info), service);
1230
1231         ret = g_dbus_interface_skeleton_export(G_DBUS_INTERFACE_SKELETON(meshd_dbus_object),
1232                         conn, WMESH_DBUS_OBJPATH, &error);
1233         if (FALSE == ret) {
1234                 WMESH_LOGE("g_dbus_interface_skeleton_export() Fail(%s)", error->message);
1235                 g_error_free(error);
1236         }
1237
1238         ret = _wmeshd_dbus_subscribe_name_owner_changed(conn);
1239         if (WMESHD_ERROR_NONE != ret) {
1240                 WMESH_LOGE("_wmeshd_dbus_subscribe_name_owner_changed() Fail(%d)", ret);
1241                 return;
1242         }
1243 }
1244
1245 static void _wmeshd_dbus_on_name_lost(GDBusConnection *conn, const gchar *name,
1246                 gpointer user_data)
1247 {
1248         NOTUSED(conn);
1249         NOTUSED(user_data);
1250
1251         WMESH_LOGD("Lost the name %s", name);
1252 }
1253
1254 static void _wmeshd_dbus_on_name_acquired(GDBusConnection *conn, const gchar *name,
1255                 gpointer user_data)
1256 {
1257         NOTUSED(conn);
1258         NOTUSED(user_data);
1259
1260         WMESH_LOGD("Acquired the name %s", name);
1261 }
1262
1263 static gboolean _wmeshd_dbus_interface_init(wmesh_service *service)
1264 {
1265         guint id;
1266         guint activation_dbus_id;
1267         wmeshd_check_null_ret_error("service", service, FALSE);
1268
1269         id = g_bus_own_name(G_BUS_TYPE_SYSTEM,
1270                         WMESH_DBUS_INTERFACE,
1271                         G_BUS_NAME_OWNER_FLAGS_REPLACE,
1272                         _wmeshd_dbus_on_bus_acquired,
1273                         _wmeshd_dbus_on_name_acquired,
1274                         _wmeshd_dbus_on_name_lost,
1275                         service,
1276                         NULL);
1277         if (0 == id) {
1278                 WMESH_LOGE("g_bus_own_name() Fail");
1279                 return FALSE;
1280         }
1281
1282         /* Get D-Bus owner to activate mesh service daemon */
1283         activation_dbus_id = g_bus_own_name(G_BUS_TYPE_SYSTEM,
1284                         WMESH_DBUS_INTERFACE".manager",
1285                         G_BUS_NAME_OWNER_FLAGS_REPLACE,
1286                         _wmeshd_dbus_on_activator_bus_acquired,
1287                         NULL,
1288                         NULL,
1289                         service,
1290                         NULL);
1291
1292         service->dbus_id = id;
1293         service->activation_dbus_id = activation_dbus_id;
1294         service->interface_info = g_new0(wmesh_interface_s, 1);
1295         service->scanned_mesh_network = NULL;
1296
1297         /* Initialize DBus sendor logic */
1298         wmeshd_dbus_start(service);
1299
1300         return TRUE;
1301 }
1302
1303 static void _wmeshd_dbus_deinit(wmesh_service *service)
1304 {
1305         wmesh_interface_s *info = NULL;
1306         wmeshd_check_null_ret("service", service);
1307
1308         /* De-Initialize DBus sendor logic */
1309         wmeshd_dbus_stop(service);
1310
1311         g_bus_unown_name(service->dbus_id);
1312         g_bus_unown_name(service->activation_dbus_id);
1313
1314         info = service->interface_info;
1315         wmeshd_check_null_ret("info", info);
1316         if (info->bridge_interface)
1317                 g_free(info->bridge_interface);
1318         if (info->base_interface)
1319                 g_free(info->base_interface);
1320         if (info->mesh_interface)
1321                 g_free(info->mesh_interface);
1322         if (info->softap_interface)
1323                 g_free(info->softap_interface);
1324         if (info->external_interface)
1325                 g_free(info->external_interface);
1326
1327         if (service->joined_network) {
1328                 g_free(service->joined_network->mesh_id);
1329                 g_free(service->joined_network->bssid);
1330                 g_free(service->joined_network);
1331                 service->joined_network = NULL;
1332         }
1333
1334         /* Clear scan list */
1335         if (service->scanned_mesh_network)
1336                 g_list_free_full(service->scanned_mesh_network, _on_scan_result_destroy);
1337         service->scanned_mesh_network = NULL;
1338
1339         /* Clear connected peers list */
1340         if (service->connected_mesh_peers)
1341                 g_list_free_full(service->connected_mesh_peers, _on_peer_info_destroy);
1342         service->connected_mesh_peers = NULL;
1343
1344         /* Clear mesh path list */
1345         if (service->mpath_list)
1346                 g_list_free_full(service->mpath_list, _on_mpath_list_destroy);
1347         service->mpath_list = NULL;
1348
1349         /* Clear mesh station list */
1350         if (service->station_list)
1351                 g_list_free_full(service->station_list, _on_station_list_destroy);
1352         service->station_list = NULL;
1353
1354         /* Clear mesh station list */
1355         if (service->softap_station_list)
1356                 g_list_free_full(service->softap_station_list,
1357                                                  _on_station_list_destroy);
1358         service->softap_station_list = NULL;
1359
1360         g_free(service->interface_info);
1361         service->interface_info = NULL;
1362 }
1363
1364 /**< Mesh service interface initialization */
1365 gboolean wmeshd_service_interface_init(wmesh_service *service)
1366 {
1367         guint ret;
1368         wmeshd_check_null_ret_error("service", service, FALSE);
1369
1370         /* Initialize dbus interface */
1371         ret = _wmeshd_dbus_interface_init(service);
1372         if (FALSE == ret) {
1373                 WMESH_LOGE("_wmeshd_dbus_interface_init failed!!!");
1374                 return FALSE;
1375         }
1376
1377         return TRUE;
1378 }
1379
1380 /**< Mesh service interface de-initialization */
1381 void wmeshd_service_interface_deinit(wmesh_service *service)
1382 {
1383         wmeshd_check_null_ret("service", service);
1384
1385         /* De-initialize dbus interface */
1386         _wmeshd_dbus_deinit(service);
1387 }