Apply changed Dbus methods
[platform/core/connectivity/wifi-mesh-manager.git] / src / mesh-service-interface.c
1 /*
2  * Network Configuration Module
3  *
4  * Copyright (c) 2017 Samsung Electronics Co., Ltd. All rights reserved.
5  *
6  * Licensed under the Apache License, Version 2.0 (the "License");
7  * you may not use this file except in compliance with the License.
8  * You may obtain a copy of the License at
9  *
10  * http://www.apache.org/licenses/LICENSE-2.0
11  *
12  * Unless required by applicable law or agreed to in writing, software
13  * distributed under the License is distributed on an "AS IS" BASIS,
14  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15  * See the License for the specific language governing permissions and
16  * limitations under the License.
17  *
18  */
19 #include <stdlib.h>
20 #include <string.h>
21
22 #include <glib.h>
23 #include <gio/gio.h>
24
25 #include "mesh.h"
26 #include "mesh-log.h"
27 #include "mesh-util.h"
28 #include "mesh-service-interface.h"
29 #include "mesh-generated-code.h"
30
31 #include "mesh-request.h"
32 #include "mesh-interface.h"
33
34 static NetMesh *meshd_dbus_object;
35
36 /* global list to care resource handle for each client */
37 static GList *meshd_dbus_client_list;
38 static GMutex meshd_dbus_client_list_mutex;
39
40 typedef struct _meshd_dbus_client_s {
41         gchar *bus_name;
42 } meshd_dbus_client_s;
43
44 NetMesh* meshd_dbus_get_object()
45 {
46         return meshd_dbus_object;
47 }
48
49 int64_t meshd_dbus_generate_signal_number()
50 {
51         static int64_t i = 0;
52
53         return i++;
54 }
55
56 static int _meshd_dbus_client_list_cleanup(GList *client_list)
57 {
58         meshd_dbus_client_s *client;
59
60         meshd_check_null_ret_error("client_list", client_list, FALSE);
61
62         client = client_list->data;
63
64         free(client->bus_name);
65         client->bus_name = NULL;
66         free(client);
67         g_list_free(client_list);
68
69         return MESHD_ERROR_NONE;
70 }
71
72 static int _meshd_dbus_client_list_compare_bus_name(const void *a, const void *b)
73 {
74         const meshd_dbus_client_s *client = a;
75
76         return g_strcmp0(client->bus_name, b);
77 }
78
79 static inline GList* _meshd_dbus_client_list_find_client(const gchar *owner)
80 {
81         return g_list_find_custom(meshd_dbus_client_list, owner,
82                         _meshd_dbus_client_list_compare_bus_name);
83 }
84
85 static void _meshd_dbus_name_owner_changed_cb(GDBusConnection *conn,
86                 const gchar *sender_name,
87                 const gchar *object_path,
88                 const gchar *interface_name,
89                 const gchar *signal_name,
90                 GVariant *parameters,
91                 gpointer user_data)
92 {
93         int ret;
94         GList *client = NULL;
95         gchar *name, *old_owner, *new_owner;
96
97         NOTUSED(conn);
98         NOTUSED(sender_name);
99         NOTUSED(object_path);
100         NOTUSED(interface_name);
101         NOTUSED(signal_name);
102         NOTUSED(user_data);
103
104         g_variant_get(parameters, "(&s&s&s)", &name, &old_owner, &new_owner);
105
106         if (0 == strlen(new_owner)) {
107                 g_mutex_lock(&meshd_dbus_client_list_mutex);
108                 client = _meshd_dbus_client_list_find_client(old_owner);
109                 if (client) { /* found bus name in our bus list */
110                         MESH_LOGD("bus(%s) stopped", old_owner);
111                         meshd_dbus_client_list = g_list_remove_link(meshd_dbus_client_list, client);
112                 }
113                 g_mutex_unlock(&meshd_dbus_client_list_mutex);
114
115                 if (client) {
116                         ret = _meshd_dbus_client_list_cleanup(client);
117                         if (MESHD_ERROR_NONE != ret)
118                                 MESH_LOGE("_meshd_dbus_client_list_cleanup() Fail(%d)", ret);
119                 }
120         }
121 }
122
123 static int _meshd_dbus_subscribe_name_owner_changed(GDBusConnection *conn)
124 {
125         unsigned int id;
126
127         id = g_dbus_connection_signal_subscribe(conn,
128                         "org.freedesktop.DBus", /* bus name */
129                         "org.freedesktop.DBus", /* interface */
130                         "NameOwnerChanged", /* member */
131                         "/org/freedesktop/DBus", /* path */
132                         NULL, /* arg0 */
133                         G_DBUS_SIGNAL_FLAGS_NONE,
134                         _meshd_dbus_name_owner_changed_cb,
135                         NULL,
136                         NULL);
137         if (0 == id) {
138                 MESH_LOGE("g_dbus_connection_signal_subscribe() Fail");
139                 return MESHD_ERROR_IO_ERROR;
140         }
141
142         return MESHD_ERROR_NONE;
143 }
144
145 static gboolean _meshd_dbus_handle_enable(NetMesh *object,
146                 GDBusMethodInvocation *invocation,
147                 gpointer user_data)
148 {
149         int ret = MESHD_ERROR_NONE;
150         mesh_service *service = (mesh_service *)user_data;
151         mesh_interface_s *info = service->interface_info;
152
153         if (service->mesh_activated) {
154                 /* Already activated */
155                 net_mesh_complete_enable(object, invocation,
156                                 MESHD_ERROR_OPERATION_FAILED);
157         } else {
158                 /* Do API response first */
159                 net_mesh_complete_enable(object, invocation, ret);
160                 service->mesh_activated = TRUE;
161         }
162
163         meshd_check_null_ret_error("info", info, FALSE);
164
165         ret = mesh_interface_initialize(service->interface_info);
166         if (MESHD_ERROR_NONE != ret) {
167                 MESH_LOGE("Failed to mesh_interface_initialize [%d]", ret);
168                 goto FINISH;
169         }
170
171         ret = mesh_request_enable_mesh_gate(info->base_interface,
172                         info->mesh_interface, info->mesh_id, info->mesh_channel);
173         if (MESHD_ERROR_NONE != ret) {
174                 MESH_LOGE("Failed to mesh_request_enable_mesh_gate [%d]", ret);
175                 goto FINISH;
176         }
177
178         ret = mesh_request_create_bridge(info->bridge_interface,
179                         info->mesh_interface, info->external_interface);
180         if (MESHD_ERROR_NONE != ret) {
181                 MESH_LOGE("Failed to mesh_request_create_bridge [%d]", ret);
182                 goto FINISH;
183         }
184 #if 0
185         ret = mesh_request_specific_scan(info->mesh_interface,
186                         info->mesh_id, info->mesh_channel);
187         if (MESHD_ERROR_NONE != ret) {
188                 MESH_LOGE("Failed to mesh_request_specific_scan [%d]", ret);
189         }
190
191         ret = mesh_dhcp_request(info->bridge_interface);
192         if (MESHD_ERROR_NONE != ret) {
193                 MESH_LOGE("Failed to mesh_dhcp_request [%d]", ret);
194         }
195 #endif
196
197 FINISH:
198         net_mesh_emit_mesh_enabled(object, ret);
199
200         return TRUE;
201 }
202
203 static gboolean _meshd_dbus_handle_disable(NetMesh *object,
204                 GDBusMethodInvocation *invocation,
205                 gpointer user_data)
206 {
207         int ret = MESHD_ERROR_NONE;
208         mesh_service *service = (mesh_service *)user_data;
209         mesh_interface_s *info = service->interface_info;
210
211         meshd_check_null_ret_error("info", info, FALSE);
212
213         if (FALSE == service->mesh_activated) {
214                 MESH_LOGD("Mesh network is not activated yet");
215                 ret = MESHD_ERROR_OPERATION_FAILED;
216                 goto FINISH;
217         }
218
219         ret = mesh_request_disable_mesh_gate(info->mesh_interface);
220         if (MESHD_ERROR_NONE != ret) {
221                 MESH_LOGE("Failed to mesh_request_disable_mesh_gate");
222                 goto FINISH;
223         }
224
225         ret = mesh_request_remove_bridge(info->bridge_interface);
226         if (MESHD_ERROR_NONE != ret) {
227                 MESH_LOGE("Failed to mesh_request_remove_bridge");
228         }
229
230 FINISH:
231         net_mesh_complete_disable(object, invocation, ret);
232
233         return TRUE;
234 }
235
236 static gboolean _meshd_dbus_handle_scan(NetMesh *object,
237                 GDBusMethodInvocation *invocation,
238                 gpointer user_data)
239 {
240         int ret = MESHD_ERROR_NONE;
241         mesh_service *service = (mesh_service *)user_data;
242         mesh_interface_s *info = service->interface_info;
243
244         meshd_check_null_ret_error("info", info, FALSE);
245
246         ret = mesh_request_scan(info->mesh_interface);
247         if (MESHD_ERROR_NONE != ret) {
248                 MESH_LOGE("Failed to mesh_request_scan");
249         }
250
251         net_mesh_complete_scan(object, invocation, ret);
252
253         return TRUE;
254 }
255
256 static gboolean _meshd_dbus_handle_specific_scan(NetMesh *object,
257                 GDBusMethodInvocation *invocation,
258                 gchar *mesh_id,
259                 gint channel,
260                 gpointer user_data)
261 {
262         int ret = MESHD_ERROR_NONE;
263         mesh_service *service = (mesh_service *)user_data;
264         mesh_interface_s *info = service->interface_info;
265
266         meshd_check_null_ret_error("info", info, FALSE);
267
268         ret = mesh_request_specific_scan(info->mesh_interface, mesh_id, channel);
269         if (MESHD_ERROR_NONE != ret) {
270                 MESH_LOGE("Failed to mesh_request_specific_scan");
271         }
272
273         net_mesh_complete_specific_scan(object, invocation, ret);
274
275         return TRUE;
276 }
277
278 static gboolean _meshd_dbus_handle_cancel_scan(NetMesh *object,
279                 GDBusMethodInvocation *invocation,
280                 gpointer user_data)
281 {
282         int ret = MESHD_ERROR_NONE;
283         mesh_service *service = (mesh_service *)user_data;
284         mesh_interface_s *info = service->interface_info;
285
286         ret = mesh_request_cancel_scan(info->mesh_interface);
287         if (MESHD_ERROR_NONE != ret) {
288                 MESH_LOGE("Failed to mesh_request_cancel_scan");
289         }
290
291         net_mesh_complete_cancel_scan(object, invocation, ret);
292
293         return TRUE;
294 }
295
296 static gboolean _meshd_dbus_handle_get_found_mesh_networks(NetMesh *object,
297                 GDBusMethodInvocation *invocation)
298 {
299         int ret = MESHD_ERROR_NONE;
300
301         GVariantBuilder builder;
302         GVariant* networks;
303
304         MESH_LOGD("Not implemented yet !");
305
306         /* TODO: Return scan results */
307
308         /*
309          * struct mesh_found_network_s {
310          * char *meshid;
311          * char *bssid;
312          * int channel;
313          * int rssi;
314          * int data_rate;
315          *};
316          */
317
318         MESH_LOGD("Not implemented yet !");
319
320         /* TODO: Get station infomation and make variant data */
321
322         g_variant_builder_init(&builder, G_VARIANT_TYPE_VARDICT);
323         g_variant_builder_add(&builder, "{sv}", "meshid", g_variant_new_string("meshnet"));
324         g_variant_builder_add(&builder, "{sv}", "bssid", g_variant_new_string("7c:dd:90:62:37:cf"));
325         g_variant_builder_add(&builder, "{sv}", "rssi", g_variant_new_uint32(-65));
326         g_variant_builder_add(&builder, "{sv}", "channel", g_variant_new_uint32(161));
327         g_variant_builder_add(&builder, "{sv}", "data_rate", g_variant_new_uint32(300));
328         g_variant_builder_add(&builder, "{sv}", "meshid", g_variant_new_string("meshnet"));
329         g_variant_builder_add(&builder, "{sv}", "bssid", g_variant_new_string("7c:dd:90:62:37:ce"));
330         g_variant_builder_add(&builder, "{sv}", "rssi", g_variant_new_uint32(-50));
331         g_variant_builder_add(&builder, "{sv}", "channel", g_variant_new_uint32(6));
332         g_variant_builder_add(&builder, "{sv}", "data_rate", g_variant_new_uint32(150));
333         networks = g_variant_builder_end(&builder);
334
335         net_mesh_complete_get_found_mesh_networks(object, invocation, networks, ret);
336
337         return TRUE;
338 }
339
340 static gboolean _meshd_dbus_handle_enable_mesh(NetMesh *object,
341                 GDBusMethodInvocation *invocation)
342 {
343         int ret = MESHD_ERROR_NONE;
344
345         MESH_LOGD("Not implemented yet !");
346
347         /* TODO: Create or join mesh network and create bridge */
348
349         net_mesh_complete_enable_mesh(object, invocation, ret);
350
351         return TRUE;
352 }
353
354 static gboolean _meshd_dbus_handle_disable_mesh(NetMesh *object,
355                 GDBusMethodInvocation *invocation)
356 {
357         int ret = MESHD_ERROR_NONE;
358
359         MESH_LOGD("Not implemented yet !");
360
361         /* TODO: Destroy bridge and return from mesh to infra mode */
362
363         net_mesh_complete_disable_mesh(object, invocation, ret);
364
365         return TRUE;
366 }
367
368 static gboolean _meshd_dbus_handle_get_joined_mesh_network(NetMesh *object,
369                 GDBusMethodInvocation *invocation)
370 {
371         int ret = MESHD_ERROR_NONE;
372
373         gchar *meshid = strdup("meshnet");
374     gchar *bssid = strdup("7c:dd:90:d8:2a:64");
375     gint channel = 161;
376     gint max_speed = 866;
377
378         MESH_LOGD("Not implemented yet !");
379         net_mesh_complete_get_joined_mesh_network(object, invocation, meshid, bssid, channel,
380                 max_speed, ret);
381
382         free(meshid);
383         free(bssid);
384
385         return TRUE;
386 }
387
388 static gboolean _meshd_dbus_handle_set_gate(NetMesh *object,
389                 GDBusMethodInvocation *invocation, gboolean stp, gint gate_announce)
390 {
391         int ret = MESHD_ERROR_NONE;
392
393         MESH_LOGD("Not implemented yet !");
394         MESH_LOGD("stp = %d", stp);
395         MESH_LOGD("gate_announce = %d", gate_announce);
396
397         /* TODO: Set stp and gate_announce */
398
399         net_mesh_complete_set_gate(object, invocation, ret);
400
401         return TRUE;
402 }
403
404 static gboolean _meshd_dbus_handle_unset_gate(NetMesh *object,
405                 GDBusMethodInvocation *invocation)
406 {
407         int ret = MESHD_ERROR_NONE;
408
409         MESH_LOGD("Not implemented yet !");
410
411         /* TODO: Check softAP interface and execute it */
412
413         net_mesh_complete_unset_gate(object, invocation, ret);
414
415         return TRUE;
416 }
417
418 static gboolean _meshd_dbus_handle_set_softap(NetMesh *object,
419                 GDBusMethodInvocation *invocation, gchar *ssid, gchar *key,
420                 gchar *mode, gint channel, gint visibility, gint max_sta, gint security)
421 {
422         int ret = MESHD_ERROR_NONE;
423
424         MESH_LOGD("Not implemented yet !");
425         MESH_LOGD("ssid = %s", ssid);
426         MESH_LOGD("key = %s", key);
427         MESH_LOGD("mode = %s", mode);
428         MESH_LOGD("channel = %d", channel);
429         MESH_LOGD("visibilty = %d", visibility);
430         MESH_LOGD("max_sta = %d", max_sta);
431         MESH_LOGD("security = %d", security);
432
433         /* TODO: Save softAP information */
434
435         net_mesh_complete_set_softap(object, invocation, ret);
436
437         return TRUE;
438 }
439
440 static gboolean _meshd_dbus_handle_enable_softap(NetMesh *object,
441                 GDBusMethodInvocation *invocation)
442 {
443         int ret = MESHD_ERROR_NONE;
444
445         MESH_LOGD("Not implemented yet !");
446
447         /* TODO: Check softAP interface and execute it */
448
449         net_mesh_complete_enable_softap(object, invocation, ret);
450
451         return TRUE;
452 }
453
454 static gboolean _meshd_dbus_handle_disable_softap(NetMesh *object,
455                 GDBusMethodInvocation *invocation)
456 {
457         int ret = MESHD_ERROR_NONE;
458
459         MESH_LOGD("Not implemented yet !");
460
461         /* TODO: Destroy softap */
462
463         net_mesh_complete_disable_softap(object, invocation, ret);
464
465         return TRUE;
466 }
467
468 static gboolean _meshd_dbus_handle_add_mesh_network(NetMesh *object,
469                 GDBusMethodInvocation *invocation,
470                 gchar *mesh_id, gint channel, gint security,
471                 gpointer user_data)
472 {
473         int ret = MESHD_ERROR_NONE;
474         mesh_service *service = (mesh_service *)user_data;
475
476         ret = mesh_request_add_mesh_network(service, mesh_id, channel, security);
477
478         net_mesh_complete_add_mesh_network(object, invocation, ret);
479
480         return TRUE;
481 }
482
483 static gboolean _meshd_dbus_handle_get_saved_mesh_network(NetMesh *object,
484                 GDBusMethodInvocation *invocation,
485                 gpointer user_data)
486 {
487         int ret = MESHD_ERROR_NONE;
488         mesh_service *service = (mesh_service *)user_data;
489
490         ret = mesh_request_get_saved_mesh_network(service);
491
492         net_mesh_complete_get_saved_mesh_network(object, invocation, ret);
493
494         return TRUE;
495 }
496
497 static gboolean _meshd_dbus_handle_select_saved_mesh_network(NetMesh *object,
498                 GDBusMethodInvocation *invocation,
499                 gchar *mesh_id, gint channel, gint security,
500                 gpointer user_data)
501 {
502         int ret = MESHD_ERROR_NONE;
503         mesh_service *service = (mesh_service *)user_data;
504
505         ret = mesh_request_select_saved_mesh_network(service, mesh_id, channel, security);
506
507         net_mesh_complete_select_saved_mesh_network(object, invocation, ret);
508
509         return TRUE;
510 }
511
512 static gboolean _meshd_dbus_handle_forget_saved_mesh_network(NetMesh *object,
513                 GDBusMethodInvocation *invocation,
514                 gchar *mesh_id, gint channel, gint security,
515                 gpointer user_data)
516 {
517         int ret = MESHD_ERROR_NONE;
518         mesh_service *service = (mesh_service *)user_data;
519
520         ret = mesh_request_forget_saved_mesh_network(service, mesh_id, channel, security);
521
522         net_mesh_complete_forget_saved_mesh_network(object, invocation, ret);
523
524         return TRUE;
525 }
526
527 static gboolean _meshd_dbus_handle_get_station_info(NetMesh *object,
528                 GDBusMethodInvocation *invocation)
529 {
530         int ret = MESHD_ERROR_NONE;
531
532         GVariantBuilder builder;
533         GVariant* station;
534
535         MESH_LOGD("Not implemented yet !");
536
537         /* TODO: Get station infomation and make variant data */
538
539         /*
540          * sh-3.2#  iw mesh0 station dump
541          * Station 7c:dd:90:62:37:cf (on mesh0)
542          * inactive time:       1685 ms
543          * rx bytes:    34174
544          * rx packets:  1181
545          * tx bytes:    6877
546          * tx packets:  76
547          * tx retries:  0
548          * tx failed:   0
549          * beacon loss: 0
550          * signal:      -64 dBm
551          * signal avg:  -63 dBm
552          * tx bitrate:  54.0 MBit/s
553          * rx bitrate:  5.5 MBit/s
554          * mesh llid:   51731
555          * mesh plid:   35432
556          * mesh plink:  ESTAB
557          * mesh local PS mode:  ACTIVE
558          * mesh peer PS mode:   ACTIVE
559          * mesh non-peer PS mode:       ACTIVE
560          * authorized:  yes
561          * authenticated:       yes
562          * associated:  yes
563          * preamble:    long
564          * WMM/WME:     yes
565          * MFP:         no
566          * TDLS peer:   no
567          * DTIM period: 0
568          * beacon interval:1000
569          * short slot time:yes
570          * connected time:      256 seconds
571          */
572         g_variant_builder_init(&builder, G_VARIANT_TYPE_VARDICT);
573         g_variant_builder_add(&builder, "{sv}", "station", g_variant_new_string("7c:dd:90:62:37:cf"));
574         g_variant_builder_add(&builder, "{sv}", "inactive_time", g_variant_new_uint32(1685));
575         g_variant_builder_add(&builder, "{sv}", "rx_bytes", g_variant_new_uint32(34174));
576         g_variant_builder_add(&builder, "{sv}", "rx_packets", g_variant_new_uint32(1181));
577         g_variant_builder_add(&builder, "{sv}", "tx_bytes", g_variant_new_uint32(6877));
578         g_variant_builder_add(&builder, "{sv}", "tx_packets", g_variant_new_uint32(76));
579         g_variant_builder_add(&builder, "{sv}", "tx_retries", g_variant_new_uint32(0));
580         g_variant_builder_add(&builder, "{sv}", "tx_failed", g_variant_new_uint32(0));
581         g_variant_builder_add(&builder, "{sv}", "beacon_loss", g_variant_new_uint32(0));
582         g_variant_builder_add(&builder, "{sv}", "signal", g_variant_new_int32(-64));
583         g_variant_builder_add(&builder, "{sv}", "signal_avg", g_variant_new_int32(-63));
584         g_variant_builder_add(&builder, "{sv}", "tx_birrate", g_variant_new_uint32(540)); /* 10 times */
585         g_variant_builder_add(&builder, "{sv}", "rx_birrate", g_variant_new_uint32(55)); /* 10 times */
586         g_variant_builder_add(&builder, "{sv}", "mesh_llid", g_variant_new_uint32(51731));
587         g_variant_builder_add(&builder, "{sv}", "mesh_plid", g_variant_new_uint32(35432));
588         g_variant_builder_add(&builder, "{sv}", "mesh_plink", g_variant_new_uint32(1)); /* 0 : DISCON, 1 : ESTAB */
589         g_variant_builder_add(&builder, "{sv}", "mesh_local_PS_mode", g_variant_new_uint32(1)); /* 0 : INACTIVE, 1 : ACTIVE */
590         g_variant_builder_add(&builder, "{sv}", "mesh_peer_PS_mode", g_variant_new_uint32(1)); /* 0 : INACTIVE, 1 : ACTIVE */
591         g_variant_builder_add(&builder, "{sv}", "mesh_none_peer_PS_mode", g_variant_new_uint32(1)); /* 0 : INACTIVE, 1 : ACTIVE */
592         g_variant_builder_add(&builder, "{sv}", "authroized", g_variant_new_boolean(TRUE));
593         g_variant_builder_add(&builder, "{sv}", "associated", g_variant_new_boolean(TRUE));
594         g_variant_builder_add(&builder, "{sv}", "preamble",g_variant_new_string("long"));
595         g_variant_builder_add(&builder, "{sv}", "WMM_WME", g_variant_new_boolean(TRUE));
596         g_variant_builder_add(&builder, "{sv}", "MFP", g_variant_new_boolean(FALSE));
597         g_variant_builder_add(&builder, "{sv}", "TDLS_peer", g_variant_new_boolean(FALSE));
598         g_variant_builder_add(&builder, "{sv}", "DTIM_period", g_variant_new_uint32(0));
599         g_variant_builder_add(&builder, "{sv}", "beacon_interval", g_variant_new_uint32(1000));
600         g_variant_builder_add(&builder, "{sv}", "short_slot_time", g_variant_new_boolean(TRUE));
601         g_variant_builder_add(&builder, "{sv}", "connected_time", g_variant_new_uint32(256));
602         station = g_variant_builder_end(&builder);
603
604         net_mesh_complete_get_station_info(object, invocation, station, ret);
605
606         g_object_unref(station);
607
608         return TRUE;
609 }
610
611 static gboolean _meshd_dbus_handle_get_mpath_info(NetMesh *object,
612                 GDBusMethodInvocation *invocation)
613 {
614         int ret = MESHD_ERROR_NONE;
615         GVariantBuilder builder;
616         GVariant* dump_data;
617
618         MESH_LOGD("Not implemented yet !");
619
620         /* TODO: Get mesh path infomation and make variant data */
621
622         // ret = _meshd_get_mpath_dump();
623
624         /*
625          * Example) sh-3.2# iw mesh0 mpath dump
626          * DEST ADDR         NEXT HOP          IFACE    SN      METRIC  QLEN    EXPTIME         DTIM    DRET    FLAGS
627          * 7c:dd:90:62:37:cf 7c:dd:90:62:37:cf mesh0    221     152             0               10                      100             0               0x5
628          */
629         g_variant_builder_init(&builder, G_VARIANT_TYPE_VARDICT);
630         g_variant_builder_add(&builder, "{sv}", "DEST_ADDR", g_variant_new_string("7c:dd:90:62:37:cf"));
631         g_variant_builder_add(&builder, "{sv}", "NEXT_HOP", g_variant_new_string("7c:dd:90:62:37:cf"));
632         g_variant_builder_add(&builder, "{sv}", "IFACE", g_variant_new_string("mesh0"));
633         g_variant_builder_add(&builder, "{sv}", "SN", g_variant_new_uint32(221));
634         g_variant_builder_add(&builder, "{sv}", "METRIC", g_variant_new_uint32(152));
635         g_variant_builder_add(&builder, "{sv}", "QLEN", g_variant_new_uint32(0));
636         g_variant_builder_add(&builder, "{sv}", "EXPTIME", g_variant_new_uint32(10));
637         g_variant_builder_add(&builder, "{sv}", "DTIM", g_variant_new_uint32(100));
638         g_variant_builder_add(&builder, "{sv}", "DRET", g_variant_new_uint32(0));
639         g_variant_builder_add(&builder, "{sv}", "FLAGS", g_variant_new_uint32(0x05));
640
641         g_variant_builder_add(&builder, "{sv}", "DEST_ADDR", g_variant_new_string("7c:dd:90:63:21:34"));
642         g_variant_builder_add(&builder, "{sv}", "NEXT_HOP", g_variant_new_string("7c:dd:90:62:37:cf"));
643         g_variant_builder_add(&builder, "{sv}", "IFACE", g_variant_new_string("mesh0"));
644         g_variant_builder_add(&builder, "{sv}", "SN", g_variant_new_uint32(221));
645         g_variant_builder_add(&builder, "{sv}", "METRIC", g_variant_new_uint32(152));
646         g_variant_builder_add(&builder, "{sv}", "QLEN", g_variant_new_uint32(0));
647         g_variant_builder_add(&builder, "{sv}", "EXPTIME", g_variant_new_uint32(10));
648         g_variant_builder_add(&builder, "{sv}", "DTIM", g_variant_new_uint32(100));
649         g_variant_builder_add(&builder, "{sv}", "DRET", g_variant_new_uint32(0));
650         g_variant_builder_add(&builder, "{sv}", "FLAGS", g_variant_new_uint32(0x05));
651         dump_data = g_variant_builder_end(&builder);
652
653         net_mesh_complete_get_mpath_info(object, invocation, dump_data, ret);
654
655         g_object_unref(dump_data);
656
657         return TRUE;
658 }
659
660 static void _meshd_dbus_on_bus_acquired(GDBusConnection *conn, const gchar *name,
661                 gpointer user_data)
662 {
663         gboolean ret;
664         GError *error = NULL;
665         mesh_service *service = (mesh_service *)user_data;
666
667         NOTUSED(name);
668
669         meshd_dbus_object = net_mesh_skeleton_new();
670         if (NULL == meshd_dbus_object) {
671                 MESH_LOGE("net_mesh_skeleton_new() Fail");
672                 return;
673         }
674
675         g_signal_connect(meshd_dbus_object, "handle-enable",
676                         G_CALLBACK(_meshd_dbus_handle_enable), service);
677         g_signal_connect(meshd_dbus_object, "handle-disable",
678                         G_CALLBACK(_meshd_dbus_handle_disable), service);
679         g_signal_connect(meshd_dbus_object, "handle-scan",
680                         G_CALLBACK(_meshd_dbus_handle_scan), service);
681         g_signal_connect(meshd_dbus_object, "handle-specific-scan",
682                         G_CALLBACK(_meshd_dbus_handle_specific_scan), service);
683         g_signal_connect(meshd_dbus_object, "handle-cancel-scan",
684                         G_CALLBACK(_meshd_dbus_handle_cancel_scan), service);
685         g_signal_connect(meshd_dbus_object, "handle-get-found-mesh-networks",
686                         G_CALLBACK(_meshd_dbus_handle_get_found_mesh_networks), service);
687         g_signal_connect(meshd_dbus_object, "handle-enable-mesh",
688                         G_CALLBACK(_meshd_dbus_handle_enable_mesh), service);
689         g_signal_connect(meshd_dbus_object, "handle-disable-mesh",
690                         G_CALLBACK(_meshd_dbus_handle_disable_mesh), service);
691         g_signal_connect(meshd_dbus_object, "handle-get-joined-mesh-network",
692                         G_CALLBACK(_meshd_dbus_handle_get_joined_mesh_network), service);
693         g_signal_connect(meshd_dbus_object, "handle-set-gate",
694                         G_CALLBACK(_meshd_dbus_handle_set_gate), service);
695         g_signal_connect(meshd_dbus_object, "handle-unset-mesh",
696                         G_CALLBACK(_meshd_dbus_handle_unset_gate), service);
697         g_signal_connect(meshd_dbus_object, "handle-set-softap",
698                         G_CALLBACK(_meshd_dbus_handle_set_softap), service);
699         g_signal_connect(meshd_dbus_object, "handle-enable-softap",
700                         G_CALLBACK(_meshd_dbus_handle_enable_softap), service);
701         g_signal_connect(meshd_dbus_object, "handle-disable-softap",
702                         G_CALLBACK(_meshd_dbus_handle_disable_softap), service);
703         g_signal_connect(meshd_dbus_object, "handle-add-mesh-network",
704                         G_CALLBACK(_meshd_dbus_handle_add_mesh_network), service);
705         g_signal_connect(meshd_dbus_object, "handle-get-saved-mesh-network",
706                         G_CALLBACK(_meshd_dbus_handle_get_saved_mesh_network), service);
707         g_signal_connect(meshd_dbus_object, "handle-select-saved-mesh-network",
708                         G_CALLBACK(_meshd_dbus_handle_select_saved_mesh_network), service);
709         g_signal_connect(meshd_dbus_object, "handle-forget-saved-mesh-network",
710                         G_CALLBACK(_meshd_dbus_handle_forget_saved_mesh_network), service);
711         g_signal_connect(meshd_dbus_object, "handle-get-station-info",
712                         G_CALLBACK(_meshd_dbus_handle_get_station_info), service);
713         g_signal_connect(meshd_dbus_object, "handle-get-mpath-info",
714                         G_CALLBACK(_meshd_dbus_handle_get_mpath_info), service);
715
716         ret = g_dbus_interface_skeleton_export(G_DBUS_INTERFACE_SKELETON(meshd_dbus_object),
717                         conn, MESH_DBUS_OBJPATH, &error);
718         if (FALSE == ret) {
719                 MESH_LOGE("g_dbus_interface_skeleton_export() Fail(%s)", error->message);
720                 g_error_free(error);
721         }
722
723         ret = _meshd_dbus_subscribe_name_owner_changed(conn);
724         if (MESHD_ERROR_NONE != ret) {
725                 MESH_LOGE("_meshd_dbus_subscribe_name_owner_changed() Fail(%d)", ret);
726                 return;
727         }
728 }
729
730 static void _meshd_dbus_on_name_lost(GDBusConnection *conn, const gchar *name,
731                 gpointer user_data)
732 {
733         NOTUSED(conn);
734         NOTUSED(user_data);
735
736         MESH_LOGD("Lost the name %s", name);
737 }
738
739 static void _meshd_dbus_on_name_acquired(GDBusConnection *conn, const gchar *name,
740                 gpointer user_data)
741 {
742         NOTUSED(conn);
743         NOTUSED(user_data);
744
745         MESH_LOGD("Acquired the name %s", name);
746 }
747
748 static gboolean _meshd_dbus_interface_init(mesh_service *service)
749 {
750         guint id;
751         meshd_check_null_ret_error("service", service, FALSE);
752
753         id = g_bus_own_name(G_BUS_TYPE_SYSTEM,
754                         MESH_DBUS_INTERFACE,
755                         G_BUS_NAME_OWNER_FLAGS_REPLACE,
756                         _meshd_dbus_on_bus_acquired,
757                         _meshd_dbus_on_name_acquired,
758                         _meshd_dbus_on_name_lost,
759                         service,
760                         NULL);
761         if (0 == id) {
762                 MESH_LOGE("g_bus_own_name() Fail");
763                 return FALSE;
764         }
765
766         service->dbus_id = id;
767         service->interface_info = g_new0(mesh_interface_s, 1);
768
769         return TRUE;
770 }
771
772 static void _meshd_dbus_deinit(mesh_service *service)
773 {
774         mesh_interface_s *info = NULL;
775         meshd_check_null_ret("service", service);
776
777         g_bus_unown_name(service->dbus_id);
778
779         info = service->interface_info;
780         meshd_check_null_ret("info", info);
781         if (info->bridge_interface)
782                 g_free(info->bridge_interface);
783         if (info->base_interface)
784                 g_free(info->base_interface);
785         if (info->mesh_interface)
786                 g_free(info->mesh_interface);
787         if (info->softap_interface)
788                 g_free(info->softap_interface);
789         if (info->external_interface)
790                 g_free(info->external_interface);
791
792         g_free(service->interface_info);
793         service->interface_info = NULL;
794 }
795
796  /**< mesh service interface initialization */
797 gboolean meshd_service_interface_init(mesh_service *service)
798 {
799         guint ret;
800         meshd_check_null_ret_error("service", service, FALSE);
801
802         /* Initialize dbus interface */
803         ret = _meshd_dbus_interface_init(service);
804         if (FALSE == ret) {
805                 MESH_LOGE("zigbee_service_dbus_interface_init failed!!!");
806                 return FALSE;
807         }
808
809         return TRUE;
810 }
811
812 /**< Zigbee service interface de-initialization */
813 void meshd_service_interface_deinit(mesh_service *service)
814 {
815         meshd_check_null_ret("service", service);
816
817         /* De-initialize dbus interface */
818         _meshd_dbus_deinit(service);
819 }