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