2 * Network Configuration Module
4 * Copyright (c) 2017 Samsung Electronics Co., Ltd. All rights reserved.
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
10 * http://www.apache.org/licenses/LICENSE-2.0
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.
27 #include "mesh-util.h"
28 #include "mesh-service.h"
29 #include "mesh-service-interface.h"
30 #include "mesh-generated-code.h"
32 #include "mesh-request.h"
33 #include "mesh-interface.h"
35 static NetMesh *meshd_dbus_object;
36 static Manager *meshd_activator_dbus_object;
38 /* global list to care resource handle for each client */
39 static GList *meshd_dbus_client_list;
40 static GMutex meshd_dbus_client_list_mutex;
42 typedef struct _meshd_dbus_client_s {
44 } meshd_dbus_client_s;
46 NetMesh* meshd_dbus_get_object()
48 return meshd_dbus_object;
51 int64_t meshd_dbus_generate_signal_number()
58 static int _meshd_dbus_client_list_cleanup(GList *client_list)
60 meshd_dbus_client_s *client;
62 meshd_check_null_ret_error("client_list", client_list, FALSE);
64 client = client_list->data;
66 free(client->bus_name);
67 client->bus_name = NULL;
69 g_list_free(client_list);
71 return MESHD_ERROR_NONE;
74 static int _meshd_dbus_client_list_compare_bus_name(const void *a, const void *b)
76 const meshd_dbus_client_s *client = a;
78 return g_strcmp0(client->bus_name, b);
81 static inline GList* _meshd_dbus_client_list_find_client(const gchar *owner)
83 return g_list_find_custom(meshd_dbus_client_list, owner,
84 _meshd_dbus_client_list_compare_bus_name);
87 static void _meshd_dbus_name_owner_changed_cb(GDBusConnection *conn,
88 const gchar *sender_name,
89 const gchar *object_path,
90 const gchar *interface_name,
91 const gchar *signal_name,
97 gchar *name, *old_owner, *new_owner;
100 NOTUSED(sender_name);
101 NOTUSED(object_path);
102 NOTUSED(interface_name);
103 NOTUSED(signal_name);
106 g_variant_get(parameters, "(&s&s&s)", &name, &old_owner, &new_owner);
108 if (0 == strlen(new_owner)) {
109 g_mutex_lock(&meshd_dbus_client_list_mutex);
110 client = _meshd_dbus_client_list_find_client(old_owner);
111 if (client) { /* found bus name in our bus list */
112 MESH_LOGD("bus(%s) stopped", old_owner);
113 meshd_dbus_client_list = g_list_remove_link(meshd_dbus_client_list, client);
115 g_mutex_unlock(&meshd_dbus_client_list_mutex);
118 ret = _meshd_dbus_client_list_cleanup(client);
119 if (MESHD_ERROR_NONE != ret)
120 MESH_LOGE("_meshd_dbus_client_list_cleanup() Fail(%d)", ret);
125 static int _meshd_dbus_subscribe_name_owner_changed(GDBusConnection *conn)
129 id = g_dbus_connection_signal_subscribe(conn,
130 "org.freedesktop.DBus", /* bus name */
131 "org.freedesktop.DBus", /* interface */
132 "NameOwnerChanged", /* member */
133 "/org/freedesktop/DBus", /* path */
135 G_DBUS_SIGNAL_FLAGS_NONE,
136 _meshd_dbus_name_owner_changed_cb,
140 MESH_LOGE("g_dbus_connection_signal_subscribe() Fail");
141 return MESHD_ERROR_IO_ERROR;
144 return MESHD_ERROR_NONE;
147 static gboolean _meshd_dbus_handle_enable(Manager *object,
148 GDBusMethodInvocation *invocation,
151 int ret = MESHD_ERROR_NONE;
152 mesh_service *service = (mesh_service *)user_data;
153 mesh_interface_s *info = service->interface_info;
155 if (service->mesh_activated) {
156 /* Already activated */
157 manager_complete_enable(object, invocation,
158 MESHD_ERROR_OPERATION_FAILED);
160 /* Do API response first */
161 manager_complete_enable(object, invocation, ret);
162 service->mesh_activated = TRUE;
165 meshd_check_null_ret_error("info", info, FALSE);
167 /* Register event handler first */
168 ret = mesh_request_register_event_handler();
169 if (MESHD_ERROR_NONE != ret) {
170 MESH_LOGE("Failed to register mesh event handler !! [%d]", ret);
173 ret = mesh_interface_initialize(service->interface_info);
174 if (MESHD_ERROR_NONE != ret) {
175 MESH_LOGE("Failed to mesh_interface_initialize [%d]", ret);
179 ret = mesh_request_load_saved_mesh_network(&service->saved_mesh_network);
180 if (MESHD_ERROR_NONE != ret) {
181 MESH_LOGE("Failed to mesh_request_load_saved_mesh_network [%d]", ret);
186 net_mesh_emit_mesh_enabled(meshd_dbus_get_object(), ret);
191 static gboolean _meshd_dbus_handle_disable(Manager *object,
192 GDBusMethodInvocation *invocation,
195 int ret = MESHD_ERROR_NONE;
196 mesh_service *service = (mesh_service *)user_data;
197 mesh_interface_s *info = service->interface_info;
199 meshd_check_null_ret_error("info", info, FALSE);
201 /* Make response first */
202 manager_complete_disable(object, invocation, ret);
204 ret = mesh_request_unregister_event_handler();
205 if (MESHD_ERROR_NONE != ret) {
206 MESH_LOGE("Failed to unregister mesh event handler !! [%d]", ret);
209 /* Terminate daemon */
210 meshd_service_exit(service);
215 static gboolean _meshd_dbus_handle_scan(NetMesh *object,
216 GDBusMethodInvocation *invocation,
219 int ret = MESHD_ERROR_NONE;
220 mesh_service *service = (mesh_service *)user_data;
221 mesh_interface_s *info = service->interface_info;
223 meshd_check_null_ret_error("info", info, FALSE);
225 ret = mesh_request_scan(info->mesh_interface);
226 if (MESHD_ERROR_NONE != ret) {
227 MESH_LOGE("Failed to mesh_request_scan on mesh interface[%s] !",
228 info->mesh_interface);
232 if (MESHD_ERROR_IN_PROGRESS != ret) {
233 ret = mesh_request_scan(info->base_interface);
234 if (MESHD_ERROR_NONE != ret)
235 MESH_LOGE("Failed to mesh_request_scan on base interface[%s] !",
236 info->base_interface);
239 net_mesh_complete_scan(object, invocation, ret);
244 static gboolean _meshd_dbus_handle_specific_scan(NetMesh *object,
245 GDBusMethodInvocation *invocation,
250 int ret = MESHD_ERROR_NONE;
251 mesh_service *service = (mesh_service *)user_data;
252 mesh_interface_s *info = service->interface_info;
254 meshd_check_null_ret_error("info", info, FALSE);
256 ret = mesh_request_specific_scan(info->mesh_interface, mesh_id, channel);
257 if (MESHD_ERROR_NONE != ret) {
258 MESH_LOGE("Failed to mesh_request_specific_scan on mesh interface[%s]",
259 info->mesh_interface);
263 if (MESHD_ERROR_IN_PROGRESS != ret) {
264 ret = mesh_request_specific_scan(info->base_interface, mesh_id, channel);
265 if (MESHD_ERROR_NONE != ret)
266 MESH_LOGE("Failed to mesh_request_specific_scan on base interface[%s]",
267 info->base_interface);
270 net_mesh_complete_specific_scan(object, invocation, ret);
275 static gboolean _meshd_dbus_handle_cancel_scan(NetMesh *object,
276 GDBusMethodInvocation *invocation,
279 int ret = MESHD_ERROR_NONE;
280 mesh_service *service = (mesh_service *)user_data;
281 mesh_interface_s *info = service->interface_info;
283 ret = mesh_request_cancel_scan(info->mesh_interface);
284 if (MESHD_ERROR_NONE != ret) {
285 MESH_LOGE("Failed to mesh_request_cancel_scan");
288 net_mesh_complete_cancel_scan(object, invocation, ret);
293 static void _on_scan_result_destroy(gpointer data)
295 mesh_scan_result_s *scan_item = (mesh_scan_result_s *)data;
298 g_free(scan_item->mesh_id);
299 g_free(scan_item->bssid);
303 static void _on_station_list_destroy(gpointer data)
305 mesh_station_info_s *info = (mesh_station_info_s*)data;
313 static void _on_mpath_list_destroy(gpointer data)
315 mesh_mpath_info_s *info = (mesh_mpath_info_s*)data;
318 g_free(info->dest_addr);
319 g_free(info->next_hop);
320 g_free(info->interface);
325 static gboolean _meshd_dbus_handle_get_found_mesh_networks(NetMesh *object,
326 GDBusMethodInvocation *invocation,
329 int ret = MESHD_ERROR_NONE;
330 mesh_service *service = (mesh_service *)user_data;
331 mesh_interface_s *info = service->interface_info;
333 GVariantBuilder builder;
336 mesh_scan_result_s *scan_item = NULL;
338 MESH_LOGD("Request to get scanned mesh network list");
340 ret = mesh_request_get_scan_result(info->mesh_interface, &service->scanned_mesh_network);
341 if (MESHD_ERROR_NONE != ret) {
342 MESH_LOGE("Failed to mesh_request_get_scan_result");
345 ret = mesh_request_get_scan_result(info->base_interface,
346 &service->scanned_mesh_network);
347 if (MESHD_ERROR_NONE != ret) {
348 MESH_LOGE("Failed to mesh_request_get_scan_result on base interface[%s]",
349 info->base_interface);
351 g_dbus_method_invocation_return_error(invocation,
352 G_DBUS_ERROR, G_DBUS_ERROR_FAILED, "Request Failed");
356 g_variant_builder_init(&builder, G_VARIANT_TYPE("aa{sv}"));
358 iter = service->scanned_mesh_network;
359 while (iter != NULL) {
360 scan_item = (mesh_scan_result_s*)iter->data;
362 g_variant_builder_open(&builder, G_VARIANT_TYPE_VARDICT);
363 g_variant_builder_add(&builder, "{sv}", "mesh_id",
364 g_variant_new_string(scan_item->mesh_id));
365 g_variant_builder_add(&builder, "{sv}", "bssid",
366 g_variant_new_string(scan_item->bssid));
367 g_variant_builder_add(&builder, "{sv}", "rssi",
368 g_variant_new_int32(scan_item->rssi));
369 g_variant_builder_add(&builder, "{sv}", "channel",
370 g_variant_new_uint32(scan_item->channel));
371 g_variant_builder_close(&builder);
373 iter = g_list_next(iter);
376 /* Clear scan list */
377 g_list_free_full(service->scanned_mesh_network, _on_scan_result_destroy);
378 service->scanned_mesh_network = NULL;
380 networks = g_variant_builder_end(&builder);
381 net_mesh_complete_get_found_mesh_networks(object, invocation, networks, ret);
386 static gboolean _meshd_dbus_handle_enable_mesh(NetMesh *object,
387 GDBusMethodInvocation *invocation,
390 int ret = MESHD_ERROR_NONE;
391 mesh_service *service = (mesh_service *)user_data;
392 mesh_interface_s *info = service->interface_info;
394 /* Create or join mesh network and create bridge */
395 ret = mesh_request_enable_mesh(info->base_interface, info->mesh_interface,
396 service->saved_mesh_network, &service->joined_network);
397 if (MESHD_ERROR_NONE != ret) {
398 MESH_LOGE("Failed to mesh_request_enable_mesh [%d]", ret);
402 ret = mesh_request_create_bridge(info->bridge_interface, info->mesh_interface);
403 if (MESHD_ERROR_NONE != ret) {
404 MESH_LOGE("Failed to mesh_request_create_bridge [%d]", ret);
408 /* Detect external network state (i.e. Ethernet)
409 and decide to make gate enabled */
410 ret = mesh_request_set_mesh_gate(info->bridge_interface,
411 info->mesh_interface, info->external_interface);
412 if (MESHD_ERROR_NONE != ret) {
413 MESH_LOGE("Failed to mesh_request_set_mesh_gate [%d]", ret);
417 /* TODO: Check if specific scan is required */
418 ret = mesh_request_specific_scan(info->mesh_interface,
419 info->mesh_id, info->mesh_channel);
420 if (MESHD_ERROR_NONE != ret) {
421 MESH_LOGE("Failed to mesh_request_specific_scan [%d]", ret);
423 ret = mesh_request_get_scan_result(info->mesh_interface,
424 &service->scanned_mesh_network);
427 /* Request DHCP on bridge interface */
428 ret = mesh_request_dhcp(info->bridge_interface);
429 if (MESHD_ERROR_NONE != ret) {
430 MESH_LOGE("Failed to mesh_request_dhcp [%d]", ret);
433 /* TODO: Notify bridge status to Connman */
436 net_mesh_complete_enable_mesh(object, invocation, ret);
441 static gboolean _meshd_dbus_handle_disable_mesh(NetMesh *object,
442 GDBusMethodInvocation *invocation,
445 int ret = MESHD_ERROR_NONE;
446 mesh_service *service = (mesh_service *)user_data;
447 mesh_interface_s *info = service->interface_info;
449 meshd_check_null_ret_error("info", info, FALSE);
451 /* Destroy bridge and return from mesh to infra mode */
452 if (service->joined_network) {
453 g_free(service->joined_network->mesh_id);
454 g_free(service->joined_network);
455 service->joined_network = NULL;
458 if (FALSE == service->mesh_activated) {
459 MESH_LOGD("Mesh network is not activated yet");
460 ret = MESHD_ERROR_OPERATION_FAILED;
461 net_mesh_complete_disable_mesh(object, invocation, ret);
465 /* If DHCP is on progress, stop it */
466 ret = mesh_request_stop_dhcp();
467 if (MESHD_ERROR_NONE != ret) {
468 MESH_LOGE("Failed to stop DHCP request !");
471 ret = mesh_request_disable_mesh(info->mesh_interface);
472 if (MESHD_ERROR_NONE != ret) {
473 MESH_LOGE("Failed to mesh_request_disable_mesh_gate");
476 ret = mesh_request_remove_bridge(info->bridge_interface);
477 if (MESHD_ERROR_NONE != ret) {
478 MESH_LOGE("Failed to mesh_request_remove_bridge");
482 net_mesh_complete_disable_mesh(object, invocation, ret);
484 /* Make notification */
485 mesh_notify_left_network();
490 static gboolean _meshd_dbus_handle_get_joined_mesh_network(NetMesh *object,
491 GDBusMethodInvocation *invocation,
494 int ret = MESHD_ERROR_NONE;
495 mesh_service *service = (mesh_service *)user_data;
496 mesh_network_info_s *joined = service->joined_network;
498 //gchar *meshid = strdup("meshnet");
499 //gchar *bssid = strdup("7c:dd:90:d8:2a:64");
500 //gint channel = 161;
501 //gint max_speed = 866;
504 net_mesh_complete_get_joined_mesh_network(object, invocation,
505 joined->mesh_id, joined->bssid, joined->channel, ret);
507 net_mesh_complete_get_joined_mesh_network(object, invocation,
508 "", "", 0, MESHD_ERROR_NO_DATA);
514 static gboolean _meshd_dbus_handle_set_gate(NetMesh *object,
515 GDBusMethodInvocation *invocation, gboolean stp, gboolean gate_announce,
518 int ret = MESHD_ERROR_NONE;
519 mesh_service *service = (mesh_service *)user_data;
520 mesh_interface_s *info = service->interface_info;
522 MESH_LOGD("STP = %d", stp);
523 MESH_LOGD("gate_announce = %d", gate_announce);
525 /* Set STP and gate_announce */
526 ret = mesh_request_set_mesh_gate(info->bridge_interface,
527 info->mesh_interface, info->external_interface);
528 if (MESHD_ERROR_NONE != ret) {
529 MESH_LOGE("Failed to mesh_request_set_mesh_gate [%d]", ret);
532 net_mesh_complete_set_gate(object, invocation, ret);
537 static gboolean _meshd_dbus_handle_unset_gate(NetMesh *object,
538 GDBusMethodInvocation *invocation,
541 int ret = MESHD_ERROR_NONE;
542 mesh_service *service = (mesh_service *)user_data;
543 mesh_interface_s *info = service->interface_info;
545 ret = mesh_request_unset_mesh_gate(info->bridge_interface,
546 info->mesh_interface, info->external_interface);
547 if (MESHD_ERROR_NONE != ret) {
548 MESH_LOGE("Failed to mesh_request_unset_mesh_gate [%d]", ret);
550 net_mesh_complete_unset_gate(object, invocation, ret);
555 static gboolean _meshd_dbus_handle_set_softap(NetMesh *object,
556 GDBusMethodInvocation *invocation,
557 gchar *ssid, gchar *passphrase,
558 gchar *mode, gint channel, gint visibility, gint max_sta,
559 gint security, gpointer user_data)
561 int ret = MESHD_ERROR_NONE;
562 mesh_service *service = (mesh_service *)user_data;
563 mesh_interface_s *info = service->interface_info;
565 MESH_LOGD("SSID : %s", ssid);
566 MESH_LOGD("mode : %s", mode);
567 MESH_LOGD("channel : %d", channel);
568 MESH_LOGD("visibility: %d", visibility);
569 MESH_LOGD("max_sta : %d", max_sta);
570 MESH_LOGD("security : %d", security);
572 /* Save softAP information */
573 ret = mesh_request_set_softap_config(info->softap_interface,
574 ssid, mode, channel, visibility, max_sta,
575 security, passphrase);
576 if (MESHD_ERROR_NONE != ret) {
577 MESH_LOGE("Failed to mesh_request_set_softap_config [%d]", ret);
580 net_mesh_complete_set_softap(object, invocation, ret);
585 static gboolean _meshd_dbus_handle_enable_softap(NetMesh *object,
586 GDBusMethodInvocation *invocation, gpointer user_data)
588 int ret = MESHD_ERROR_NONE;
589 mesh_service *service = (mesh_service *)user_data;
590 mesh_interface_s *info = service->interface_info;
592 /* Check softAP interface and execute it */
593 ret = mesh_request_enable_softap(info->bridge_interface, info->softap_interface);
594 if (MESHD_ERROR_NONE != ret) {
595 MESH_LOGE("Failed to mesh_request_enable_softap [%d]", ret);
598 net_mesh_complete_enable_softap(object, invocation, ret);
603 static gboolean _meshd_dbus_handle_disable_softap(NetMesh *object,
604 GDBusMethodInvocation *invocation, gpointer user_data)
606 int ret = MESHD_ERROR_NONE;
607 mesh_service *service = (mesh_service *)user_data;
608 mesh_interface_s *info = service->interface_info;
611 ret = mesh_request_disable_softap(info->bridge_interface, info->softap_interface);
612 if (MESHD_ERROR_NONE != ret) {
613 MESH_LOGE("Failed to mesh_request_disable_softap [%d]", ret);
616 net_mesh_complete_disable_softap(object, invocation, ret);
621 static gboolean _meshd_dbus_handle_add_mesh_network(NetMesh *object,
622 GDBusMethodInvocation *invocation,
623 gchar *mesh_id, gint channel, gint security,
626 int ret = MESHD_ERROR_NONE;
627 mesh_service *service = (mesh_service *)user_data;
629 ret = mesh_request_add_mesh_network(&service->saved_mesh_network,
630 mesh_id, channel, security);
632 net_mesh_complete_add_mesh_network(object, invocation, ret);
637 static gboolean _meshd_dbus_handle_get_saved_mesh_network(NetMesh *object,
638 GDBusMethodInvocation *invocation,
641 int ret = MESHD_ERROR_NONE;
642 mesh_service *service = (mesh_service *)user_data;
644 GVariantBuilder builder;
648 ret = mesh_request_get_saved_mesh_network(&service->saved_mesh_network);
649 if (MESHD_ERROR_NONE != ret) {
650 MESH_LOGE("Failed to mesh_request_get_saved_mesh_network");
652 g_dbus_method_invocation_return_error(invocation,
653 G_DBUS_ERROR, G_DBUS_ERROR_FAILED, "Request Failed");
655 /* TODO: Get station information and make variant data */
656 g_variant_builder_init(&builder, G_VARIANT_TYPE("aa{sv}"));
658 iter = service->saved_mesh_network;
659 while (iter != NULL) {
660 mesh_network_info_s *item = (mesh_network_info_s*)iter->data;
662 g_variant_builder_open(&builder, G_VARIANT_TYPE_VARDICT);
663 g_variant_builder_add(&builder, "{sv}", "mesh_id",
664 g_variant_new_string(item->mesh_id));
665 g_variant_builder_add(&builder, "{sv}", "channel",
666 g_variant_new_uint32(item->channel));
667 g_variant_builder_add(&builder, "{sv}", "security",
668 g_variant_new_uint32(item->security));
669 g_variant_builder_close(&builder);
671 iter = g_list_next(iter);
674 networks = g_variant_builder_end(&builder);
675 net_mesh_complete_get_saved_mesh_network(object, invocation, networks, ret);
681 static gboolean _meshd_dbus_handle_select_saved_mesh_network(NetMesh *object,
682 GDBusMethodInvocation *invocation,
683 gchar *mesh_id, gint channel, gint security,
686 int ret = MESHD_ERROR_NONE;
687 mesh_service *service = (mesh_service *)user_data;
689 ret = mesh_request_select_saved_mesh_network(&service->saved_mesh_network,
690 mesh_id, channel, security);
692 net_mesh_complete_select_saved_mesh_network(object, invocation, ret);
697 static gboolean _meshd_dbus_handle_forget_saved_mesh_network(NetMesh *object,
698 GDBusMethodInvocation *invocation,
699 gchar *mesh_id, gint channel, gint security,
702 int ret = MESHD_ERROR_NONE;
703 mesh_service *service = (mesh_service *)user_data;
705 ret = mesh_request_forget_saved_mesh_network(&service->saved_mesh_network,
706 mesh_id, channel, security);
708 net_mesh_complete_forget_saved_mesh_network(object, invocation, ret);
713 static gboolean _meshd_dbus_handle_set_interfaces(NetMesh *object,
714 GDBusMethodInvocation *invocation,
715 gchar *mesh, gchar *gate, gchar *softap,
718 int ret = MESHD_ERROR_NONE;
719 mesh_service *service = (mesh_service *)user_data;
720 mesh_interface_s *info = service->interface_info;
722 g_free(info->mesh_interface);
723 info->mesh_interface = g_strdup(mesh);
725 g_free(info->external_interface);
726 info->external_interface = g_strdup(gate);
728 g_free(info->softap_interface);
729 info->softap_interface = g_strdup(softap);
731 MESH_LOGD("Interface configuration for mesh network :");
732 MESH_LOGD(" Base : [%s]", info->base_interface);
733 MESH_LOGD(" Mesh : [%s]", info->mesh_interface);
734 MESH_LOGD(" Bridge : [%s]", info->bridge_interface);
735 MESH_LOGD(" SoftAP : [%s]", info->softap_interface);
736 MESH_LOGD(" External: [%s]", info->external_interface);
738 net_mesh_complete_set_interfaces(object, invocation, ret);
743 static gboolean _meshd_dbus_handle_get_station_info(NetMesh *object,
744 GDBusMethodInvocation *invocation,
747 int ret = MESHD_ERROR_NONE;
749 GVariantBuilder builder;
753 mesh_service *service = (mesh_service *)user_data;
754 mesh_interface_s *info = service->interface_info;
756 /* Clear mesh station list */
757 g_list_free_full(service->station_list, _on_station_list_destroy);
758 service->station_list = NULL;
760 ret = mesh_request_get_station_info(
761 info->mesh_interface, &service->station_list);
762 if (MESHD_ERROR_NONE != ret) {
763 MESH_LOGE("Failed to mesh_request_get_station_info");
765 g_dbus_method_invocation_return_error(invocation,
766 G_DBUS_ERROR, G_DBUS_ERROR_FAILED, "Request Failed");
769 * sh-3.2# iw mesh0 station dump
770 * Station 7c:dd:90:62:37:cf (on mesh0)
771 * inactive time: 1685 ms
780 * signal avg: -63 dBm
781 * tx bitrate: 54.0 MBit/s
782 * rx bitrate: 5.5 MBit/s
786 * mesh local PS mode: ACTIVE
787 * mesh peer PS mode: ACTIVE
788 * mesh non-peer PS mode: ACTIVE
797 * beacon interval:1000
798 * short slot time:yes
799 * connected time: 256 seconds
801 /* Get station information and make variant data */
802 g_variant_builder_init(&builder, G_VARIANT_TYPE("aa{sv}"));
804 iter = service->station_list;
805 while (iter != NULL) {
806 mesh_station_info_s *item = (mesh_station_info_s*)iter->data;
808 g_variant_builder_open(&builder, G_VARIANT_TYPE_VARDICT);
809 g_variant_builder_add(&builder, "{sv}", "bssid",
810 g_variant_new_string(item->bssid));
811 g_variant_builder_add(&builder, "{sv}", "inactive_time",
812 g_variant_new_uint32(item->inactive_time));
813 g_variant_builder_add(&builder, "{sv}", "rx_bytes",
814 g_variant_new_uint64(item->rx_bytes));
815 g_variant_builder_add(&builder, "{sv}", "rx_packets",
816 g_variant_new_uint32(item->rx_packets));
817 g_variant_builder_add(&builder, "{sv}", "tx_bytes",
818 g_variant_new_uint64(item->tx_bytes));
819 g_variant_builder_add(&builder, "{sv}", "tx_packets",
820 g_variant_new_uint32(item->tx_packets));
821 g_variant_builder_add(&builder, "{sv}", "tx_retries",
822 g_variant_new_uint32(item->tx_retries));
823 g_variant_builder_add(&builder, "{sv}", "tx_failed",
824 g_variant_new_uint32(item->tx_failed));
825 g_variant_builder_add(&builder, "{sv}", "beacon_loss",
826 g_variant_new_uint32(item->beacon_loss));
827 g_variant_builder_add(&builder, "{sv}", "beacon_rx",
828 g_variant_new_uint64(item->beacon_rx));
829 g_variant_builder_add(&builder, "{sv}", "rx_drop_misc",
830 g_variant_new_uint64(item->rx_drop_misc));
831 g_variant_builder_add(&builder, "{sv}", "signal",
832 g_variant_new_int32(item->rssi));
833 g_variant_builder_add(&builder, "{sv}", "signal_avg",
834 g_variant_new_int32(item->rssi_avg));
835 g_variant_builder_add(&builder, "{sv}", "tx_bitrate",
836 g_variant_new_uint32(item->tx_bitrate)); /* 10 times */
837 g_variant_builder_add(&builder, "{sv}", "rx_bitrate",
838 g_variant_new_uint32(item->rx_bitrate)); /* 10 times */
839 g_variant_builder_add(&builder, "{sv}", "mesh_llid",
840 g_variant_new_uint16(item->llid));
841 g_variant_builder_add(&builder, "{sv}", "mesh_plid",
842 g_variant_new_uint16(item->plid));
843 g_variant_builder_add(&builder, "{sv}", "mesh_plink",
844 g_variant_new_byte(item->mesh_plink)); /* 0 : DISCON, 1 : ESTAB */
845 g_variant_builder_add(&builder, "{sv}", "local_ps_mode",
846 g_variant_new_uint32(item->local_ps_mode)); /* 0 : INACTIVE, 1 : ACTIVE */
847 g_variant_builder_add(&builder, "{sv}", "peer_ps_mode",
848 g_variant_new_uint32(item->peer_ps_mode)); /* 0 : INACTIVE, 1 : ACTIVE */
849 g_variant_builder_add(&builder, "{sv}", "non_peer_ps_mode",
850 g_variant_new_uint32(item->non_peer_ps_mode)); /* 0 : INACTIVE, 1 : ACTIVE */
851 g_variant_builder_add(&builder, "{sv}", "authorized",
852 g_variant_new_boolean(item->authorized));
853 g_variant_builder_add(&builder, "{sv}", "associated",
854 g_variant_new_boolean(item->associated));
855 g_variant_builder_add(&builder, "{sv}", "preamble",
856 g_variant_new_boolean(item->preamble));
857 g_variant_builder_add(&builder, "{sv}", "WMM_WME",
858 g_variant_new_boolean(item->wme));
859 g_variant_builder_add(&builder, "{sv}", "MFP",
860 g_variant_new_boolean(item->mfp));
861 g_variant_builder_add(&builder, "{sv}", "TDLS_peer",
862 g_variant_new_boolean(item->tdls_peer));
863 g_variant_builder_add(&builder, "{sv}", "DTIM_period",
864 g_variant_new_byte(item->dtim_period));
865 g_variant_builder_add(&builder, "{sv}", "beacon_interval",
866 g_variant_new_uint16(item->beacon_interval));
867 g_variant_builder_add(&builder, "{sv}", "short_slot_time",
868 g_variant_new_boolean(item->short_slot_time));
869 g_variant_builder_add(&builder, "{sv}", "connected_time",
870 g_variant_new_uint32(item->connected_time));
871 g_variant_builder_close(&builder);
873 iter = g_list_next(iter);
876 station = g_variant_builder_end(&builder);
877 net_mesh_complete_get_station_info(object, invocation, station, ret);
879 g_object_unref(station);
883 g_variant_builder_init(&builder, G_VARIANT_TYPE_VARDICT);
884 g_variant_builder_add(&builder, "{sv}", "station", g_variant_new_string("7c:dd:90:62:37:cf"));
885 g_variant_builder_add(&builder, "{sv}", "inactive_time", g_variant_new_uint32(1685));
886 g_variant_builder_add(&builder, "{sv}", "rx_bytes", g_variant_new_uint32(34174));
887 g_variant_builder_add(&builder, "{sv}", "rx_packets", g_variant_new_uint32(1181));
888 g_variant_builder_add(&builder, "{sv}", "tx_bytes", g_variant_new_uint32(6877));
889 g_variant_builder_add(&builder, "{sv}", "tx_packets", g_variant_new_uint32(76));
890 g_variant_builder_add(&builder, "{sv}", "tx_retries", g_variant_new_uint32(0));
891 g_variant_builder_add(&builder, "{sv}", "tx_failed", g_variant_new_uint32(0));
892 g_variant_builder_add(&builder, "{sv}", "beacon_loss", g_variant_new_uint32(0));
893 g_variant_builder_add(&builder, "{sv}", "signal", g_variant_new_int32(-64));
894 g_variant_builder_add(&builder, "{sv}", "signal_avg", g_variant_new_int32(-63));
895 g_variant_builder_add(&builder, "{sv}", "tx_bitrate", g_variant_new_uint32(540)); /* 10 times */
896 g_variant_builder_add(&builder, "{sv}", "rx_bitrate", g_variant_new_uint32(55)); /* 10 times */
897 g_variant_builder_add(&builder, "{sv}", "mesh_llid", g_variant_new_uint32(51731));
898 g_variant_builder_add(&builder, "{sv}", "mesh_plid", g_variant_new_uint32(35432));
899 g_variant_builder_add(&builder, "{sv}", "mesh_plink", g_variant_new_uint32(1)); /* 0 : DISCON, 1 : ESTAB */
900 g_variant_builder_add(&builder, "{sv}", "mesh_local_PS_mode", g_variant_new_uint32(1)); /* 0 : INACTIVE, 1 : ACTIVE */
901 g_variant_builder_add(&builder, "{sv}", "mesh_peer_PS_mode", g_variant_new_uint32(1)); /* 0 : INACTIVE, 1 : ACTIVE */
902 g_variant_builder_add(&builder, "{sv}", "mesh_none_peer_PS_mode", g_variant_new_uint32(1)); /* 0 : INACTIVE, 1 : ACTIVE */
903 g_variant_builder_add(&builder, "{sv}", "authorized", g_variant_new_boolean(TRUE));
904 g_variant_builder_add(&builder, "{sv}", "associated", g_variant_new_boolean(TRUE));
905 g_variant_builder_add(&builder, "{sv}", "preamble",g_variant_new_string("long"));
906 g_variant_builder_add(&builder, "{sv}", "WMM_WME", g_variant_new_boolean(TRUE));
907 g_variant_builder_add(&builder, "{sv}", "MFP", g_variant_new_boolean(FALSE));
908 g_variant_builder_add(&builder, "{sv}", "TDLS_peer", g_variant_new_boolean(FALSE));
909 g_variant_builder_add(&builder, "{sv}", "DTIM_period", g_variant_new_uint32(0));
910 g_variant_builder_add(&builder, "{sv}", "beacon_interval", g_variant_new_uint32(1000));
911 g_variant_builder_add(&builder, "{sv}", "short_slot_time", g_variant_new_boolean(TRUE));
912 g_variant_builder_add(&builder, "{sv}", "connected_time", g_variant_new_uint32(256));
913 station = g_variant_builder_end(&builder);
915 net_mesh_complete_get_station_info(object, invocation, station, ret);
917 g_object_unref(station);
922 static gboolean _meshd_dbus_handle_get_mpath_info(NetMesh *object,
923 GDBusMethodInvocation *invocation,
926 int ret = MESHD_ERROR_NONE;
927 GVariantBuilder builder;
928 GVariant* mpath_data;
931 mesh_service *service = (mesh_service *)user_data;
932 mesh_interface_s *info = service->interface_info;
934 /* Clear mesh path list */
935 g_list_free_full(service->mpath_list, _on_mpath_list_destroy);
936 service->mpath_list = NULL;
938 ret = mesh_request_get_mpath_info(
939 info->mesh_interface, &service->mpath_list);
940 if (MESHD_ERROR_NONE != ret) {
941 MESH_LOGE("Failed to mesh_request_get_mpath_info");
943 g_dbus_method_invocation_return_error(invocation,
944 G_DBUS_ERROR, G_DBUS_ERROR_FAILED, "Request Failed");
947 * Example) sh-3.2# iw mesh0 mpath dump
948 * DEST ADDR NEXT HOP IFACE SN METRIC QLEN EXPTIME DTIM DRET FLAGS
949 * 7c:dd:90:62:37:cf 7c:dd:90:62:37:cf mesh0 221 152 0 10 100 0 0x5
951 /* Get mesh path information and make variant data */
952 g_variant_builder_init(&builder, G_VARIANT_TYPE("aa{sv}"));
954 iter = service->mpath_list;
955 while (iter != NULL) {
956 mesh_mpath_info_s *item = (mesh_mpath_info_s*)iter->data;
958 g_variant_builder_open(&builder, G_VARIANT_TYPE_VARDICT);
959 g_variant_builder_add(&builder, "{sv}", "DEST_ADDR",
960 g_variant_new_string(item->dest_addr));
961 g_variant_builder_add(&builder, "{sv}", "NEXT_HOP",
962 g_variant_new_string(item->next_hop));
963 g_variant_builder_add(&builder, "{sv}", "IFACE",
964 g_variant_new_string(item->interface));
965 g_variant_builder_add(&builder, "{sv}", "SN",
966 g_variant_new_uint32(item->sn));
967 g_variant_builder_add(&builder, "{sv}", "METRIC",
968 g_variant_new_uint32(item->metric));
969 g_variant_builder_add(&builder, "{sv}", "QLEN",
970 g_variant_new_uint32(item->qlen));
971 g_variant_builder_add(&builder, "{sv}", "EXPTIME",
972 g_variant_new_uint32(item->exptime));
973 g_variant_builder_add(&builder, "{sv}", "DTIM",
974 g_variant_new_uint32(item->discovery_timeout));
975 g_variant_builder_add(&builder, "{sv}", "DRET",
976 g_variant_new_byte(item->discovery_retries));
977 g_variant_builder_add(&builder, "{sv}", "FLAGS",
978 g_variant_new_byte(item->flags));
979 g_variant_builder_close(&builder);
981 iter = g_list_next(iter);
984 mpath_data = g_variant_builder_end(&builder);
985 net_mesh_complete_get_mpath_info(object, invocation, mpath_data, ret);
987 g_object_unref(mpath_data);
993 static void _meshd_dbus_on_activator_bus_acquired(GDBusConnection *conn,
994 const gchar *name, gpointer user_data)
997 GError *error = NULL;
998 mesh_service *service = (mesh_service *)user_data;
1002 meshd_activator_dbus_object = manager_skeleton_new();
1003 if (NULL == meshd_activator_dbus_object) {
1004 MESH_LOGE("manager_skeleton_new() Fail");
1008 g_signal_connect(meshd_activator_dbus_object, "handle-enable",
1009 G_CALLBACK(_meshd_dbus_handle_enable), service);
1010 g_signal_connect(meshd_activator_dbus_object, "handle-disable",
1011 G_CALLBACK(_meshd_dbus_handle_disable), service);
1013 ret = g_dbus_interface_skeleton_export(
1014 G_DBUS_INTERFACE_SKELETON(meshd_activator_dbus_object),
1015 conn, MESH_DBUS_MANAGER_OBJPATH, &error);
1017 MESH_LOGE("g_dbus_interface_skeleton_export() Fail(%s)", error->message);
1018 g_error_free(error);
1022 static void _meshd_dbus_on_bus_acquired(GDBusConnection *conn, const gchar *name,
1026 GError *error = NULL;
1027 mesh_service *service = (mesh_service *)user_data;
1031 meshd_dbus_object = net_mesh_skeleton_new();
1032 if (NULL == meshd_dbus_object) {
1033 MESH_LOGE("net_mesh_skeleton_new() Fail");
1037 g_signal_connect(meshd_dbus_object, "handle-scan",
1038 G_CALLBACK(_meshd_dbus_handle_scan), service);
1039 g_signal_connect(meshd_dbus_object, "handle-specific-scan",
1040 G_CALLBACK(_meshd_dbus_handle_specific_scan), service);
1041 g_signal_connect(meshd_dbus_object, "handle-cancel-scan",
1042 G_CALLBACK(_meshd_dbus_handle_cancel_scan), service);
1043 g_signal_connect(meshd_dbus_object, "handle-get-found-mesh-networks",
1044 G_CALLBACK(_meshd_dbus_handle_get_found_mesh_networks), service);
1045 g_signal_connect(meshd_dbus_object, "handle-enable-mesh",
1046 G_CALLBACK(_meshd_dbus_handle_enable_mesh), service);
1047 g_signal_connect(meshd_dbus_object, "handle-disable-mesh",
1048 G_CALLBACK(_meshd_dbus_handle_disable_mesh), service);
1049 g_signal_connect(meshd_dbus_object, "handle-get-joined-mesh-network",
1050 G_CALLBACK(_meshd_dbus_handle_get_joined_mesh_network), service);
1051 g_signal_connect(meshd_dbus_object, "handle-set-gate",
1052 G_CALLBACK(_meshd_dbus_handle_set_gate), service);
1053 g_signal_connect(meshd_dbus_object, "handle-unset-gate",
1054 G_CALLBACK(_meshd_dbus_handle_unset_gate), service);
1055 g_signal_connect(meshd_dbus_object, "handle-set-softap",
1056 G_CALLBACK(_meshd_dbus_handle_set_softap), service);
1057 g_signal_connect(meshd_dbus_object, "handle-enable-softap",
1058 G_CALLBACK(_meshd_dbus_handle_enable_softap), service);
1059 g_signal_connect(meshd_dbus_object, "handle-disable-softap",
1060 G_CALLBACK(_meshd_dbus_handle_disable_softap), service);
1061 g_signal_connect(meshd_dbus_object, "handle-add-mesh-network",
1062 G_CALLBACK(_meshd_dbus_handle_add_mesh_network), service);
1063 g_signal_connect(meshd_dbus_object, "handle-get-saved-mesh-network",
1064 G_CALLBACK(_meshd_dbus_handle_get_saved_mesh_network), service);
1065 g_signal_connect(meshd_dbus_object, "handle-select-saved-mesh-network",
1066 G_CALLBACK(_meshd_dbus_handle_select_saved_mesh_network), service);
1067 g_signal_connect(meshd_dbus_object, "handle-forget-saved-mesh-network",
1068 G_CALLBACK(_meshd_dbus_handle_forget_saved_mesh_network), service);
1069 g_signal_connect(meshd_dbus_object, "handle-set-interfaces",
1070 G_CALLBACK(_meshd_dbus_handle_set_interfaces), service);
1071 g_signal_connect(meshd_dbus_object, "handle-get-station-info",
1072 G_CALLBACK(_meshd_dbus_handle_get_station_info), service);
1073 g_signal_connect(meshd_dbus_object, "handle-get-mpath-info",
1074 G_CALLBACK(_meshd_dbus_handle_get_mpath_info), service);
1076 ret = g_dbus_interface_skeleton_export(G_DBUS_INTERFACE_SKELETON(meshd_dbus_object),
1077 conn, MESH_DBUS_OBJPATH, &error);
1079 MESH_LOGE("g_dbus_interface_skeleton_export() Fail(%s)", error->message);
1080 g_error_free(error);
1083 ret = _meshd_dbus_subscribe_name_owner_changed(conn);
1084 if (MESHD_ERROR_NONE != ret) {
1085 MESH_LOGE("_meshd_dbus_subscribe_name_owner_changed() Fail(%d)", ret);
1090 static void _meshd_dbus_on_name_lost(GDBusConnection *conn, const gchar *name,
1096 MESH_LOGD("Lost the name %s", name);
1099 static void _meshd_dbus_on_name_acquired(GDBusConnection *conn, const gchar *name,
1105 MESH_LOGD("Acquired the name %s", name);
1108 static gboolean _meshd_dbus_interface_init(mesh_service *service)
1111 guint activation_dbus_id;
1112 meshd_check_null_ret_error("service", service, FALSE);
1114 id = g_bus_own_name(G_BUS_TYPE_SYSTEM,
1115 MESH_DBUS_INTERFACE,
1116 G_BUS_NAME_OWNER_FLAGS_REPLACE,
1117 _meshd_dbus_on_bus_acquired,
1118 _meshd_dbus_on_name_acquired,
1119 _meshd_dbus_on_name_lost,
1123 MESH_LOGE("g_bus_own_name() Fail");
1127 /* Get D-Bus owner to activate zigbee-daemon */
1128 activation_dbus_id = g_bus_own_name(G_BUS_TYPE_SYSTEM,
1129 MESH_DBUS_INTERFACE".manager",
1130 G_BUS_NAME_OWNER_FLAGS_REPLACE,
1131 _meshd_dbus_on_activator_bus_acquired,
1137 service->dbus_id = id;
1138 service->activation_dbus_id = activation_dbus_id;
1139 service->interface_info = g_new0(mesh_interface_s, 1);
1140 service->scanned_mesh_network = NULL;
1145 static void _meshd_dbus_deinit(mesh_service *service)
1147 mesh_interface_s *info = NULL;
1148 meshd_check_null_ret("service", service);
1150 g_bus_unown_name(service->dbus_id);
1152 g_bus_unown_name(service->activation_dbus_id);
1154 info = service->interface_info;
1155 meshd_check_null_ret("info", info);
1156 if (info->bridge_interface)
1157 g_free(info->bridge_interface);
1158 if (info->base_interface)
1159 g_free(info->base_interface);
1160 if (info->mesh_interface)
1161 g_free(info->mesh_interface);
1162 if (info->softap_interface)
1163 g_free(info->softap_interface);
1164 if (info->external_interface)
1165 g_free(info->external_interface);
1167 if (service->joined_network) {
1168 g_free(service->joined_network->mesh_id);
1169 g_free(service->joined_network);
1170 service->joined_network = NULL;
1172 mesh_request_clear_saved_mesh_network(&service->saved_mesh_network);
1174 /* Clear scan list */
1175 g_list_free_full(service->scanned_mesh_network, _on_scan_result_destroy);
1176 service->scanned_mesh_network = NULL;
1178 g_free(service->interface_info);
1179 service->interface_info = NULL;
1182 /**< mesh service interface initialization */
1183 gboolean meshd_service_interface_init(mesh_service *service)
1186 meshd_check_null_ret_error("service", service, FALSE);
1188 /* Initialize dbus interface */
1189 ret = _meshd_dbus_interface_init(service);
1191 MESH_LOGE("zigbee_service_dbus_interface_init failed!!!");
1198 /**< Zigbee service interface de-initialization */
1199 void meshd_service_interface_deinit(mesh_service *service)
1201 meshd_check_null_ret("service", service);
1203 /* De-initialize dbus interface */
1204 _meshd_dbus_deinit(service);