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