Add network connection state
[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_add(&builder, "{sv}", "state",
388                                 g_variant_new_uint32(scan_item->state));
389                 g_variant_builder_close(&builder);
390
391                 iter = g_list_next(iter);
392         }
393
394         /* Clear scan list */
395         //g_list_free_full(service->scanned_mesh_network, _on_scan_result_destroy);
396         //service->scanned_mesh_network = NULL;
397
398         networks = g_variant_builder_end(&builder);
399
400         net_mesh_complete_get_found_mesh_networks(object, invocation, networks, ret);
401
402         return TRUE;
403 }
404
405 static gboolean _meshd_dbus_handle_enable_mesh(NetMesh *object,
406                 GDBusMethodInvocation *invocation,
407                 gpointer user_data)
408 {
409         int ret = MESHD_ERROR_NONE;
410         mesh_service *service = (mesh_service *)user_data;
411         //mesh_interface_s *info = service->interface_info;
412
413 #if 0 ///////////////////
414         /* Create or join mesh network and create bridge */
415         ret = mesh_request_enable_mesh(info->base_interface, info->mesh_interface,
416                                 service->saved_mesh_network, &service->joined_network);
417         if (MESHD_ERROR_NONE != ret) {
418                 MESH_LOGE("Failed to mesh_request_enable_mesh [%d]", ret);
419                 goto FINISH;
420         }
421
422         ret = mesh_request_create_bridge(info->bridge_interface, info->mesh_interface);
423         if (MESHD_ERROR_NONE != ret) {
424                 MESH_LOGE("Failed to mesh_request_create_bridge [%d]", ret);
425                 goto FINISH;
426         }
427 #endif
428         ret = mesh_request_ipc_enable_network(service);
429         if (MESHD_ERROR_NONE != ret) {
430                 MESH_LOGE("Failed to mesh_request_ipc_enable_network [%d]", ret);
431                 goto FINISH;
432         }
433
434 #if 0
435         /* Detect external network state (i.e. Ethernet)
436                         and decide to make gate enabled */
437         ret = mesh_request_set_mesh_gate(info->bridge_interface,
438                         info->mesh_interface, info->external_interface);
439         if (MESHD_ERROR_NONE != ret) {
440                 MESH_LOGE("Failed to mesh_request_set_mesh_gate [%d]", ret);
441         }
442
443
444         /* TODO: Check if specific scan is required */
445         ret = mesh_request_specific_scan(info->mesh_interface,
446                         info->mesh_id, info->mesh_channel);
447         if (MESHD_ERROR_NONE != ret) {
448                 MESH_LOGE("Failed to mesh_request_specific_scan [%d]", ret);
449         }
450         ret = mesh_request_get_scan_result(info->mesh_interface,
451                         &service->scanned_mesh_network);
452
453         /* Request DHCP on bridge interface */
454         ret = mesh_request_dhcp(info->bridge_interface);
455         if (MESHD_ERROR_NONE != ret) {
456                 MESH_LOGE("Failed to mesh_request_dhcp [%d]", ret);
457         }
458
459         /* TODO: Notify bridge status to Connman */
460 #endif
461
462 FINISH:
463         net_mesh_complete_enable_mesh(object, invocation, ret);
464
465         return TRUE;
466 }
467
468 static gboolean _meshd_dbus_handle_disable_mesh(NetMesh *object,
469                 GDBusMethodInvocation *invocation,
470                 gpointer user_data)
471 {
472         int ret = MESHD_ERROR_NONE;
473         mesh_service *service = (mesh_service *)user_data;
474         mesh_interface_s *info = service->interface_info;
475
476         meshd_check_null_ret_error("info", info, FALSE);
477 #if 0
478         /* Destroy bridge and return from mesh to infra mode */
479         if (service->joined_network) {
480                 g_free(service->joined_network->mesh_id);
481                 g_free(service->joined_network);
482                 service->joined_network = NULL;
483         }
484 #endif
485         if (FALSE == service->mesh_activated) {
486                 MESH_LOGD("Mesh network is not activated yet");
487                 ret = MESHD_ERROR_OPERATION_FAILED;
488                 net_mesh_complete_disable_mesh(object, invocation, ret);
489                 return TRUE;
490         }
491
492         ret = mesh_request_ipc_disable_network(service);
493         if (MESHD_ERROR_NONE != ret) {
494                 MESH_LOGE("Failed to disable mesh network !");
495         }
496 #if 0
497         /* If DHCP is on progress, stop it */
498         ret = mesh_request_stop_dhcp();
499         if (MESHD_ERROR_NONE != ret) {
500                 MESH_LOGE("Failed to stop DHCP request !");
501         }
502
503         ret = mesh_request_disable_mesh(info->mesh_interface);
504         if (MESHD_ERROR_NONE != ret) {
505                 MESH_LOGE("Failed to mesh_request_disable_mesh_gate");
506         }
507
508         ret = mesh_request_remove_bridge(info->bridge_interface);
509         if (MESHD_ERROR_NONE != ret) {
510                 MESH_LOGE("Failed to mesh_request_remove_bridge");
511         }
512 #endif
513         /* Make response */
514         net_mesh_complete_disable_mesh(object, invocation, ret);
515
516         return TRUE;
517 }
518
519 static gboolean _meshd_dbus_handle_get_joined_mesh_network(NetMesh *object,
520                 GDBusMethodInvocation *invocation,
521                 gpointer user_data)
522 {
523         int ret = MESHD_ERROR_NONE;
524         mesh_service *service = (mesh_service *)user_data;
525         mesh_network_info_s *joined = NULL;
526
527         //gchar *meshid = strdup("meshnet");
528         //gchar *bssid = strdup("7c:dd:90:d8:2a:64");
529         //gint channel = 161;
530         //gint max_speed = 866;
531         ret = mesh_request_ipc_get_joined_network(service);
532         if (MESHD_ERROR_NONE == ret) {
533                 joined = service->joined_network;
534                 if (joined) {
535                         net_mesh_complete_get_joined_mesh_network(object, invocation,
536                                 joined->mesh_id, joined->bssid,
537                                 joined->channel, joined->state, ret);
538                 } else {
539                         net_mesh_complete_get_joined_mesh_network(object, invocation,
540                                 "", "", 0, 0, MESHD_ERROR_NO_DATA);
541                 }
542         } else {
543                 net_mesh_complete_get_joined_mesh_network(object, invocation,
544                         "", "", 0, 0, ret);
545         }
546
547         return TRUE;
548 }
549
550 static gboolean _meshd_dbus_handle_get_connected_peers(NetMesh *object,
551                 GDBusMethodInvocation *invocation,
552                 gpointer user_data)
553 {
554         int ret = MESHD_ERROR_NONE;
555         mesh_service *service = (mesh_service *)user_data;
556
557         GVariantBuilder builder;
558         GVariant* peer_list;
559         GList *iter = NULL;
560         mesh_peer_info_s *peer = NULL;
561
562         MESH_LOGD("Request to get connected peers");
563
564         ret = mesh_ipc_get_connected_peers(service);
565         if (MESHD_ERROR_NONE != ret)
566                 MESH_LOGE("Failed to mesh_ipc_get_connected_peers");
567         g_variant_builder_init(&builder, G_VARIANT_TYPE("aa{sv}"));
568
569         iter = service->connected_mesh_peers;
570         while (iter != NULL) {
571                 peer = (mesh_peer_info_s*)iter->data;
572
573                 g_variant_builder_open(&builder, G_VARIANT_TYPE_VARDICT);
574                 g_variant_builder_add(&builder, "{sv}", "Address",
575                                 g_variant_new_string(peer->address));
576                 g_variant_builder_close(&builder);
577
578                 iter = g_list_next(iter);
579         }
580
581         peer_list = g_variant_builder_end(&builder);
582
583         net_mesh_complete_get_connected_peers(object, invocation, peer_list, ret);
584
585         return TRUE;
586 }
587
588 static gboolean _meshd_dbus_handle_set_gate(NetMesh *object,
589                 GDBusMethodInvocation *invocation, gboolean stp, gboolean gate_announce,
590                 gpointer user_data)
591 {
592         int ret = MESHD_ERROR_NONE;
593         mesh_service *service = (mesh_service *)user_data;
594         mesh_interface_s *info = service->interface_info;
595
596         MESH_LOGD("STP = %d", stp);
597         MESH_LOGD("gate_announce = %d", gate_announce);
598
599         /* Set STP and gate_announce */
600         ret = mesh_request_set_mesh_gate(info->bridge_interface,
601                         info->mesh_interface, info->external_interface);
602         if (MESHD_ERROR_NONE != ret) {
603                 MESH_LOGE("Failed to mesh_request_set_mesh_gate [%d]", ret);
604         }
605
606         net_mesh_complete_set_gate(object, invocation, ret);
607
608         return TRUE;
609 }
610
611 static gboolean _meshd_dbus_handle_unset_gate(NetMesh *object,
612                 GDBusMethodInvocation *invocation,
613                 gpointer user_data)
614 {
615         int ret = MESHD_ERROR_NONE;
616         mesh_service *service = (mesh_service *)user_data;
617         mesh_interface_s *info = service->interface_info;
618
619         ret = mesh_request_unset_mesh_gate(info->bridge_interface,
620                         info->mesh_interface, info->external_interface);
621         if (MESHD_ERROR_NONE != ret) {
622                 MESH_LOGE("Failed to mesh_request_unset_mesh_gate [%d]", ret);
623         }
624         net_mesh_complete_unset_gate(object, invocation, ret);
625
626         return TRUE;
627 }
628
629 static gboolean _meshd_dbus_handle_set_softap(NetMesh *object,
630                 GDBusMethodInvocation *invocation,
631                 gchar *ssid, gchar *passphrase,
632                 gchar *mode, gint channel, gint visibility, gint max_sta,
633                 gint security, gpointer user_data)
634 {
635         int ret = MESHD_ERROR_NONE;
636         mesh_service *service = (mesh_service *)user_data;
637         mesh_interface_s *info = service->interface_info;
638
639         MESH_LOGD("SSID      : %s", ssid);
640         MESH_LOGD("mode      : %s", mode);
641         MESH_LOGD("channel   : %d", channel);
642         MESH_LOGD("visibility: %d", visibility);
643         MESH_LOGD("max_sta   : %d", max_sta);
644         MESH_LOGD("security  : %d", security);
645
646         /* Save softAP information */
647         ret = mesh_request_set_softap_config(info->softap_interface,
648                 ssid, mode, channel, visibility, max_sta,
649                 security, passphrase);
650         if (MESHD_ERROR_NONE != ret) {
651                 MESH_LOGE("Failed to mesh_request_set_softap_config [%d]", ret);
652         }
653
654         net_mesh_complete_set_softap(object, invocation, ret);
655
656         return TRUE;
657 }
658
659 static gboolean _meshd_dbus_handle_enable_softap(NetMesh *object,
660                 GDBusMethodInvocation *invocation, gpointer user_data)
661 {
662         int ret = MESHD_ERROR_NONE;
663         mesh_service *service = (mesh_service *)user_data;
664         mesh_interface_s *info = service->interface_info;
665
666         /* Check softAP interface and execute it */
667         ret = mesh_request_enable_softap(info->bridge_interface, info->softap_interface);
668         if (MESHD_ERROR_NONE != ret) {
669                 MESH_LOGE("Failed to mesh_request_enable_softap [%d]", ret);
670         }
671
672         net_mesh_complete_enable_softap(object, invocation, ret);
673
674         return TRUE;
675 }
676
677 static gboolean _meshd_dbus_handle_disable_softap(NetMesh *object,
678                 GDBusMethodInvocation *invocation, gpointer user_data)
679 {
680         int ret = MESHD_ERROR_NONE;
681         mesh_service *service = (mesh_service *)user_data;
682         mesh_interface_s *info = service->interface_info;
683
684         /* Destroy softAP */
685         ret = mesh_request_disable_softap(info->bridge_interface, info->softap_interface);
686         if (MESHD_ERROR_NONE != ret) {
687                 MESH_LOGE("Failed to mesh_request_disable_softap [%d]", ret);
688         }
689
690         net_mesh_complete_disable_softap(object, invocation, ret);
691
692         return TRUE;
693 }
694
695 static gboolean _meshd_dbus_handle_create_mesh_network(NetMesh *object,
696                 GDBusMethodInvocation *invocation,
697                 gchar *mesh_id, gint channel, gint security,
698                 gpointer user_data)
699 {
700         int ret = MESHD_ERROR_NONE;
701         mesh_service *service = (mesh_service *)user_data;
702
703         //ret = mesh_request_add_mesh_network(&service->saved_mesh_network,
704         //              mesh_id, channel, security);
705         ret = mesh_request_ipc_create_mesh_network(service, mesh_id, channel, security);
706
707         net_mesh_complete_create_mesh_network(object, invocation, ret);
708
709         return TRUE;
710 }
711 #if 0
712 static gboolean _meshd_dbus_handle_get_saved_mesh_network(NetMesh *object,
713                 GDBusMethodInvocation *invocation,
714                 gpointer user_data)
715 {
716         int ret = MESHD_ERROR_NONE;
717         mesh_service *service = (mesh_service *)user_data;
718
719         GVariantBuilder builder;
720         GVariant* networks;
721         GList *iter = NULL;
722
723         ret = mesh_request_get_saved_mesh_network(&service->saved_mesh_network);
724         if (MESHD_ERROR_NONE != ret) {
725                 MESH_LOGE("Failed to mesh_request_get_saved_mesh_network");
726
727                 g_dbus_method_invocation_return_error(invocation,
728                                 G_DBUS_ERROR, G_DBUS_ERROR_FAILED, "Request Failed");
729         } else {
730                 /* TODO: Get station information and make variant data */
731                 g_variant_builder_init(&builder, G_VARIANT_TYPE("aa{sv}"));
732
733                 iter = service->saved_mesh_network;
734                 while (iter != NULL) {
735                         mesh_network_info_s *item = (mesh_network_info_s*)iter->data;
736
737                         g_variant_builder_open(&builder, G_VARIANT_TYPE_VARDICT);
738                         g_variant_builder_add(&builder, "{sv}", "mesh_id",
739                                         g_variant_new_string(item->mesh_id));
740                         g_variant_builder_add(&builder, "{sv}", "channel",
741                                         g_variant_new_uint32(item->channel));
742                         g_variant_builder_add(&builder, "{sv}", "security",
743                                         g_variant_new_uint32(item->security));
744                         g_variant_builder_close(&builder);
745
746                         iter = g_list_next(iter);
747                 }
748
749                 networks = g_variant_builder_end(&builder);
750                 net_mesh_complete_get_saved_mesh_network(object, invocation, networks, ret);
751         }
752
753         return TRUE;
754 }
755 #endif
756 static gboolean _meshd_dbus_handle_connect_mesh_network(NetMesh *object,
757                 GDBusMethodInvocation *invocation,
758                 gchar *mesh_id, gint channel, gint security,
759                 gpointer user_data)
760 {
761         int ret = MESHD_ERROR_NONE;
762         mesh_service *service = (mesh_service *)user_data;
763
764         //ret = mesh_request_select_saved_mesh_network(&service->saved_mesh_network,
765         //              mesh_id, channel, security);
766
767 /* ADDED */
768         ret = mesh_request_ipc_connect_mesh_network(service, mesh_id, channel, security);
769 /* ADDED */
770
771         net_mesh_complete_connect_mesh_network(object, invocation, ret);
772
773         return TRUE;
774 }
775 static gboolean _meshd_dbus_handle_disconnect_mesh_network(NetMesh *object,
776                 GDBusMethodInvocation *invocation,
777                 gchar *mesh_id, gint channel, gint security,
778                 gpointer user_data)
779 {
780         int ret = MESHD_ERROR_NONE;
781         mesh_service *service = (mesh_service *)user_data;
782
783         ret = mesh_request_ipc_disconnect_mesh_network(service, mesh_id, channel, security);
784
785         net_mesh_complete_disconnect_mesh_network(object, invocation, ret);
786
787         return TRUE;
788 }
789
790 static gboolean _meshd_dbus_handle_forget_mesh_network(NetMesh *object,
791                 GDBusMethodInvocation *invocation,
792                 gchar *mesh_id, gint channel, gint security,
793                 gpointer user_data)
794 {
795         int ret = MESHD_ERROR_NONE;
796         mesh_service *service = (mesh_service *)user_data;
797
798         //ret = mesh_request_forget_saved_mesh_network(&service->saved_mesh_network,
799         //              mesh_id, channel, security);
800         ret = mesh_request_ipc_remove_mesh_network(service,
801                         mesh_id, channel, security);
802
803         net_mesh_complete_forget_mesh_network(object, invocation, ret);
804
805         return TRUE;
806 }
807
808 static gboolean _meshd_dbus_handle_set_interfaces(NetMesh *object,
809                 GDBusMethodInvocation *invocation,
810                 gchar *mesh, gchar *gate, gchar *softap,
811                 gpointer user_data)
812 {
813         int ret = MESHD_ERROR_NONE;
814         mesh_service *service = (mesh_service *)user_data;
815         mesh_interface_s *info = service->interface_info;
816
817         g_free(info->mesh_interface);
818         info->mesh_interface = g_strdup(mesh);
819
820         g_free(info->external_interface);
821         info->external_interface = g_strdup(gate);
822
823         g_free(info->softap_interface);
824         info->softap_interface = g_strdup(softap);
825
826         MESH_LOGD("Interface configuration for mesh network :");
827         MESH_LOGD("  Base    : [%s]", info->base_interface);
828         MESH_LOGD("  Mesh    : [%s]", info->mesh_interface);
829         MESH_LOGD("  Bridge  : [%s]", info->bridge_interface);
830         MESH_LOGD("  SoftAP  : [%s]", info->softap_interface);
831         MESH_LOGD("  External: [%s]", info->external_interface);
832
833         net_mesh_complete_set_interfaces(object, invocation, ret);
834
835         return TRUE;
836 }
837
838 static gboolean _meshd_dbus_handle_get_station_info(NetMesh *object,
839                 GDBusMethodInvocation *invocation,
840                 gpointer user_data)
841 {
842         int ret = MESHD_ERROR_NONE;
843
844         GVariantBuilder builder;
845         GVariant* station;
846         GList *iter = NULL;
847
848         mesh_service *service = (mesh_service *)user_data;
849         mesh_interface_s *info = service->interface_info;
850
851         /* Clear mesh station list */
852         g_list_free_full(service->station_list, _on_station_list_destroy);
853         service->station_list = NULL;
854
855         ret = mesh_request_get_station_info(
856                                 info->mesh_interface, &service->station_list);
857         if (MESHD_ERROR_NONE != ret) {
858                 MESH_LOGE("Failed to mesh_request_get_station_info");
859
860                 g_dbus_method_invocation_return_error(invocation,
861                                 G_DBUS_ERROR, G_DBUS_ERROR_FAILED, "Request Failed");
862         } else {
863         /*
864          * sh-3.2#  iw mesh0 station dump
865          * Station 7c:dd:90:62:37:cf (on mesh0)
866          * inactive time:       1685 ms
867          * rx bytes:    34174
868          * rx packets:  1181
869          * tx bytes:    6877
870          * tx packets:  76
871          * tx retries:  0
872          * tx failed:   0
873          * beacon loss: 0
874          * signal:      -64 dBm
875          * signal avg:  -63 dBm
876          * tx bitrate:  54.0 MBit/s
877          * rx bitrate:  5.5 MBit/s
878          * mesh llid:   51731
879          * mesh plid:   35432
880          * mesh plink:  ESTAB
881          * mesh local PS mode:  ACTIVE
882          * mesh peer PS mode:   ACTIVE
883          * mesh non-peer PS mode:       ACTIVE
884          * authorized:  yes
885          * authenticated:       yes
886          * associated:  yes
887          * preamble:    long
888          * WMM/WME:     yes
889          * MFP:         no
890          * TDLS peer:   no
891          * DTIM period: 0
892          * beacon interval:1000
893          * short slot time:yes
894          * connected time:      256 seconds
895          */
896                 /* Get station information and make variant data */
897                 g_variant_builder_init(&builder, G_VARIANT_TYPE("aa{sv}"));
898
899                 iter = service->station_list;
900                 while (iter != NULL) {
901                         mesh_station_info_s *item = (mesh_station_info_s*)iter->data;
902
903                         g_variant_builder_open(&builder, G_VARIANT_TYPE_VARDICT);
904                         g_variant_builder_add(&builder, "{sv}", "bssid",
905                                                 g_variant_new_string(item->bssid));
906                         g_variant_builder_add(&builder, "{sv}", "inactive_time",
907                                                 g_variant_new_uint32(item->inactive_time));
908                         g_variant_builder_add(&builder, "{sv}", "rx_bytes",
909                                                 g_variant_new_uint64(item->rx_bytes));
910                         g_variant_builder_add(&builder, "{sv}", "rx_packets",
911                                                 g_variant_new_uint32(item->rx_packets));
912                         g_variant_builder_add(&builder, "{sv}", "tx_bytes",
913                                                 g_variant_new_uint64(item->tx_bytes));
914                         g_variant_builder_add(&builder, "{sv}", "tx_packets",
915                                                 g_variant_new_uint32(item->tx_packets));
916                         g_variant_builder_add(&builder, "{sv}", "tx_retries",
917                                                 g_variant_new_uint32(item->tx_retries));
918                         g_variant_builder_add(&builder, "{sv}", "tx_failed",
919                                                 g_variant_new_uint32(item->tx_failed));
920                         g_variant_builder_add(&builder, "{sv}", "beacon_loss",
921                                                 g_variant_new_uint32(item->beacon_loss));
922                         g_variant_builder_add(&builder, "{sv}", "beacon_rx",
923                                                 g_variant_new_uint64(item->beacon_rx));
924                         g_variant_builder_add(&builder, "{sv}", "rx_drop_misc",
925                                                 g_variant_new_uint64(item->rx_drop_misc));
926                         g_variant_builder_add(&builder, "{sv}", "signal",
927                                                 g_variant_new_int32(item->rssi));
928                         g_variant_builder_add(&builder, "{sv}", "signal_avg",
929                                                 g_variant_new_int32(item->rssi_avg));
930                         g_variant_builder_add(&builder, "{sv}", "tx_bitrate",
931                                                 g_variant_new_uint32(item->tx_bitrate)); /* 10 times */
932                         g_variant_builder_add(&builder, "{sv}", "rx_bitrate",
933                                                 g_variant_new_uint32(item->rx_bitrate)); /* 10 times */
934                         g_variant_builder_add(&builder, "{sv}", "mesh_llid",
935                                                 g_variant_new_uint16(item->llid));
936                         g_variant_builder_add(&builder, "{sv}", "mesh_plid",
937                                                 g_variant_new_uint16(item->plid));
938                         g_variant_builder_add(&builder, "{sv}", "mesh_plink",
939                                                 g_variant_new_byte(item->mesh_plink)); /* 0 : DISCON, 1 : ESTAB */
940                         g_variant_builder_add(&builder, "{sv}", "local_ps_mode",
941                                                 g_variant_new_uint32(item->local_ps_mode)); /* 0 : INACTIVE, 1 : ACTIVE */
942                         g_variant_builder_add(&builder, "{sv}", "peer_ps_mode",
943                                                 g_variant_new_uint32(item->peer_ps_mode)); /* 0 : INACTIVE, 1 : ACTIVE */
944                         g_variant_builder_add(&builder, "{sv}", "non_peer_ps_mode",
945                                                 g_variant_new_uint32(item->non_peer_ps_mode)); /* 0 : INACTIVE, 1 : ACTIVE */
946                         g_variant_builder_add(&builder, "{sv}", "authorized",
947                                                 g_variant_new_boolean(item->authorized));
948                         g_variant_builder_add(&builder, "{sv}", "associated",
949                                                 g_variant_new_boolean(item->associated));
950                         g_variant_builder_add(&builder, "{sv}", "preamble",
951                                                 g_variant_new_boolean(item->preamble));
952                         g_variant_builder_add(&builder, "{sv}", "WMM_WME",
953                                                 g_variant_new_boolean(item->wme));
954                         g_variant_builder_add(&builder, "{sv}", "MFP",
955                                                 g_variant_new_boolean(item->mfp));
956                         g_variant_builder_add(&builder, "{sv}", "TDLS_peer",
957                                                 g_variant_new_boolean(item->tdls_peer));
958                         g_variant_builder_add(&builder, "{sv}", "DTIM_period",
959                                                 g_variant_new_byte(item->dtim_period));
960                         g_variant_builder_add(&builder, "{sv}", "beacon_interval",
961                                                 g_variant_new_uint16(item->beacon_interval));
962                         g_variant_builder_add(&builder, "{sv}", "short_slot_time",
963                                                 g_variant_new_boolean(item->short_slot_time));
964                         g_variant_builder_add(&builder, "{sv}", "connected_time",
965                                                 g_variant_new_uint32(item->connected_time));
966                         g_variant_builder_close(&builder);
967
968                         iter = g_list_next(iter);
969                 }
970
971                 station = g_variant_builder_end(&builder);
972                 net_mesh_complete_get_station_info(object, invocation, station, ret);
973
974                 g_object_unref(station);
975         }
976
977 #if 0
978         g_variant_builder_init(&builder, G_VARIANT_TYPE_VARDICT);
979         g_variant_builder_add(&builder, "{sv}", "station", g_variant_new_string("7c:dd:90:62:37:cf"));
980         g_variant_builder_add(&builder, "{sv}", "inactive_time", g_variant_new_uint32(1685));
981         g_variant_builder_add(&builder, "{sv}", "rx_bytes", g_variant_new_uint32(34174));
982         g_variant_builder_add(&builder, "{sv}", "rx_packets", g_variant_new_uint32(1181));
983         g_variant_builder_add(&builder, "{sv}", "tx_bytes", g_variant_new_uint32(6877));
984         g_variant_builder_add(&builder, "{sv}", "tx_packets", g_variant_new_uint32(76));
985         g_variant_builder_add(&builder, "{sv}", "tx_retries", g_variant_new_uint32(0));
986         g_variant_builder_add(&builder, "{sv}", "tx_failed", g_variant_new_uint32(0));
987         g_variant_builder_add(&builder, "{sv}", "beacon_loss", g_variant_new_uint32(0));
988         g_variant_builder_add(&builder, "{sv}", "signal", g_variant_new_int32(-64));
989         g_variant_builder_add(&builder, "{sv}", "signal_avg", g_variant_new_int32(-63));
990         g_variant_builder_add(&builder, "{sv}", "tx_bitrate", g_variant_new_uint32(540)); /* 10 times */
991         g_variant_builder_add(&builder, "{sv}", "rx_bitrate", g_variant_new_uint32(55)); /* 10 times */
992         g_variant_builder_add(&builder, "{sv}", "mesh_llid", g_variant_new_uint32(51731));
993         g_variant_builder_add(&builder, "{sv}", "mesh_plid", g_variant_new_uint32(35432));
994         g_variant_builder_add(&builder, "{sv}", "mesh_plink", g_variant_new_uint32(1)); /* 0 : DISCON, 1 : ESTAB */
995         g_variant_builder_add(&builder, "{sv}", "mesh_local_PS_mode", g_variant_new_uint32(1)); /* 0 : INACTIVE, 1 : ACTIVE */
996         g_variant_builder_add(&builder, "{sv}", "mesh_peer_PS_mode", g_variant_new_uint32(1)); /* 0 : INACTIVE, 1 : ACTIVE */
997         g_variant_builder_add(&builder, "{sv}", "mesh_none_peer_PS_mode", g_variant_new_uint32(1)); /* 0 : INACTIVE, 1 : ACTIVE */
998         g_variant_builder_add(&builder, "{sv}", "authorized", g_variant_new_boolean(TRUE));
999         g_variant_builder_add(&builder, "{sv}", "associated", g_variant_new_boolean(TRUE));
1000         g_variant_builder_add(&builder, "{sv}", "preamble",g_variant_new_string("long"));
1001         g_variant_builder_add(&builder, "{sv}", "WMM_WME", g_variant_new_boolean(TRUE));
1002         g_variant_builder_add(&builder, "{sv}", "MFP", g_variant_new_boolean(FALSE));
1003         g_variant_builder_add(&builder, "{sv}", "TDLS_peer", g_variant_new_boolean(FALSE));
1004         g_variant_builder_add(&builder, "{sv}", "DTIM_period", g_variant_new_uint32(0));
1005         g_variant_builder_add(&builder, "{sv}", "beacon_interval", g_variant_new_uint32(1000));
1006         g_variant_builder_add(&builder, "{sv}", "short_slot_time", g_variant_new_boolean(TRUE));
1007         g_variant_builder_add(&builder, "{sv}", "connected_time", g_variant_new_uint32(256));
1008         station = g_variant_builder_end(&builder);
1009
1010         net_mesh_complete_get_station_info(object, invocation, station, ret);
1011
1012         g_object_unref(station);
1013 #endif
1014         return TRUE;
1015 }
1016
1017 static gboolean _meshd_dbus_handle_get_mpath_info(NetMesh *object,
1018                 GDBusMethodInvocation *invocation,
1019                 gpointer user_data)
1020 {
1021         int ret = MESHD_ERROR_NONE;
1022         GVariantBuilder builder;
1023         GVariant* mpath_data;
1024         GList *iter = NULL;
1025
1026         mesh_service *service = (mesh_service *)user_data;
1027         mesh_interface_s *info = service->interface_info;
1028
1029         /* Clear mesh path list */
1030         g_list_free_full(service->mpath_list, _on_mpath_list_destroy);
1031         service->mpath_list = NULL;
1032
1033         ret = mesh_request_get_mpath_info(
1034                                 info->mesh_interface, &service->mpath_list);
1035         if (MESHD_ERROR_NONE != ret) {
1036                 MESH_LOGE("Failed to mesh_request_get_mpath_info");
1037
1038                 g_dbus_method_invocation_return_error(invocation,
1039                                 G_DBUS_ERROR, G_DBUS_ERROR_FAILED, "Request Failed");
1040         } else {
1041         /*
1042          * Example) sh-3.2# iw mesh0 mpath dump
1043          * DEST ADDR         NEXT HOP          IFACE    SN      METRIC  QLEN    EXPTIME         DTIM    DRET    FLAGS
1044          * 7c:dd:90:62:37:cf 7c:dd:90:62:37:cf mesh0    221     152             0               10                      100             0               0x5
1045          */
1046                 /* Get mesh path information and make variant data */
1047                 g_variant_builder_init(&builder, G_VARIANT_TYPE("aa{sv}"));
1048         
1049                 iter = service->mpath_list;
1050                 while (iter != NULL) {
1051                         mesh_mpath_info_s *item = (mesh_mpath_info_s*)iter->data;
1052
1053                         g_variant_builder_open(&builder, G_VARIANT_TYPE_VARDICT);
1054                         g_variant_builder_add(&builder, "{sv}", "DEST_ADDR",
1055                                                 g_variant_new_string(item->dest_addr));
1056                         g_variant_builder_add(&builder, "{sv}", "NEXT_HOP",
1057                                                 g_variant_new_string(item->next_hop));
1058                         g_variant_builder_add(&builder, "{sv}", "IFACE",
1059                                                 g_variant_new_string(item->interface));
1060                         g_variant_builder_add(&builder, "{sv}", "SN",
1061                                                 g_variant_new_uint32(item->sn));
1062                         g_variant_builder_add(&builder, "{sv}", "METRIC",
1063                                                 g_variant_new_uint32(item->metric));
1064                         g_variant_builder_add(&builder, "{sv}", "QLEN",
1065                                                 g_variant_new_uint32(item->qlen));
1066                         g_variant_builder_add(&builder, "{sv}", "EXPTIME",
1067                                                 g_variant_new_uint32(item->exptime));
1068                         g_variant_builder_add(&builder, "{sv}", "DTIM",
1069                                                 g_variant_new_uint32(item->discovery_timeout));
1070                         g_variant_builder_add(&builder, "{sv}", "DRET",
1071                                                 g_variant_new_byte(item->discovery_retries));
1072                         g_variant_builder_add(&builder, "{sv}", "FLAGS",
1073                                                 g_variant_new_byte(item->flags));
1074                         g_variant_builder_close(&builder);
1075
1076                         iter = g_list_next(iter);
1077                 }
1078
1079                 mpath_data = g_variant_builder_end(&builder);
1080                 net_mesh_complete_get_mpath_info(object, invocation, mpath_data, ret);
1081
1082                 g_object_unref(mpath_data);
1083         }
1084
1085         return TRUE;
1086 }
1087
1088 static void _meshd_dbus_on_activator_bus_acquired(GDBusConnection *conn,
1089                 const gchar *name, gpointer user_data)
1090 {
1091         gboolean ret;
1092         GError *error = NULL;
1093         mesh_service *service = (mesh_service *)user_data;
1094
1095         NOTUSED(name);
1096
1097         meshd_activator_dbus_object = manager_skeleton_new();
1098         if (NULL == meshd_activator_dbus_object) {
1099                 MESH_LOGE("manager_skeleton_new() Fail");
1100                 return;
1101         }
1102
1103         g_signal_connect(meshd_activator_dbus_object, "handle-enable",
1104                         G_CALLBACK(_meshd_dbus_handle_enable), service);
1105         g_signal_connect(meshd_activator_dbus_object, "handle-disable",
1106                         G_CALLBACK(_meshd_dbus_handle_disable), service);
1107
1108         ret = g_dbus_interface_skeleton_export(
1109                                 G_DBUS_INTERFACE_SKELETON(meshd_activator_dbus_object),
1110                                 conn, MESH_DBUS_MANAGER_OBJPATH, &error);
1111         if (FALSE == ret) {
1112                 MESH_LOGE("g_dbus_interface_skeleton_export() Fail(%s)", error->message);
1113                 g_error_free(error);
1114         }
1115 }
1116
1117 static void _meshd_dbus_on_bus_acquired(GDBusConnection *conn, const gchar *name,
1118                 gpointer user_data)
1119 {
1120         gboolean ret;
1121         GError *error = NULL;
1122         mesh_service *service = (mesh_service *)user_data;
1123
1124         NOTUSED(name);
1125
1126         meshd_dbus_object = net_mesh_skeleton_new();
1127         if (NULL == meshd_dbus_object) {
1128                 MESH_LOGE("net_mesh_skeleton_new() Fail");
1129                 return;
1130         }
1131
1132         g_signal_connect(meshd_dbus_object, "handle-scan",
1133                         G_CALLBACK(_meshd_dbus_handle_scan), service);
1134         g_signal_connect(meshd_dbus_object, "handle-specific-scan",
1135                         G_CALLBACK(_meshd_dbus_handle_specific_scan), service);
1136         g_signal_connect(meshd_dbus_object, "handle-cancel-scan",
1137                         G_CALLBACK(_meshd_dbus_handle_cancel_scan), service);
1138         g_signal_connect(meshd_dbus_object, "handle-get-found-mesh-networks",
1139                         G_CALLBACK(_meshd_dbus_handle_get_found_mesh_networks), service);
1140         g_signal_connect(meshd_dbus_object, "handle-enable-mesh",
1141                         G_CALLBACK(_meshd_dbus_handle_enable_mesh), service);
1142         g_signal_connect(meshd_dbus_object, "handle-disable-mesh",
1143                         G_CALLBACK(_meshd_dbus_handle_disable_mesh), service);
1144         g_signal_connect(meshd_dbus_object, "handle-get-joined-mesh-network",
1145                         G_CALLBACK(_meshd_dbus_handle_get_joined_mesh_network), service);
1146         g_signal_connect(meshd_dbus_object, "handle-get-connected-peers",
1147                         G_CALLBACK(_meshd_dbus_handle_get_connected_peers), service);
1148         g_signal_connect(meshd_dbus_object, "handle-set-gate",
1149                         G_CALLBACK(_meshd_dbus_handle_set_gate), service);
1150         g_signal_connect(meshd_dbus_object, "handle-unset-gate",
1151                         G_CALLBACK(_meshd_dbus_handle_unset_gate), service);
1152         g_signal_connect(meshd_dbus_object, "handle-set-softap",
1153                         G_CALLBACK(_meshd_dbus_handle_set_softap), service);
1154         g_signal_connect(meshd_dbus_object, "handle-enable-softap",
1155                         G_CALLBACK(_meshd_dbus_handle_enable_softap), service);
1156         g_signal_connect(meshd_dbus_object, "handle-disable-softap",
1157                         G_CALLBACK(_meshd_dbus_handle_disable_softap), service);
1158         g_signal_connect(meshd_dbus_object, "handle-create-mesh-network",
1159                         G_CALLBACK(_meshd_dbus_handle_create_mesh_network), service);
1160         g_signal_connect(meshd_dbus_object, "handle-connect-mesh-network",
1161                         G_CALLBACK(_meshd_dbus_handle_connect_mesh_network), service);
1162         g_signal_connect(meshd_dbus_object, "handle-disconnect-mesh-network",
1163                         G_CALLBACK(_meshd_dbus_handle_disconnect_mesh_network), service);
1164         g_signal_connect(meshd_dbus_object, "handle-forget-mesh-network",
1165                         G_CALLBACK(_meshd_dbus_handle_forget_mesh_network), service);
1166         g_signal_connect(meshd_dbus_object, "handle-set-interfaces",
1167                         G_CALLBACK(_meshd_dbus_handle_set_interfaces), service);
1168         g_signal_connect(meshd_dbus_object, "handle-get-station-info",
1169                         G_CALLBACK(_meshd_dbus_handle_get_station_info), service);
1170         g_signal_connect(meshd_dbus_object, "handle-get-mpath-info",
1171                         G_CALLBACK(_meshd_dbus_handle_get_mpath_info), service);
1172
1173         ret = g_dbus_interface_skeleton_export(G_DBUS_INTERFACE_SKELETON(meshd_dbus_object),
1174                         conn, MESH_DBUS_OBJPATH, &error);
1175         if (FALSE == ret) {
1176                 MESH_LOGE("g_dbus_interface_skeleton_export() Fail(%s)", error->message);
1177                 g_error_free(error);
1178         }
1179
1180         ret = _meshd_dbus_subscribe_name_owner_changed(conn);
1181         if (MESHD_ERROR_NONE != ret) {
1182                 MESH_LOGE("_meshd_dbus_subscribe_name_owner_changed() Fail(%d)", ret);
1183                 return;
1184         }
1185 }
1186
1187 static void _meshd_dbus_on_name_lost(GDBusConnection *conn, const gchar *name,
1188                 gpointer user_data)
1189 {
1190         NOTUSED(conn);
1191         NOTUSED(user_data);
1192
1193         MESH_LOGD("Lost the name %s", name);
1194 }
1195
1196 static void _meshd_dbus_on_name_acquired(GDBusConnection *conn, const gchar *name,
1197                 gpointer user_data)
1198 {
1199         NOTUSED(conn);
1200         NOTUSED(user_data);
1201
1202         MESH_LOGD("Acquired the name %s", name);
1203 }
1204
1205 static gboolean _meshd_dbus_interface_init(mesh_service *service)
1206 {
1207         guint id;
1208         guint activation_dbus_id;
1209         meshd_check_null_ret_error("service", service, FALSE);
1210
1211         id = g_bus_own_name(G_BUS_TYPE_SYSTEM,
1212                         MESH_DBUS_INTERFACE,
1213                         G_BUS_NAME_OWNER_FLAGS_REPLACE,
1214                         _meshd_dbus_on_bus_acquired,
1215                         _meshd_dbus_on_name_acquired,
1216                         _meshd_dbus_on_name_lost,
1217                         service,
1218                         NULL);
1219         if (0 == id) {
1220                 MESH_LOGE("g_bus_own_name() Fail");
1221                 return FALSE;
1222         }
1223
1224         /* Get D-Bus owner to activate zigbee-daemon */
1225         activation_dbus_id = g_bus_own_name(G_BUS_TYPE_SYSTEM,
1226                         MESH_DBUS_INTERFACE".manager",
1227                         G_BUS_NAME_OWNER_FLAGS_REPLACE,
1228                         _meshd_dbus_on_activator_bus_acquired,
1229                         NULL,
1230                         NULL,
1231                         service,
1232                         NULL);
1233
1234         service->dbus_id = id;
1235         service->activation_dbus_id = activation_dbus_id;
1236         service->interface_info = g_new0(mesh_interface_s, 1);
1237         service->scanned_mesh_network = NULL;
1238
1239         /* Initialize DBus sendor logic */
1240         meshd_dbus_start(service);
1241
1242         return TRUE;
1243 }
1244
1245 static void _meshd_dbus_deinit(mesh_service *service)
1246 {
1247         mesh_interface_s *info = NULL;
1248         meshd_check_null_ret("service", service);
1249
1250         /* De-Initialize DBus sendor logic */
1251         meshd_dbus_stop(service);
1252
1253         g_bus_unown_name(service->dbus_id);
1254         g_bus_unown_name(service->activation_dbus_id);
1255
1256         info = service->interface_info;
1257         meshd_check_null_ret("info", info);
1258         if (info->bridge_interface)
1259                 g_free(info->bridge_interface);
1260         if (info->base_interface)
1261                 g_free(info->base_interface);
1262         if (info->mesh_interface)
1263                 g_free(info->mesh_interface);
1264         if (info->softap_interface)
1265                 g_free(info->softap_interface);
1266         if (info->external_interface)
1267                 g_free(info->external_interface);
1268
1269         if (service->joined_network) {
1270                 g_free(service->joined_network->mesh_id);
1271                 g_free(service->joined_network);
1272                 service->joined_network = NULL;
1273         }
1274         mesh_request_clear_saved_mesh_network(&service->saved_mesh_network);
1275
1276         /* Clear scan list */
1277         g_list_free_full(service->scanned_mesh_network, _on_scan_result_destroy);
1278         service->scanned_mesh_network = NULL;
1279
1280         g_free(service->interface_info);
1281         service->interface_info = NULL;
1282 }
1283
1284  /**< mesh service interface initialization */
1285 gboolean meshd_service_interface_init(mesh_service *service)
1286 {
1287         guint ret;
1288         meshd_check_null_ret_error("service", service, FALSE);
1289
1290         /* Initialize dbus interface */
1291         ret = _meshd_dbus_interface_init(service);
1292         if (FALSE == ret) {
1293                 MESH_LOGE("zigbee_service_dbus_interface_init failed!!!");
1294                 return FALSE;
1295         }
1296
1297         return TRUE;
1298 }
1299
1300 /**< Zigbee service interface de-initialization */
1301 void meshd_service_interface_deinit(mesh_service *service)
1302 {
1303         meshd_check_null_ret("service", service);
1304
1305         /* De-initialize dbus interface */
1306         _meshd_dbus_deinit(service);
1307 }