Add DHCP terminate logic
[platform/core/connectivity/wifi-mesh-manager.git] / src / mesh-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
25 #include "mesh.h"
26 #include "mesh-log.h"
27 #include "mesh-util.h"
28 #include "mesh-service.h"
29 #include "mesh-service-interface.h"
30 #include "mesh-generated-code.h"
31
32 #include "mesh-request.h"
33 #include "mesh-interface.h"
34
35 static NetMesh *meshd_dbus_object;
36 static Manager *meshd_activator_dbus_object;
37
38 /* global list to care resource handle for each client */
39 static GList *meshd_dbus_client_list;
40 static GMutex meshd_dbus_client_list_mutex;
41
42 typedef struct _meshd_dbus_client_s {
43         gchar *bus_name;
44 } meshd_dbus_client_s;
45
46 NetMesh* meshd_dbus_get_object()
47 {
48         return meshd_dbus_object;
49 }
50
51 int64_t meshd_dbus_generate_signal_number()
52 {
53         static int64_t i = 0;
54
55         return i++;
56 }
57
58 static int _meshd_dbus_client_list_cleanup(GList *client_list)
59 {
60         meshd_dbus_client_s *client;
61
62         meshd_check_null_ret_error("client_list", client_list, FALSE);
63
64         client = client_list->data;
65
66         free(client->bus_name);
67         client->bus_name = NULL;
68         free(client);
69         g_list_free(client_list);
70
71         return MESHD_ERROR_NONE;
72 }
73
74 static int _meshd_dbus_client_list_compare_bus_name(const void *a, const void *b)
75 {
76         const meshd_dbus_client_s *client = a;
77
78         return g_strcmp0(client->bus_name, b);
79 }
80
81 static inline GList* _meshd_dbus_client_list_find_client(const gchar *owner)
82 {
83         return g_list_find_custom(meshd_dbus_client_list, owner,
84                         _meshd_dbus_client_list_compare_bus_name);
85 }
86
87 static void _meshd_dbus_name_owner_changed_cb(GDBusConnection *conn,
88                 const gchar *sender_name,
89                 const gchar *object_path,
90                 const gchar *interface_name,
91                 const gchar *signal_name,
92                 GVariant *parameters,
93                 gpointer user_data)
94 {
95         int ret;
96         GList *client = NULL;
97         gchar *name, *old_owner, *new_owner;
98
99         NOTUSED(conn);
100         NOTUSED(sender_name);
101         NOTUSED(object_path);
102         NOTUSED(interface_name);
103         NOTUSED(signal_name);
104         NOTUSED(user_data);
105
106         g_variant_get(parameters, "(&s&s&s)", &name, &old_owner, &new_owner);
107
108         if (0 == strlen(new_owner)) {
109                 g_mutex_lock(&meshd_dbus_client_list_mutex);
110                 client = _meshd_dbus_client_list_find_client(old_owner);
111                 if (client) { /* found bus name in our bus list */
112                         MESH_LOGD("bus(%s) stopped", old_owner);
113                         meshd_dbus_client_list = g_list_remove_link(meshd_dbus_client_list, client);
114                 }
115                 g_mutex_unlock(&meshd_dbus_client_list_mutex);
116
117                 if (client) {
118                         ret = _meshd_dbus_client_list_cleanup(client);
119                         if (MESHD_ERROR_NONE != ret)
120                                 MESH_LOGE("_meshd_dbus_client_list_cleanup() Fail(%d)", ret);
121                 }
122         }
123 }
124
125 static int _meshd_dbus_subscribe_name_owner_changed(GDBusConnection *conn)
126 {
127         unsigned int id;
128
129         id = g_dbus_connection_signal_subscribe(conn,
130                         "org.freedesktop.DBus", /* bus name */
131                         "org.freedesktop.DBus", /* interface */
132                         "NameOwnerChanged", /* member */
133                         "/org/freedesktop/DBus", /* path */
134                         NULL, /* arg0 */
135                         G_DBUS_SIGNAL_FLAGS_NONE,
136                         _meshd_dbus_name_owner_changed_cb,
137                         NULL,
138                         NULL);
139         if (0 == id) {
140                 MESH_LOGE("g_dbus_connection_signal_subscribe() Fail");
141                 return MESHD_ERROR_IO_ERROR;
142         }
143
144         return MESHD_ERROR_NONE;
145 }
146
147 static gboolean _meshd_dbus_handle_enable(Manager *object,
148                 GDBusMethodInvocation *invocation,
149                 gpointer user_data)
150 {
151         int ret = MESHD_ERROR_NONE;
152         mesh_service *service = (mesh_service *)user_data;
153         mesh_interface_s *info = service->interface_info;
154
155         if (service->mesh_activated) {
156                 /* Already activated */
157                 manager_complete_enable(object, invocation,
158                                 MESHD_ERROR_OPERATION_FAILED);
159         } else {
160                 /* Do API response first */
161                 manager_complete_enable(object, invocation, ret);
162                 service->mesh_activated = TRUE;
163         }
164
165         meshd_check_null_ret_error("info", info, FALSE);
166
167         /* Register event handler first */
168         ret = mesh_request_register_event_handler();
169         if (MESHD_ERROR_NONE != ret) {
170                 MESH_LOGE("Failed to register mesh event handler !! [%d]", ret);
171         }
172
173         ret = mesh_interface_initialize(service->interface_info);
174         if (MESHD_ERROR_NONE != ret) {
175                 MESH_LOGE("Failed to mesh_interface_initialize [%d]", ret);
176                 goto FINISH;
177         }
178
179 FINISH:
180         net_mesh_emit_mesh_enabled(meshd_dbus_get_object(), ret);
181
182         return TRUE;
183 }
184
185 static gboolean _meshd_dbus_handle_disable(Manager *object,
186                 GDBusMethodInvocation *invocation,
187                 gpointer user_data)
188 {
189         int ret = MESHD_ERROR_NONE;
190         mesh_service *service = (mesh_service *)user_data;
191         mesh_interface_s *info = service->interface_info;
192
193         meshd_check_null_ret_error("info", info, FALSE);
194
195         /* Make response first */
196         manager_complete_disable(object, invocation, ret);
197
198         ret = mesh_request_unregister_event_handler();
199         if (MESHD_ERROR_NONE != ret) {
200                 MESH_LOGE("Failed to unregister mesh event handler !! [%d]", ret);
201         }
202
203         /* Terminate daemon */
204         meshd_service_exit(service);
205
206         return TRUE;
207 }
208
209 static gboolean _meshd_dbus_handle_scan(NetMesh *object,
210                 GDBusMethodInvocation *invocation,
211                 gpointer user_data)
212 {
213         int ret = MESHD_ERROR_NONE;
214         mesh_service *service = (mesh_service *)user_data;
215         mesh_interface_s *info = service->interface_info;
216
217         meshd_check_null_ret_error("info", info, FALSE);
218
219         ret = mesh_request_scan(info->mesh_interface);
220         if (MESHD_ERROR_NONE != ret) {
221                 MESH_LOGE("Failed to mesh_request_scan on mesh interface[%s] !",
222                                 info->mesh_interface);
223         }
224
225         /* Fall-back */
226         if (MESHD_ERROR_IN_PROGRESS != ret) {
227                 ret = mesh_request_scan(info->base_interface);
228                 if (MESHD_ERROR_NONE != ret)
229                         MESH_LOGE("Failed to mesh_request_scan on base interface[%s] !",
230                                         info->base_interface);
231         }
232
233         net_mesh_complete_scan(object, invocation, ret);
234
235         return TRUE;
236 }
237
238 static gboolean _meshd_dbus_handle_specific_scan(NetMesh *object,
239                 GDBusMethodInvocation *invocation,
240                 gchar *mesh_id,
241                 gint channel,
242                 gpointer user_data)
243 {
244         int ret = MESHD_ERROR_NONE;
245         mesh_service *service = (mesh_service *)user_data;
246         mesh_interface_s *info = service->interface_info;
247
248         meshd_check_null_ret_error("info", info, FALSE);
249
250         ret = mesh_request_specific_scan(info->mesh_interface, mesh_id, channel);
251         if (MESHD_ERROR_NONE != ret) {
252                 MESH_LOGE("Failed to mesh_request_specific_scan on mesh interface[%s]",
253                                 info->mesh_interface);
254         }
255
256         /* Fall-back */
257         if (MESHD_ERROR_IN_PROGRESS != ret) {
258                 ret = mesh_request_specific_scan(info->base_interface, mesh_id, channel);
259                 if (MESHD_ERROR_NONE != ret)
260                         MESH_LOGE("Failed to mesh_request_specific_scan on base interface[%s]",
261                                         info->base_interface);
262         }
263
264         net_mesh_complete_specific_scan(object, invocation, ret);
265
266         return TRUE;
267 }
268
269 static gboolean _meshd_dbus_handle_cancel_scan(NetMesh *object,
270                 GDBusMethodInvocation *invocation,
271                 gpointer user_data)
272 {
273         int ret = MESHD_ERROR_NONE;
274         mesh_service *service = (mesh_service *)user_data;
275         mesh_interface_s *info = service->interface_info;
276
277         ret = mesh_request_cancel_scan(info->mesh_interface);
278         if (MESHD_ERROR_NONE != ret) {
279                 MESH_LOGE("Failed to mesh_request_cancel_scan");
280         }
281
282         net_mesh_complete_cancel_scan(object, invocation, ret);
283
284         return TRUE;
285 }
286
287 static void _on_scan_result_destroy(gpointer data)
288 {
289         mesh_scan_result_s *scan_item = (mesh_scan_result_s *)data;
290
291         if (scan_item) {
292                 g_free(scan_item->mesh_id);
293                 g_free(scan_item->bssid);
294         }
295 }
296
297 static void _on_station_list_destroy(gpointer data)
298 {
299         mesh_station_info_s *info = (mesh_station_info_s*)data;
300
301         if (info) {
302                 g_free(info->bssid);
303                 g_free(info);
304         }
305 }
306
307 static void _on_mpath_list_destroy(gpointer data)
308 {
309         mesh_mpath_info_s *info = (mesh_mpath_info_s*)data;
310
311         if (info) {
312                 g_free(info->dest_addr);
313                 g_free(info->next_hop);
314                 g_free(info->interface);
315                 g_free(info);
316         }
317 }
318
319 static gboolean _meshd_dbus_handle_get_found_mesh_networks(NetMesh *object,
320                 GDBusMethodInvocation *invocation,
321                 gpointer user_data)
322 {
323         int ret = MESHD_ERROR_NONE;
324         mesh_service *service = (mesh_service *)user_data;
325         mesh_interface_s *info = service->interface_info;
326
327         GVariantBuilder builder;
328         GVariant* networks;
329         GList *iter = NULL;
330         mesh_scan_result_s *scan_item = NULL;
331
332         MESH_LOGD("Request to get scanned mesh network list");
333
334         ret = mesh_request_get_scan_result(info->mesh_interface, &service->scanned_mesh_network);
335         if (MESHD_ERROR_NONE != ret) {
336                 MESH_LOGE("Failed to mesh_request_get_scan_result");
337
338                 /* Fall-back */
339                 ret = mesh_request_get_scan_result(info->base_interface,
340                                 &service->scanned_mesh_network);
341                 if (MESHD_ERROR_NONE != ret) {
342                         MESH_LOGE("Failed to mesh_request_get_scan_result on base interface[%s]",
343                                         info->base_interface);
344
345                         g_dbus_method_invocation_return_error(invocation,
346                                         G_DBUS_ERROR, G_DBUS_ERROR_FAILED, "Request Failed");
347                 }
348         }
349
350         g_variant_builder_init(&builder, G_VARIANT_TYPE("aa{sv}"));
351
352         iter = service->scanned_mesh_network;
353         while (iter != NULL) {
354                 scan_item = (mesh_scan_result_s*)iter->data;
355
356                 g_variant_builder_open(&builder, G_VARIANT_TYPE_VARDICT);
357                 g_variant_builder_add(&builder, "{sv}", "mesh_id",
358                                 g_variant_new_string(scan_item->mesh_id));
359                 g_variant_builder_add(&builder, "{sv}", "bssid",
360                                 g_variant_new_string(scan_item->bssid));
361                 g_variant_builder_add(&builder, "{sv}", "rssi",
362                                 g_variant_new_int32(scan_item->rssi));
363                 g_variant_builder_add(&builder, "{sv}", "channel",
364                                 g_variant_new_uint32(scan_item->channel));
365                 g_variant_builder_close(&builder);
366
367                 iter = g_list_next(iter);
368         }
369
370         /* Clear scan list */
371         g_list_free_full(service->scanned_mesh_network, _on_scan_result_destroy);
372         service->scanned_mesh_network = NULL;
373
374         networks = g_variant_builder_end(&builder);
375         net_mesh_complete_get_found_mesh_networks(object, invocation, networks, ret);
376
377         return TRUE;
378 }
379
380 static gboolean _meshd_dbus_handle_enable_mesh(NetMesh *object,
381                 GDBusMethodInvocation *invocation,
382                 gpointer user_data)
383 {
384         int ret = MESHD_ERROR_NONE;
385         mesh_service *service = (mesh_service *)user_data;
386         mesh_interface_s *info = service->interface_info;
387
388         /* Create or join mesh network and create bridge */
389         ret = mesh_request_enable_mesh(info->base_interface, info->mesh_interface);
390         if (MESHD_ERROR_NONE != ret) {
391                 MESH_LOGE("Failed to mesh_request_enable_mesh [%d]", ret);
392                 goto FINISH;
393         }
394
395         ret = mesh_request_create_bridge(info->bridge_interface, info->mesh_interface);
396         if (MESHD_ERROR_NONE != ret) {
397                 MESH_LOGE("Failed to mesh_request_create_bridge [%d]", ret);
398                 goto FINISH;
399         }
400
401
402         ret = mesh_request_join_mesh(info->mesh_interface,
403                         service->saved_mesh_network, &service->joined_network);
404         if (MESHD_ERROR_NONE != ret) {
405                 MESH_LOGE("Failed to mesh_request_join_mesh [%d]", ret);
406                 MESH_LOGE("Remove created bridge...");
407                 ret = mesh_request_remove_bridge(info->bridge_interface);
408                 if (MESHD_ERROR_NONE != ret) {
409                         MESH_LOGE("Failed to mesh_request_remove_bridge");
410                 }
411                 goto FINISH;
412         }
413
414         /* Detect external network state (i.e. Ethernet)
415                         and decide to make gate enabled */
416         ret = mesh_request_set_mesh_gate(info->bridge_interface,
417                         info->mesh_interface, info->external_interface);
418         if (MESHD_ERROR_NONE != ret) {
419                 MESH_LOGE("Failed to mesh_request_set_mesh_gate [%d]", ret);
420         }
421
422 #if 0
423         /* TODO: Check if specific scan is required */
424         ret = mesh_request_specific_scan(info->mesh_interface,
425                         info->mesh_id, info->mesh_channel);
426         if (MESHD_ERROR_NONE != ret) {
427                 MESH_LOGE("Failed to mesh_request_specific_scan [%d]", ret);
428         }
429         ret = mesh_request_get_scan_result(info->mesh_interface,
430                         &service->scanned_mesh_network);
431 #endif
432
433         /* Request DHCP on bridge interface */
434         ret = mesh_request_dhcp(info->bridge_interface);
435         if (MESHD_ERROR_NONE != ret) {
436                 MESH_LOGE("Failed to mesh_request_dhcp [%d]", ret);
437         }
438
439         /* TODO: Notify bridge status to Connman */
440
441 FINISH:
442         net_mesh_complete_enable_mesh(object, invocation, ret);
443
444         return TRUE;
445 }
446
447 static gboolean _meshd_dbus_handle_disable_mesh(NetMesh *object,
448                 GDBusMethodInvocation *invocation,
449                 gpointer user_data)
450 {
451         int ret = MESHD_ERROR_NONE;
452         mesh_service *service = (mesh_service *)user_data;
453         mesh_interface_s *info = service->interface_info;
454
455         meshd_check_null_ret_error("info", info, FALSE);
456
457         /* Destroy bridge and return from mesh to infra mode */
458         if (service->joined_network) {
459                 g_free(service->joined_network->mesh_id);
460                 g_free(service->joined_network);
461                 service->joined_network = NULL;
462         }
463
464         if (FALSE == service->mesh_activated) {
465                 MESH_LOGD("Mesh network is not activated yet");
466                 ret = MESHD_ERROR_OPERATION_FAILED;
467                 net_mesh_complete_disable_mesh(object, invocation, ret);
468                 return TRUE;
469         }
470
471         /* If DHCP is on progress, stop it */
472         ret = mesh_request_stop_dhcp();
473         if (MESHD_ERROR_NONE != ret) {
474                 MESH_LOGE("Failed to stop DHCP request !");
475         }
476
477         ret = mesh_request_disable_mesh(info->mesh_interface);
478         if (MESHD_ERROR_NONE != ret) {
479                 MESH_LOGE("Failed to mesh_request_disable_mesh_gate");
480         }
481
482         ret = mesh_request_remove_bridge(info->bridge_interface);
483         if (MESHD_ERROR_NONE != ret) {
484                 MESH_LOGE("Failed to mesh_request_remove_bridge");
485         }
486
487         /* Make response */
488         net_mesh_complete_disable_mesh(object, invocation, ret);
489
490         /* Make notification */
491         mesh_notify_left_network();
492
493         return TRUE;
494 }
495
496 static gboolean _meshd_dbus_handle_get_joined_mesh_network(NetMesh *object,
497                 GDBusMethodInvocation *invocation,
498                 gpointer user_data)
499 {
500         int ret = MESHD_ERROR_NONE;
501         mesh_service *service = (mesh_service *)user_data;
502         mesh_network_info_s *joined = service->joined_network;
503
504         //gchar *meshid = strdup("meshnet");
505         //gchar *bssid = strdup("7c:dd:90:d8:2a:64");
506         //gint channel = 161;
507         //gint max_speed = 866;
508
509         if (joined) {
510                 net_mesh_complete_get_joined_mesh_network(object, invocation,
511                         joined->mesh_id, joined->bssid, joined->channel, ret);
512         } else {
513                 net_mesh_complete_get_joined_mesh_network(object, invocation,
514                         "", "", 0, MESHD_ERROR_NO_DATA);
515         }
516
517         return TRUE;
518 }
519
520 static gboolean _meshd_dbus_handle_set_gate(NetMesh *object,
521                 GDBusMethodInvocation *invocation, gboolean stp, gboolean gate_announce,
522                 gpointer user_data)
523 {
524         int ret = MESHD_ERROR_NONE;
525         mesh_service *service = (mesh_service *)user_data;
526         mesh_interface_s *info = service->interface_info;
527
528         MESH_LOGD("STP = %d", stp);
529         MESH_LOGD("gate_announce = %d", gate_announce);
530
531         /* Set STP and gate_announce */
532         ret = mesh_request_set_mesh_gate(info->bridge_interface,
533                         info->mesh_interface, info->external_interface);
534         if (MESHD_ERROR_NONE != ret) {
535                 MESH_LOGE("Failed to mesh_request_set_mesh_gate [%d]", ret);
536         }
537
538         net_mesh_complete_set_gate(object, invocation, ret);
539
540         return TRUE;
541 }
542
543 static gboolean _meshd_dbus_handle_unset_gate(NetMesh *object,
544                 GDBusMethodInvocation *invocation,
545                 gpointer user_data)
546 {
547         int ret = MESHD_ERROR_NONE;
548         mesh_service *service = (mesh_service *)user_data;
549         mesh_interface_s *info = service->interface_info;
550
551         ret = mesh_request_unset_mesh_gate(info->bridge_interface,
552                         info->mesh_interface, info->external_interface);
553         if (MESHD_ERROR_NONE != ret) {
554                 MESH_LOGE("Failed to mesh_request_unset_mesh_gate [%d]", ret);
555         }
556         net_mesh_complete_unset_gate(object, invocation, ret);
557
558         return TRUE;
559 }
560
561 static gboolean _meshd_dbus_handle_set_softap(NetMesh *object,
562                 GDBusMethodInvocation *invocation,
563                 gchar *ssid, gchar *passphrase,
564                 gchar *mode, gint channel, gint visibility, gint max_sta,
565                 gint security, gpointer user_data)
566 {
567         int ret = MESHD_ERROR_NONE;
568         mesh_service *service = (mesh_service *)user_data;
569         mesh_interface_s *info = service->interface_info;
570
571         MESH_LOGD("SSID      : %s", ssid);
572         MESH_LOGD("mode      : %s", mode);
573         MESH_LOGD("channel   : %d", channel);
574         MESH_LOGD("visibility: %d", visibility);
575         MESH_LOGD("max_sta   : %d", max_sta);
576         MESH_LOGD("security  : %d", security);
577
578         /* Save softAP information */
579         ret = mesh_request_set_softap_config(info->softap_interface,
580                 ssid, mode, channel, visibility, max_sta,
581                 security, passphrase);
582         if (MESHD_ERROR_NONE != ret) {
583                 MESH_LOGE("Failed to mesh_request_set_softap_config [%d]", ret);
584         }
585
586         net_mesh_complete_set_softap(object, invocation, ret);
587
588         return TRUE;
589 }
590
591 static gboolean _meshd_dbus_handle_enable_softap(NetMesh *object,
592                 GDBusMethodInvocation *invocation, gpointer user_data)
593 {
594         int ret = MESHD_ERROR_NONE;
595         mesh_service *service = (mesh_service *)user_data;
596         mesh_interface_s *info = service->interface_info;
597
598         /* Check softAP interface and execute it */
599         ret = mesh_request_enable_softap(info->bridge_interface, info->softap_interface);
600         if (MESHD_ERROR_NONE != ret) {
601                 MESH_LOGE("Failed to mesh_request_enable_softap [%d]", ret);
602         }
603
604         net_mesh_complete_enable_softap(object, invocation, ret);
605
606         return TRUE;
607 }
608
609 static gboolean _meshd_dbus_handle_disable_softap(NetMesh *object,
610                 GDBusMethodInvocation *invocation, gpointer user_data)
611 {
612         int ret = MESHD_ERROR_NONE;
613         mesh_service *service = (mesh_service *)user_data;
614         mesh_interface_s *info = service->interface_info;
615
616         /* Destroy softAP */
617         ret = mesh_request_disable_softap(info->bridge_interface, info->softap_interface);
618         if (MESHD_ERROR_NONE != ret) {
619                 MESH_LOGE("Failed to mesh_request_disable_softap [%d]", ret);
620         }
621
622         net_mesh_complete_disable_softap(object, invocation, ret);
623
624         return TRUE;
625 }
626
627 static gboolean _meshd_dbus_handle_add_mesh_network(NetMesh *object,
628                 GDBusMethodInvocation *invocation,
629                 gchar *mesh_id, gint channel, gint security,
630                 gpointer user_data)
631 {
632         int ret = MESHD_ERROR_NONE;
633         mesh_service *service = (mesh_service *)user_data;
634
635         ret = mesh_request_add_mesh_network(&service->saved_mesh_network,
636                         mesh_id, channel, security);
637
638         net_mesh_complete_add_mesh_network(object, invocation, ret);
639
640         return TRUE;
641 }
642
643 static gboolean _meshd_dbus_handle_get_saved_mesh_network(NetMesh *object,
644                 GDBusMethodInvocation *invocation,
645                 gpointer user_data)
646 {
647         int ret = MESHD_ERROR_NONE;
648         mesh_service *service = (mesh_service *)user_data;
649
650         GVariantBuilder builder;
651         GVariant* networks;
652         GList *iter = NULL;
653
654         ret = mesh_request_get_saved_mesh_network(&service->saved_mesh_network);
655         if (MESHD_ERROR_NONE != ret) {
656                 MESH_LOGE("Failed to mesh_request_get_saved_mesh_network");
657
658                 g_dbus_method_invocation_return_error(invocation,
659                                 G_DBUS_ERROR, G_DBUS_ERROR_FAILED, "Request Failed");
660         } else {
661                 /* TODO: Get station information and make variant data */
662                 g_variant_builder_init(&builder, G_VARIANT_TYPE("aa{sv}"));
663
664                 iter = service->saved_mesh_network;
665                 while (iter != NULL) {
666                         mesh_network_info_s *item = (mesh_network_info_s*)iter->data;
667
668                         g_variant_builder_open(&builder, G_VARIANT_TYPE_VARDICT);
669                         g_variant_builder_add(&builder, "{sv}", "mesh_id",
670                                         g_variant_new_string(item->mesh_id));
671                         g_variant_builder_add(&builder, "{sv}", "channel",
672                                         g_variant_new_uint32(item->channel));
673                         g_variant_builder_add(&builder, "{sv}", "security",
674                                         g_variant_new_uint32(item->security));
675                         g_variant_builder_close(&builder);
676
677                         iter = g_list_next(iter);
678                 }
679
680                 networks = g_variant_builder_end(&builder);
681                 net_mesh_complete_get_saved_mesh_network(object, invocation, networks, ret);
682         }
683
684         return TRUE;
685 }
686
687 static gboolean _meshd_dbus_handle_select_saved_mesh_network(NetMesh *object,
688                 GDBusMethodInvocation *invocation,
689                 gchar *mesh_id, gint channel, gint security,
690                 gpointer user_data)
691 {
692         int ret = MESHD_ERROR_NONE;
693         mesh_service *service = (mesh_service *)user_data;
694
695         ret = mesh_request_select_saved_mesh_network(&service->saved_mesh_network,
696                         mesh_id, channel, security);
697
698         net_mesh_complete_select_saved_mesh_network(object, invocation, ret);
699
700         return TRUE;
701 }
702
703 static gboolean _meshd_dbus_handle_forget_saved_mesh_network(NetMesh *object,
704                 GDBusMethodInvocation *invocation,
705                 gchar *mesh_id, gint channel, gint security,
706                 gpointer user_data)
707 {
708         int ret = MESHD_ERROR_NONE;
709         mesh_service *service = (mesh_service *)user_data;
710
711         ret = mesh_request_forget_saved_mesh_network(&service->saved_mesh_network,
712                         mesh_id, channel, security);
713
714         net_mesh_complete_forget_saved_mesh_network(object, invocation, ret);
715
716         return TRUE;
717 }
718
719 static gboolean _meshd_dbus_handle_set_interfaces(NetMesh *object,
720                 GDBusMethodInvocation *invocation,
721                 gchar *mesh, gchar *gate, gchar *softap,
722                 gpointer user_data)
723 {
724         int ret = MESHD_ERROR_NONE;
725         mesh_service *service = (mesh_service *)user_data;
726         mesh_interface_s *info = service->interface_info;
727
728         g_free(info->mesh_interface);
729         info->mesh_interface = g_strdup(mesh);
730
731         g_free(info->external_interface);
732         info->external_interface = g_strdup(gate);
733
734         g_free(info->softap_interface);
735         info->softap_interface = g_strdup(softap);
736
737         net_mesh_complete_set_interfaces(object, invocation, ret);
738
739         return TRUE;
740 }
741
742 static gboolean _meshd_dbus_handle_get_station_info(NetMesh *object,
743                 GDBusMethodInvocation *invocation,
744                 gpointer user_data)
745 {
746         int ret = MESHD_ERROR_NONE;
747
748         GVariantBuilder builder;
749         GVariant* station;
750         GList *iter = NULL;
751
752         mesh_service *service = (mesh_service *)user_data;
753         mesh_interface_s *info = service->interface_info;
754
755         /* Clear mesh station list */
756         g_list_free_full(service->station_list, _on_station_list_destroy);
757         service->station_list = NULL;
758
759         ret = mesh_request_get_station_info(
760                                 info->mesh_interface, &service->station_list);
761         if (MESHD_ERROR_NONE != ret) {
762                 MESH_LOGE("Failed to mesh_request_get_station_info");
763
764                 g_dbus_method_invocation_return_error(invocation,
765                                 G_DBUS_ERROR, G_DBUS_ERROR_FAILED, "Request Failed");
766         } else {
767         /*
768          * sh-3.2#  iw mesh0 station dump
769          * Station 7c:dd:90:62:37:cf (on mesh0)
770          * inactive time:       1685 ms
771          * rx bytes:    34174
772          * rx packets:  1181
773          * tx bytes:    6877
774          * tx packets:  76
775          * tx retries:  0
776          * tx failed:   0
777          * beacon loss: 0
778          * signal:      -64 dBm
779          * signal avg:  -63 dBm
780          * tx bitrate:  54.0 MBit/s
781          * rx bitrate:  5.5 MBit/s
782          * mesh llid:   51731
783          * mesh plid:   35432
784          * mesh plink:  ESTAB
785          * mesh local PS mode:  ACTIVE
786          * mesh peer PS mode:   ACTIVE
787          * mesh non-peer PS mode:       ACTIVE
788          * authorized:  yes
789          * authenticated:       yes
790          * associated:  yes
791          * preamble:    long
792          * WMM/WME:     yes
793          * MFP:         no
794          * TDLS peer:   no
795          * DTIM period: 0
796          * beacon interval:1000
797          * short slot time:yes
798          * connected time:      256 seconds
799          */
800                 /* Get station information and make variant data */
801                 g_variant_builder_init(&builder, G_VARIANT_TYPE("aa{sv}"));
802
803                 iter = service->station_list;
804                 while (iter != NULL) {
805                         mesh_station_info_s *item = (mesh_station_info_s*)iter->data;
806
807                         g_variant_builder_open(&builder, G_VARIANT_TYPE_VARDICT);
808                         g_variant_builder_add(&builder, "{sv}", "bssid",
809                                                 g_variant_new_string(item->bssid));
810                         g_variant_builder_add(&builder, "{sv}", "inactive_time",
811                                                 g_variant_new_uint32(item->inactive_time));
812                         g_variant_builder_add(&builder, "{sv}", "rx_bytes",
813                                                 g_variant_new_uint64(item->rx_bytes));
814                         g_variant_builder_add(&builder, "{sv}", "rx_packets",
815                                                 g_variant_new_uint32(item->rx_packets));
816                         g_variant_builder_add(&builder, "{sv}", "tx_bytes",
817                                                 g_variant_new_uint64(item->tx_bytes));
818                         g_variant_builder_add(&builder, "{sv}", "tx_packets",
819                                                 g_variant_new_uint32(item->tx_packets));
820                         g_variant_builder_add(&builder, "{sv}", "tx_retries",
821                                                 g_variant_new_uint32(item->tx_retries));
822                         g_variant_builder_add(&builder, "{sv}", "tx_failed",
823                                                 g_variant_new_uint32(item->tx_failed));
824                         g_variant_builder_add(&builder, "{sv}", "beacon_loss",
825                                                 g_variant_new_uint32(item->beacon_loss));
826                         g_variant_builder_add(&builder, "{sv}", "beacon_rx",
827                                                 g_variant_new_uint64(item->beacon_rx));
828                         g_variant_builder_add(&builder, "{sv}", "rx_drop_misc",
829                                                 g_variant_new_uint64(item->rx_drop_misc));
830                         g_variant_builder_add(&builder, "{sv}", "signal",
831                                                 g_variant_new_int32(item->rssi));
832                         g_variant_builder_add(&builder, "{sv}", "signal_avg",
833                                                 g_variant_new_int32(item->rssi_avg));
834                         g_variant_builder_add(&builder, "{sv}", "tx_bitrate",
835                                                 g_variant_new_uint32(item->tx_bitrate)); /* 10 times */
836                         g_variant_builder_add(&builder, "{sv}", "rx_bitrate",
837                                                 g_variant_new_uint32(item->rx_bitrate)); /* 10 times */
838                         g_variant_builder_add(&builder, "{sv}", "mesh_llid",
839                                                 g_variant_new_uint16(item->llid));
840                         g_variant_builder_add(&builder, "{sv}", "mesh_plid",
841                                                 g_variant_new_uint16(item->plid));
842                         g_variant_builder_add(&builder, "{sv}", "mesh_plink",
843                                                 g_variant_new_byte(item->mesh_plink)); /* 0 : DISCON, 1 : ESTAB */
844                         g_variant_builder_add(&builder, "{sv}", "local_ps_mode",
845                                                 g_variant_new_uint32(item->local_ps_mode)); /* 0 : INACTIVE, 1 : ACTIVE */
846                         g_variant_builder_add(&builder, "{sv}", "peer_ps_mode",
847                                                 g_variant_new_uint32(item->peer_ps_mode)); /* 0 : INACTIVE, 1 : ACTIVE */
848                         g_variant_builder_add(&builder, "{sv}", "non_peer_ps_mode",
849                                                 g_variant_new_uint32(item->non_peer_ps_mode)); /* 0 : INACTIVE, 1 : ACTIVE */
850                         g_variant_builder_add(&builder, "{sv}", "authorized",
851                                                 g_variant_new_boolean(item->authorized));
852                         g_variant_builder_add(&builder, "{sv}", "associated",
853                                                 g_variant_new_boolean(item->associated));
854                         g_variant_builder_add(&builder, "{sv}", "preamble",
855                                                 g_variant_new_boolean(item->preamble));
856                         g_variant_builder_add(&builder, "{sv}", "WMM_WME",
857                                                 g_variant_new_boolean(item->wme));
858                         g_variant_builder_add(&builder, "{sv}", "MFP",
859                                                 g_variant_new_boolean(item->mfp));
860                         g_variant_builder_add(&builder, "{sv}", "TDLS_peer",
861                                                 g_variant_new_boolean(item->tdls_peer));
862                         g_variant_builder_add(&builder, "{sv}", "DTIM_period",
863                                                 g_variant_new_byte(item->dtim_period));
864                         g_variant_builder_add(&builder, "{sv}", "beacon_interval",
865                                                 g_variant_new_uint16(item->beacon_interval));
866                         g_variant_builder_add(&builder, "{sv}", "short_slot_time",
867                                                 g_variant_new_boolean(item->short_slot_time));
868                         g_variant_builder_add(&builder, "{sv}", "connected_time",
869                                                 g_variant_new_uint32(item->connected_time));
870                         g_variant_builder_close(&builder);
871
872                         iter = g_list_next(iter);
873                 }
874
875                 station = g_variant_builder_end(&builder);
876                 net_mesh_complete_get_station_info(object, invocation, station, ret);
877
878                 g_object_unref(station);
879         }
880
881 #if 0
882         g_variant_builder_init(&builder, G_VARIANT_TYPE_VARDICT);
883         g_variant_builder_add(&builder, "{sv}", "station", g_variant_new_string("7c:dd:90:62:37:cf"));
884         g_variant_builder_add(&builder, "{sv}", "inactive_time", g_variant_new_uint32(1685));
885         g_variant_builder_add(&builder, "{sv}", "rx_bytes", g_variant_new_uint32(34174));
886         g_variant_builder_add(&builder, "{sv}", "rx_packets", g_variant_new_uint32(1181));
887         g_variant_builder_add(&builder, "{sv}", "tx_bytes", g_variant_new_uint32(6877));
888         g_variant_builder_add(&builder, "{sv}", "tx_packets", g_variant_new_uint32(76));
889         g_variant_builder_add(&builder, "{sv}", "tx_retries", g_variant_new_uint32(0));
890         g_variant_builder_add(&builder, "{sv}", "tx_failed", g_variant_new_uint32(0));
891         g_variant_builder_add(&builder, "{sv}", "beacon_loss", g_variant_new_uint32(0));
892         g_variant_builder_add(&builder, "{sv}", "signal", g_variant_new_int32(-64));
893         g_variant_builder_add(&builder, "{sv}", "signal_avg", g_variant_new_int32(-63));
894         g_variant_builder_add(&builder, "{sv}", "tx_bitrate", g_variant_new_uint32(540)); /* 10 times */
895         g_variant_builder_add(&builder, "{sv}", "rx_bitrate", g_variant_new_uint32(55)); /* 10 times */
896         g_variant_builder_add(&builder, "{sv}", "mesh_llid", g_variant_new_uint32(51731));
897         g_variant_builder_add(&builder, "{sv}", "mesh_plid", g_variant_new_uint32(35432));
898         g_variant_builder_add(&builder, "{sv}", "mesh_plink", g_variant_new_uint32(1)); /* 0 : DISCON, 1 : ESTAB */
899         g_variant_builder_add(&builder, "{sv}", "mesh_local_PS_mode", g_variant_new_uint32(1)); /* 0 : INACTIVE, 1 : ACTIVE */
900         g_variant_builder_add(&builder, "{sv}", "mesh_peer_PS_mode", g_variant_new_uint32(1)); /* 0 : INACTIVE, 1 : ACTIVE */
901         g_variant_builder_add(&builder, "{sv}", "mesh_none_peer_PS_mode", g_variant_new_uint32(1)); /* 0 : INACTIVE, 1 : ACTIVE */
902         g_variant_builder_add(&builder, "{sv}", "authorized", g_variant_new_boolean(TRUE));
903         g_variant_builder_add(&builder, "{sv}", "associated", g_variant_new_boolean(TRUE));
904         g_variant_builder_add(&builder, "{sv}", "preamble",g_variant_new_string("long"));
905         g_variant_builder_add(&builder, "{sv}", "WMM_WME", g_variant_new_boolean(TRUE));
906         g_variant_builder_add(&builder, "{sv}", "MFP", g_variant_new_boolean(FALSE));
907         g_variant_builder_add(&builder, "{sv}", "TDLS_peer", g_variant_new_boolean(FALSE));
908         g_variant_builder_add(&builder, "{sv}", "DTIM_period", g_variant_new_uint32(0));
909         g_variant_builder_add(&builder, "{sv}", "beacon_interval", g_variant_new_uint32(1000));
910         g_variant_builder_add(&builder, "{sv}", "short_slot_time", g_variant_new_boolean(TRUE));
911         g_variant_builder_add(&builder, "{sv}", "connected_time", g_variant_new_uint32(256));
912         station = g_variant_builder_end(&builder);
913
914         net_mesh_complete_get_station_info(object, invocation, station, ret);
915
916         g_object_unref(station);
917 #endif
918         return TRUE;
919 }
920
921 static gboolean _meshd_dbus_handle_get_mpath_info(NetMesh *object,
922                 GDBusMethodInvocation *invocation,
923                 gpointer user_data)
924 {
925         int ret = MESHD_ERROR_NONE;
926         GVariantBuilder builder;
927         GVariant* mpath_data;
928         GList *iter = NULL;
929
930         mesh_service *service = (mesh_service *)user_data;
931         mesh_interface_s *info = service->interface_info;
932
933         /* Clear mesh path list */
934         g_list_free_full(service->mpath_list, _on_mpath_list_destroy);
935         service->mpath_list = NULL;
936
937         ret = mesh_request_get_mpath_info(
938                                 info->mesh_interface, &service->mpath_list);
939         if (MESHD_ERROR_NONE != ret) {
940                 MESH_LOGE("Failed to mesh_request_get_mpath_info");
941
942                 g_dbus_method_invocation_return_error(invocation,
943                                 G_DBUS_ERROR, G_DBUS_ERROR_FAILED, "Request Failed");
944         } else {
945         /*
946          * Example) sh-3.2# iw mesh0 mpath dump
947          * DEST ADDR         NEXT HOP          IFACE    SN      METRIC  QLEN    EXPTIME         DTIM    DRET    FLAGS
948          * 7c:dd:90:62:37:cf 7c:dd:90:62:37:cf mesh0    221     152             0               10                      100             0               0x5
949          */
950                 /* Get mesh path information and make variant data */
951                 g_variant_builder_init(&builder, G_VARIANT_TYPE("aa{sv}"));
952         
953                 iter = service->mpath_list;
954                 while (iter != NULL) {
955                         mesh_mpath_info_s *item = (mesh_mpath_info_s*)iter->data;
956
957                         g_variant_builder_open(&builder, G_VARIANT_TYPE_VARDICT);
958                         g_variant_builder_add(&builder, "{sv}", "DEST_ADDR",
959                                                 g_variant_new_string(item->dest_addr));
960                         g_variant_builder_add(&builder, "{sv}", "NEXT_HOP",
961                                                 g_variant_new_string(item->next_hop));
962                         g_variant_builder_add(&builder, "{sv}", "IFACE",
963                                                 g_variant_new_string(item->interface));
964                         g_variant_builder_add(&builder, "{sv}", "SN",
965                                                 g_variant_new_uint32(item->sn));
966                         g_variant_builder_add(&builder, "{sv}", "METRIC",
967                                                 g_variant_new_uint32(item->metric));
968                         g_variant_builder_add(&builder, "{sv}", "QLEN",
969                                                 g_variant_new_uint32(item->qlen));
970                         g_variant_builder_add(&builder, "{sv}", "EXPTIME",
971                                                 g_variant_new_uint32(item->exptime));
972                         g_variant_builder_add(&builder, "{sv}", "DTIM",
973                                                 g_variant_new_uint32(item->discovery_timeout));
974                         g_variant_builder_add(&builder, "{sv}", "DRET",
975                                                 g_variant_new_byte(item->discovery_retries));
976                         g_variant_builder_add(&builder, "{sv}", "FLAGS",
977                                                 g_variant_new_byte(item->flags));
978                         g_variant_builder_close(&builder);
979
980                         iter = g_list_next(iter);
981                 }
982
983                 mpath_data = g_variant_builder_end(&builder);
984                 net_mesh_complete_get_mpath_info(object, invocation, mpath_data, ret);
985
986                 g_object_unref(mpath_data);
987         }
988
989         return TRUE;
990 }
991
992 static void _meshd_dbus_on_activator_bus_acquired(GDBusConnection *conn,
993                 const gchar *name, gpointer user_data)
994 {
995         gboolean ret;
996         GError *error = NULL;
997         mesh_service *service = (mesh_service *)user_data;
998
999         NOTUSED(name);
1000
1001         meshd_activator_dbus_object = manager_skeleton_new();
1002         if (NULL == meshd_activator_dbus_object) {
1003                 MESH_LOGE("manager_skeleton_new() Fail");
1004                 return;
1005         }
1006
1007         g_signal_connect(meshd_activator_dbus_object, "handle-enable",
1008                         G_CALLBACK(_meshd_dbus_handle_enable), service);
1009         g_signal_connect(meshd_activator_dbus_object, "handle-disable",
1010                         G_CALLBACK(_meshd_dbus_handle_disable), service);
1011
1012         ret = g_dbus_interface_skeleton_export(
1013                                 G_DBUS_INTERFACE_SKELETON(meshd_activator_dbus_object),
1014                                 conn, MESH_DBUS_MANAGER_OBJPATH, &error);
1015         if (FALSE == ret) {
1016                 MESH_LOGE("g_dbus_interface_skeleton_export() Fail(%s)", error->message);
1017                 g_error_free(error);
1018         }
1019 }
1020
1021 static void _meshd_dbus_on_bus_acquired(GDBusConnection *conn, const gchar *name,
1022                 gpointer user_data)
1023 {
1024         gboolean ret;
1025         GError *error = NULL;
1026         mesh_service *service = (mesh_service *)user_data;
1027
1028         NOTUSED(name);
1029
1030         meshd_dbus_object = net_mesh_skeleton_new();
1031         if (NULL == meshd_dbus_object) {
1032                 MESH_LOGE("net_mesh_skeleton_new() Fail");
1033                 return;
1034         }
1035
1036         g_signal_connect(meshd_dbus_object, "handle-scan",
1037                         G_CALLBACK(_meshd_dbus_handle_scan), service);
1038         g_signal_connect(meshd_dbus_object, "handle-specific-scan",
1039                         G_CALLBACK(_meshd_dbus_handle_specific_scan), service);
1040         g_signal_connect(meshd_dbus_object, "handle-cancel-scan",
1041                         G_CALLBACK(_meshd_dbus_handle_cancel_scan), service);
1042         g_signal_connect(meshd_dbus_object, "handle-get-found-mesh-networks",
1043                         G_CALLBACK(_meshd_dbus_handle_get_found_mesh_networks), service);
1044         g_signal_connect(meshd_dbus_object, "handle-enable-mesh",
1045                         G_CALLBACK(_meshd_dbus_handle_enable_mesh), service);
1046         g_signal_connect(meshd_dbus_object, "handle-disable-mesh",
1047                         G_CALLBACK(_meshd_dbus_handle_disable_mesh), service);
1048         g_signal_connect(meshd_dbus_object, "handle-get-joined-mesh-network",
1049                         G_CALLBACK(_meshd_dbus_handle_get_joined_mesh_network), service);
1050         g_signal_connect(meshd_dbus_object, "handle-set-gate",
1051                         G_CALLBACK(_meshd_dbus_handle_set_gate), service);
1052         g_signal_connect(meshd_dbus_object, "handle-unset-gate",
1053                         G_CALLBACK(_meshd_dbus_handle_unset_gate), service);
1054         g_signal_connect(meshd_dbus_object, "handle-set-softap",
1055                         G_CALLBACK(_meshd_dbus_handle_set_softap), service);
1056         g_signal_connect(meshd_dbus_object, "handle-enable-softap",
1057                         G_CALLBACK(_meshd_dbus_handle_enable_softap), service);
1058         g_signal_connect(meshd_dbus_object, "handle-disable-softap",
1059                         G_CALLBACK(_meshd_dbus_handle_disable_softap), service);
1060         g_signal_connect(meshd_dbus_object, "handle-add-mesh-network",
1061                         G_CALLBACK(_meshd_dbus_handle_add_mesh_network), service);
1062         g_signal_connect(meshd_dbus_object, "handle-get-saved-mesh-network",
1063                         G_CALLBACK(_meshd_dbus_handle_get_saved_mesh_network), service);
1064         g_signal_connect(meshd_dbus_object, "handle-select-saved-mesh-network",
1065                         G_CALLBACK(_meshd_dbus_handle_select_saved_mesh_network), service);
1066         g_signal_connect(meshd_dbus_object, "handle-forget-saved-mesh-network",
1067                         G_CALLBACK(_meshd_dbus_handle_forget_saved_mesh_network), service);
1068         g_signal_connect(meshd_dbus_object, "handle-set-interfaces",
1069                         G_CALLBACK(_meshd_dbus_handle_set_interfaces), service);
1070         g_signal_connect(meshd_dbus_object, "handle-get-station-info",
1071                         G_CALLBACK(_meshd_dbus_handle_get_station_info), service);
1072         g_signal_connect(meshd_dbus_object, "handle-get-mpath-info",
1073                         G_CALLBACK(_meshd_dbus_handle_get_mpath_info), service);
1074
1075         ret = g_dbus_interface_skeleton_export(G_DBUS_INTERFACE_SKELETON(meshd_dbus_object),
1076                         conn, MESH_DBUS_OBJPATH, &error);
1077         if (FALSE == ret) {
1078                 MESH_LOGE("g_dbus_interface_skeleton_export() Fail(%s)", error->message);
1079                 g_error_free(error);
1080         }
1081
1082         ret = _meshd_dbus_subscribe_name_owner_changed(conn);
1083         if (MESHD_ERROR_NONE != ret) {
1084                 MESH_LOGE("_meshd_dbus_subscribe_name_owner_changed() Fail(%d)", ret);
1085                 return;
1086         }
1087 }
1088
1089 static void _meshd_dbus_on_name_lost(GDBusConnection *conn, const gchar *name,
1090                 gpointer user_data)
1091 {
1092         NOTUSED(conn);
1093         NOTUSED(user_data);
1094
1095         MESH_LOGD("Lost the name %s", name);
1096 }
1097
1098 static void _meshd_dbus_on_name_acquired(GDBusConnection *conn, const gchar *name,
1099                 gpointer user_data)
1100 {
1101         NOTUSED(conn);
1102         NOTUSED(user_data);
1103
1104         MESH_LOGD("Acquired the name %s", name);
1105 }
1106
1107 static gboolean _meshd_dbus_interface_init(mesh_service *service)
1108 {
1109         guint id;
1110         guint activation_dbus_id;
1111         meshd_check_null_ret_error("service", service, FALSE);
1112
1113         id = g_bus_own_name(G_BUS_TYPE_SYSTEM,
1114                         MESH_DBUS_INTERFACE,
1115                         G_BUS_NAME_OWNER_FLAGS_REPLACE,
1116                         _meshd_dbus_on_bus_acquired,
1117                         _meshd_dbus_on_name_acquired,
1118                         _meshd_dbus_on_name_lost,
1119                         service,
1120                         NULL);
1121         if (0 == id) {
1122                 MESH_LOGE("g_bus_own_name() Fail");
1123                 return FALSE;
1124         }
1125
1126         /* Get D-Bus owner to activate zigbee-daemon */
1127         activation_dbus_id = g_bus_own_name(G_BUS_TYPE_SYSTEM,
1128                         MESH_DBUS_INTERFACE".manager",
1129                         G_BUS_NAME_OWNER_FLAGS_REPLACE,
1130                         _meshd_dbus_on_activator_bus_acquired,
1131                         NULL,
1132                         NULL,
1133                         service,
1134                         NULL);
1135
1136         service->dbus_id = id;
1137         service->activation_dbus_id = activation_dbus_id;
1138         service->interface_info = g_new0(mesh_interface_s, 1);
1139         service->scanned_mesh_network = NULL;
1140
1141         return TRUE;
1142 }
1143
1144 static void _meshd_dbus_deinit(mesh_service *service)
1145 {
1146         mesh_interface_s *info = NULL;
1147         meshd_check_null_ret("service", service);
1148
1149         g_bus_unown_name(service->dbus_id);
1150
1151         g_bus_unown_name(service->activation_dbus_id);
1152
1153         info = service->interface_info;
1154         meshd_check_null_ret("info", info);
1155         if (info->bridge_interface)
1156                 g_free(info->bridge_interface);
1157         if (info->base_interface)
1158                 g_free(info->base_interface);
1159         if (info->mesh_interface)
1160                 g_free(info->mesh_interface);
1161         if (info->softap_interface)
1162                 g_free(info->softap_interface);
1163         if (info->external_interface)
1164                 g_free(info->external_interface);
1165
1166         if (service->joined_network) {
1167                 g_free(service->joined_network->mesh_id);
1168                 g_free(service->joined_network);
1169                 service->joined_network = NULL;
1170         }
1171         mesh_request_clear_saved_mesh_network(&service->saved_mesh_network);
1172
1173         /* Clear scan list */
1174         g_list_free_full(service->scanned_mesh_network, _on_scan_result_destroy);
1175         service->scanned_mesh_network = NULL;
1176
1177         g_free(service->interface_info);
1178         service->interface_info = NULL;
1179 }
1180
1181  /**< mesh service interface initialization */
1182 gboolean meshd_service_interface_init(mesh_service *service)
1183 {
1184         guint ret;
1185         meshd_check_null_ret_error("service", service, FALSE);
1186
1187         /* Initialize dbus interface */
1188         ret = _meshd_dbus_interface_init(service);
1189         if (FALSE == ret) {
1190                 MESH_LOGE("zigbee_service_dbus_interface_init failed!!!");
1191                 return FALSE;
1192         }
1193
1194         return TRUE;
1195 }
1196
1197 /**< Zigbee service interface de-initialization */
1198 void meshd_service_interface_deinit(mesh_service *service)
1199 {
1200         meshd_check_null_ret("service", service);
1201
1202         /* De-initialize dbus interface */
1203         _meshd_dbus_deinit(service);
1204 }