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;
37 /* global list to care resource handle for each client */
38 static GList *meshd_dbus_client_list;
39 static GMutex meshd_dbus_client_list_mutex;
41 typedef struct _meshd_dbus_client_s {
43 } meshd_dbus_client_s;
45 NetMesh* meshd_dbus_get_object()
47 return meshd_dbus_object;
50 int64_t meshd_dbus_generate_signal_number()
57 static int _meshd_dbus_client_list_cleanup(GList *client_list)
59 meshd_dbus_client_s *client;
61 meshd_check_null_ret_error("client_list", client_list, FALSE);
63 client = client_list->data;
65 free(client->bus_name);
66 client->bus_name = NULL;
68 g_list_free(client_list);
70 return MESHD_ERROR_NONE;
73 static int _meshd_dbus_client_list_compare_bus_name(const void *a, const void *b)
75 const meshd_dbus_client_s *client = a;
77 return g_strcmp0(client->bus_name, b);
80 static inline GList* _meshd_dbus_client_list_find_client(const gchar *owner)
82 return g_list_find_custom(meshd_dbus_client_list, owner,
83 _meshd_dbus_client_list_compare_bus_name);
86 static void _meshd_dbus_name_owner_changed_cb(GDBusConnection *conn,
87 const gchar *sender_name,
88 const gchar *object_path,
89 const gchar *interface_name,
90 const gchar *signal_name,
96 gchar *name, *old_owner, *new_owner;
100 NOTUSED(object_path);
101 NOTUSED(interface_name);
102 NOTUSED(signal_name);
105 g_variant_get(parameters, "(&s&s&s)", &name, &old_owner, &new_owner);
107 if (0 == strlen(new_owner)) {
108 g_mutex_lock(&meshd_dbus_client_list_mutex);
109 client = _meshd_dbus_client_list_find_client(old_owner);
110 if (client) { /* found bus name in our bus list */
111 MESH_LOGD("bus(%s) stopped", old_owner);
112 meshd_dbus_client_list = g_list_remove_link(meshd_dbus_client_list, client);
114 g_mutex_unlock(&meshd_dbus_client_list_mutex);
117 ret = _meshd_dbus_client_list_cleanup(client);
118 if (MESHD_ERROR_NONE != ret)
119 MESH_LOGE("_meshd_dbus_client_list_cleanup() Fail(%d)", ret);
124 static int _meshd_dbus_subscribe_name_owner_changed(GDBusConnection *conn)
128 id = g_dbus_connection_signal_subscribe(conn,
129 "org.freedesktop.DBus", /* bus name */
130 "org.freedesktop.DBus", /* interface */
131 "NameOwnerChanged", /* member */
132 "/org/freedesktop/DBus", /* path */
134 G_DBUS_SIGNAL_FLAGS_NONE,
135 _meshd_dbus_name_owner_changed_cb,
139 MESH_LOGE("g_dbus_connection_signal_subscribe() Fail");
140 return MESHD_ERROR_IO_ERROR;
143 return MESHD_ERROR_NONE;
146 static gboolean _meshd_dbus_handle_enable(NetMesh *object,
147 GDBusMethodInvocation *invocation,
150 int ret = MESHD_ERROR_NONE;
151 mesh_service *service = (mesh_service *)user_data;
152 mesh_interface_s *info = service->interface_info;
154 if (service->mesh_activated) {
155 /* Already activated */
156 net_mesh_complete_enable(object, invocation,
157 MESHD_ERROR_OPERATION_FAILED);
159 /* Do API response first */
160 net_mesh_complete_enable(object, invocation, ret);
161 service->mesh_activated = TRUE;
164 meshd_check_null_ret_error("info", info, FALSE);
166 ret = mesh_interface_initialize(service->interface_info);
167 if (MESHD_ERROR_NONE != ret) {
168 MESH_LOGE("Failed to mesh_interface_initialize [%d]", ret);
173 net_mesh_emit_mesh_enabled(object, ret);
178 static gboolean _meshd_dbus_handle_disable(NetMesh *object,
179 GDBusMethodInvocation *invocation,
182 int ret = MESHD_ERROR_NONE;
183 mesh_service *service = (mesh_service *)user_data;
184 mesh_interface_s *info = service->interface_info;
186 meshd_check_null_ret_error("info", info, FALSE);
188 /* Make response first */
189 net_mesh_complete_disable(object, invocation, ret);
191 /* Terminate daemon */
192 meshd_service_exit(service);
197 static gboolean _meshd_dbus_handle_scan(NetMesh *object,
198 GDBusMethodInvocation *invocation,
201 int ret = MESHD_ERROR_NONE;
202 mesh_service *service = (mesh_service *)user_data;
203 mesh_interface_s *info = service->interface_info;
205 meshd_check_null_ret_error("info", info, FALSE);
207 ret = mesh_request_scan(info->mesh_interface);
208 if (MESHD_ERROR_NONE != ret) {
209 MESH_LOGE("Failed to mesh_request_scan on mesh interface[%s] !",
210 info->mesh_interface);
214 if (MESHD_ERROR_IN_PROGRESS != ret) {
215 ret = mesh_request_scan(info->base_interface);
216 if (MESHD_ERROR_NONE != ret)
217 MESH_LOGE("Failed to mesh_request_scan on base interface[%s] !",
218 info->base_interface);
221 net_mesh_complete_scan(object, invocation, ret);
226 static gboolean _meshd_dbus_handle_specific_scan(NetMesh *object,
227 GDBusMethodInvocation *invocation,
232 int ret = MESHD_ERROR_NONE;
233 mesh_service *service = (mesh_service *)user_data;
234 mesh_interface_s *info = service->interface_info;
236 meshd_check_null_ret_error("info", info, FALSE);
238 ret = mesh_request_specific_scan(info->mesh_interface, mesh_id, channel);
239 if (MESHD_ERROR_NONE != ret) {
240 MESH_LOGE("Failed to mesh_request_specific_scan on mesh interface[%s]",
241 info->mesh_interface);
245 if (MESHD_ERROR_IN_PROGRESS != ret) {
246 ret = mesh_request_specific_scan(info->base_interface, mesh_id, channel);
247 if (MESHD_ERROR_NONE != ret)
248 MESH_LOGE("Failed to mesh_request_specific_scan on base interface[%s]",
249 info->base_interface);
252 net_mesh_complete_specific_scan(object, invocation, ret);
257 static gboolean _meshd_dbus_handle_cancel_scan(NetMesh *object,
258 GDBusMethodInvocation *invocation,
261 int ret = MESHD_ERROR_NONE;
262 mesh_service *service = (mesh_service *)user_data;
263 mesh_interface_s *info = service->interface_info;
265 ret = mesh_request_cancel_scan(info->mesh_interface);
266 if (MESHD_ERROR_NONE != ret) {
267 MESH_LOGE("Failed to mesh_request_cancel_scan");
270 net_mesh_complete_cancel_scan(object, invocation, ret);
275 static void _on_scan_result_destroy(gpointer data)
277 mesh_scan_result_s *scan_item = (mesh_scan_result_s *)data;
280 g_free(scan_item->mesh_id);
281 g_free(scan_item->bssid);
285 static void _on_station_list_destroy(gpointer data)
287 mesh_station_info_s *info = (mesh_station_info_s*)data;
295 static void _on_mpath_list_destroy(gpointer data)
297 mesh_mpath_info_s *info = (mesh_mpath_info_s*)data;
300 g_free(info->dest_addr);
301 g_free(info->next_hop);
302 g_free(info->interface);
307 static gboolean _meshd_dbus_handle_get_found_mesh_networks(NetMesh *object,
308 GDBusMethodInvocation *invocation,
311 int ret = MESHD_ERROR_NONE;
312 mesh_service *service = (mesh_service *)user_data;
313 mesh_interface_s *info = service->interface_info;
315 GVariantBuilder builder;
318 mesh_scan_result_s *scan_item = NULL;
320 MESH_LOGD("Request to get scanned mesh network list");
322 ret = mesh_request_get_scan_result(info->mesh_interface, &service->scanned_mesh_network);
323 if (MESHD_ERROR_NONE != ret) {
324 MESH_LOGE("Failed to mesh_request_get_scan_result");
327 ret = mesh_request_get_scan_result(info->base_interface,
328 &service->scanned_mesh_network);
329 if (MESHD_ERROR_NONE != ret) {
330 MESH_LOGE("Failed to mesh_request_get_scan_result on base interface[%s]",
331 info->base_interface);
333 g_dbus_method_invocation_return_error(invocation,
334 G_DBUS_ERROR, G_DBUS_ERROR_FAILED, "Request Failed");
338 g_variant_builder_init(&builder, G_VARIANT_TYPE("aa{sv}"));
340 iter = service->scanned_mesh_network;
341 while (iter != NULL) {
342 scan_item = (mesh_scan_result_s*)iter->data;
344 g_variant_builder_open(&builder, G_VARIANT_TYPE_VARDICT);
345 g_variant_builder_add(&builder, "{sv}", "mesh_id",
346 g_variant_new_string(scan_item->mesh_id));
347 g_variant_builder_add(&builder, "{sv}", "bssid",
348 g_variant_new_string(scan_item->bssid));
349 g_variant_builder_add(&builder, "{sv}", "rssi",
350 g_variant_new_int32(scan_item->rssi));
351 g_variant_builder_add(&builder, "{sv}", "channel",
352 g_variant_new_uint32(scan_item->channel));
353 g_variant_builder_close(&builder);
355 iter = g_list_next(iter);
358 /* Clear scan list */
359 g_list_free_full(service->scanned_mesh_network, _on_scan_result_destroy);
360 service->scanned_mesh_network = NULL;
362 networks = g_variant_builder_end(&builder);
363 net_mesh_complete_get_found_mesh_networks(object, invocation, networks, ret);
368 static gboolean _meshd_dbus_handle_enable_mesh(NetMesh *object,
369 GDBusMethodInvocation *invocation,
372 int ret = MESHD_ERROR_NONE;
373 mesh_service *service = (mesh_service *)user_data;
374 mesh_interface_s *info = service->interface_info;
376 /* Create or join mesh network and create bridge */
377 ret = mesh_request_enable_mesh(info->base_interface, info->mesh_interface);
378 if (MESHD_ERROR_NONE != ret) {
379 MESH_LOGE("Failed to mesh_request_enable_mesh [%d]", ret);
383 ret = mesh_request_create_bridge(info->bridge_interface, info->mesh_interface);
384 if (MESHD_ERROR_NONE != ret) {
385 MESH_LOGE("Failed to mesh_request_create_bridge [%d]", ret);
390 ret = mesh_request_join_mesh(info->mesh_interface,
391 service->saved_mesh_network, &service->joined_network);
392 if (MESHD_ERROR_NONE != ret) {
393 MESH_LOGE("Failed to mesh_request_join_mesh [%d]", ret);
397 /* Detect external network state (i.e. Ethernet)
398 and decide to make gate enabled */
399 ret = mesh_request_set_mesh_gate(info->bridge_interface,
400 info->mesh_interface, info->external_interface);
401 if (MESHD_ERROR_NONE != ret) {
402 MESH_LOGE("Failed to mesh_request_set_mesh_gate [%d]", ret);
406 /* TODO: Check if specific scan is required */
407 ret = mesh_request_specific_scan(info->mesh_interface,
408 info->mesh_id, info->mesh_channel);
409 if (MESHD_ERROR_NONE != ret) {
410 MESH_LOGE("Failed to mesh_request_specific_scan [%d]", ret);
412 ret = mesh_request_get_scan_result(info->mesh_interface,
413 &service->scanned_mesh_network);
416 /* Request DHCP on bridge interface */
417 ret = mesh_request_dhcp(info->bridge_interface);
418 if (MESHD_ERROR_NONE != ret) {
419 MESH_LOGE("Failed to mesh_request_dhcp [%d]", ret);
422 /* TODO: Notify bridge status to Connman */
425 net_mesh_complete_enable_mesh(object, invocation, ret);
430 static gboolean _meshd_dbus_handle_disable_mesh(NetMesh *object,
431 GDBusMethodInvocation *invocation,
434 int ret = MESHD_ERROR_NONE;
435 mesh_service *service = (mesh_service *)user_data;
436 mesh_interface_s *info = service->interface_info;
438 meshd_check_null_ret_error("info", info, FALSE);
440 /* Destroy bridge and return from mesh to infra mode */
441 if (service->joined_network) {
442 g_free(service->joined_network->mesh_id);
443 g_free(service->joined_network);
444 service->joined_network = NULL;
447 if (FALSE == service->mesh_activated) {
448 MESH_LOGD("Mesh network is not activated yet");
449 ret = MESHD_ERROR_OPERATION_FAILED;
450 net_mesh_complete_disable_mesh(object, invocation, ret);
454 ret = mesh_request_disable_mesh(info->mesh_interface);
455 if (MESHD_ERROR_NONE != ret) {
456 MESH_LOGE("Failed to mesh_request_disable_mesh_gate");
459 ret = mesh_request_remove_bridge(info->bridge_interface);
460 if (MESHD_ERROR_NONE != ret) {
461 MESH_LOGE("Failed to mesh_request_remove_bridge");
465 net_mesh_complete_disable_mesh(object, invocation, ret);
467 /* Make notification */
468 mesh_notify_left_network();
473 static gboolean _meshd_dbus_handle_get_joined_mesh_network(NetMesh *object,
474 GDBusMethodInvocation *invocation,
477 int ret = MESHD_ERROR_NONE;
478 mesh_service *service = (mesh_service *)user_data;
479 mesh_network_info_s *joined = service->joined_network;
481 //gchar *meshid = strdup("meshnet");
482 //gchar *bssid = strdup("7c:dd:90:d8:2a:64");
483 //gint channel = 161;
484 //gint max_speed = 866;
487 net_mesh_complete_get_joined_mesh_network(object, invocation,
488 joined->mesh_id, joined->bssid, joined->channel, ret);
490 net_mesh_complete_get_joined_mesh_network(object, invocation,
491 "", "", 0, MESHD_ERROR_NO_DATA);
497 static gboolean _meshd_dbus_handle_set_gate(NetMesh *object,
498 GDBusMethodInvocation *invocation, gboolean stp, gboolean gate_announce,
501 int ret = MESHD_ERROR_NONE;
502 mesh_service *service = (mesh_service *)user_data;
503 mesh_interface_s *info = service->interface_info;
505 MESH_LOGD("STP = %d", stp);
506 MESH_LOGD("gate_announce = %d", gate_announce);
508 /* Set STP and gate_announce */
509 ret = mesh_request_set_mesh_gate(info->bridge_interface,
510 info->mesh_interface, info->external_interface);
511 if (MESHD_ERROR_NONE != ret) {
512 MESH_LOGE("Failed to mesh_request_set_mesh_gate [%d]", ret);
515 net_mesh_complete_set_gate(object, invocation, ret);
520 static gboolean _meshd_dbus_handle_unset_gate(NetMesh *object,
521 GDBusMethodInvocation *invocation,
524 int ret = MESHD_ERROR_NONE;
525 mesh_service *service = (mesh_service *)user_data;
526 mesh_interface_s *info = service->interface_info;
528 ret = mesh_request_unset_mesh_gate(info->bridge_interface,
529 info->mesh_interface, info->external_interface);
530 if (MESHD_ERROR_NONE != ret) {
531 MESH_LOGE("Failed to mesh_request_unset_mesh_gate [%d]", ret);
533 net_mesh_complete_unset_gate(object, invocation, ret);
538 static gboolean _meshd_dbus_handle_set_softap(NetMesh *object,
539 GDBusMethodInvocation *invocation, gchar *ssid, gchar *key,
540 gchar *mode, gint channel, gint visibility, gint max_sta,
541 gint security, gchar *passphrase, gpointer user_data)
543 int ret = MESHD_ERROR_NONE;
544 mesh_service *service = (mesh_service *)user_data;
545 mesh_interface_s *info = service->interface_info;
547 MESH_LOGD("SSID : %s", ssid);
548 MESH_LOGD("key : %s", key);
549 MESH_LOGD("mode : %s", mode);
550 MESH_LOGD("channel : %d", channel);
551 MESH_LOGD("visibility: %d", visibility);
552 MESH_LOGD("max_sta : %d", max_sta);
553 MESH_LOGD("security : %d", security);
555 /* Save softAP information */
556 ret = mesh_request_set_softap_config(info->softap_interface,
557 ssid, mode, channel, visibility, max_sta,
558 security, passphrase);
559 if (MESHD_ERROR_NONE != ret) {
560 MESH_LOGE("Failed to mesh_request_set_softap_config [%d]", ret);
563 net_mesh_complete_set_softap(object, invocation, ret);
568 static gboolean _meshd_dbus_handle_enable_softap(NetMesh *object,
569 GDBusMethodInvocation *invocation, gpointer user_data)
571 int ret = MESHD_ERROR_NONE;
572 mesh_service *service = (mesh_service *)user_data;
573 mesh_interface_s *info = service->interface_info;
575 /* Check softAP interface and execute it */
576 ret = mesh_request_enable_softap(info->bridge_interface, info->softap_interface);
577 if (MESHD_ERROR_NONE != ret) {
578 MESH_LOGE("Failed to mesh_request_enable_softap [%d]", ret);
581 net_mesh_complete_enable_softap(object, invocation, ret);
586 static gboolean _meshd_dbus_handle_disable_softap(NetMesh *object,
587 GDBusMethodInvocation *invocation, gpointer user_data)
589 int ret = MESHD_ERROR_NONE;
590 mesh_service *service = (mesh_service *)user_data;
591 mesh_interface_s *info = service->interface_info;
594 ret = mesh_request_disable_softap(info->bridge_interface, info->softap_interface);
595 if (MESHD_ERROR_NONE != ret) {
596 MESH_LOGE("Failed to mesh_request_disable_softap [%d]", ret);
599 net_mesh_complete_disable_softap(object, invocation, ret);
604 static gboolean _meshd_dbus_handle_add_mesh_network(NetMesh *object,
605 GDBusMethodInvocation *invocation,
606 gchar *mesh_id, gint channel, gint security,
609 int ret = MESHD_ERROR_NONE;
610 mesh_service *service = (mesh_service *)user_data;
612 ret = mesh_request_add_mesh_network(&service->saved_mesh_network,
613 mesh_id, channel, security);
615 net_mesh_complete_add_mesh_network(object, invocation, ret);
620 static gboolean _meshd_dbus_handle_get_saved_mesh_network(NetMesh *object,
621 GDBusMethodInvocation *invocation,
624 int ret = MESHD_ERROR_NONE;
625 mesh_service *service = (mesh_service *)user_data;
627 GVariantBuilder builder;
631 ret = mesh_request_get_saved_mesh_network(&service->saved_mesh_network);
632 if (MESHD_ERROR_NONE != ret) {
633 MESH_LOGE("Failed to mesh_request_get_saved_mesh_network");
635 g_dbus_method_invocation_return_error(invocation,
636 G_DBUS_ERROR, G_DBUS_ERROR_FAILED, "Request Failed");
638 /* TODO: Get station information and make variant data */
639 g_variant_builder_init(&builder, G_VARIANT_TYPE("aa{sv}"));
641 iter = service->saved_mesh_network;
642 while (iter != NULL) {
643 mesh_network_info_s *item = (mesh_network_info_s*)iter->data;
645 g_variant_builder_open(&builder, G_VARIANT_TYPE_VARDICT);
646 g_variant_builder_add(&builder, "{sv}", "mesh_id",
647 g_variant_new_string(item->mesh_id));
648 g_variant_builder_add(&builder, "{sv}", "channel",
649 g_variant_new_uint32(item->channel));
650 g_variant_builder_add(&builder, "{sv}", "security",
651 g_variant_new_uint32(item->security));
652 g_variant_builder_close(&builder);
654 iter = g_list_next(iter);
657 networks = g_variant_builder_end(&builder);
658 net_mesh_complete_get_saved_mesh_network(object, invocation, networks, ret);
664 static gboolean _meshd_dbus_handle_select_saved_mesh_network(NetMesh *object,
665 GDBusMethodInvocation *invocation,
666 gchar *mesh_id, gint channel, gint security,
669 int ret = MESHD_ERROR_NONE;
670 mesh_service *service = (mesh_service *)user_data;
672 ret = mesh_request_select_saved_mesh_network(&service->saved_mesh_network,
673 mesh_id, channel, security);
675 net_mesh_complete_select_saved_mesh_network(object, invocation, ret);
680 static gboolean _meshd_dbus_handle_forget_saved_mesh_network(NetMesh *object,
681 GDBusMethodInvocation *invocation,
682 gchar *mesh_id, gint channel, gint security,
685 int ret = MESHD_ERROR_NONE;
686 mesh_service *service = (mesh_service *)user_data;
688 ret = mesh_request_forget_saved_mesh_network(&service->saved_mesh_network,
689 mesh_id, channel, security);
691 net_mesh_complete_forget_saved_mesh_network(object, invocation, ret);
696 static gboolean _meshd_dbus_handle_set_interfaces(NetMesh *object,
697 GDBusMethodInvocation *invocation,
698 gchar *mesh, gchar *gate, gchar *softap,
701 int ret = MESHD_ERROR_NONE;
702 mesh_service *service = (mesh_service *)user_data;
703 mesh_interface_s *info = service->interface_info;
705 g_free(info->mesh_interface);
706 info->mesh_interface = g_strdup(mesh);
708 g_free(info->external_interface);
709 info->external_interface = g_strdup(gate);
711 g_free(info->softap_interface);
712 info->softap_interface = g_strdup(softap);
714 net_mesh_complete_set_interfaces(object, invocation, ret);
719 static gboolean _meshd_dbus_handle_get_station_info(NetMesh *object,
720 GDBusMethodInvocation *invocation,
723 int ret = MESHD_ERROR_NONE;
725 GVariantBuilder builder;
729 mesh_service *service = (mesh_service *)user_data;
730 mesh_interface_s *info = service->interface_info;
732 /* Clear mesh station list */
733 g_list_free_full(service->station_list, _on_station_list_destroy);
734 service->station_list = NULL;
736 ret = mesh_request_get_station_info(
737 info->mesh_interface, &service->station_list);
738 if (MESHD_ERROR_NONE != ret) {
739 MESH_LOGE("Failed to mesh_request_get_station_info");
741 g_dbus_method_invocation_return_error(invocation,
742 G_DBUS_ERROR, G_DBUS_ERROR_FAILED, "Request Failed");
745 * sh-3.2# iw mesh0 station dump
746 * Station 7c:dd:90:62:37:cf (on mesh0)
747 * inactive time: 1685 ms
756 * signal avg: -63 dBm
757 * tx bitrate: 54.0 MBit/s
758 * rx bitrate: 5.5 MBit/s
762 * mesh local PS mode: ACTIVE
763 * mesh peer PS mode: ACTIVE
764 * mesh non-peer PS mode: ACTIVE
773 * beacon interval:1000
774 * short slot time:yes
775 * connected time: 256 seconds
777 /* Get station information and make variant data */
778 g_variant_builder_init(&builder, G_VARIANT_TYPE("aa{sv}"));
780 iter = service->station_list;
781 while (iter != NULL) {
782 mesh_station_info_s *item = (mesh_station_info_s*)iter->data;
784 g_variant_builder_open(&builder, G_VARIANT_TYPE_VARDICT);
785 g_variant_builder_add(&builder, "{sv}", "bssid",
786 g_variant_new_string(item->bssid));
787 g_variant_builder_add(&builder, "{sv}", "inactive_time",
788 g_variant_new_uint32(item->inactive_time));
789 g_variant_builder_add(&builder, "{sv}", "rx_bytes",
790 g_variant_new_uint64(item->rx_bytes));
791 g_variant_builder_add(&builder, "{sv}", "rx_packets",
792 g_variant_new_uint32(item->rx_packets));
793 g_variant_builder_add(&builder, "{sv}", "tx_bytes",
794 g_variant_new_uint64(item->tx_bytes));
795 g_variant_builder_add(&builder, "{sv}", "tx_packets",
796 g_variant_new_uint32(item->tx_packets));
797 g_variant_builder_add(&builder, "{sv}", "tx_retries",
798 g_variant_new_uint32(item->tx_retries));
799 g_variant_builder_add(&builder, "{sv}", "tx_failed",
800 g_variant_new_uint32(item->tx_failed));
801 g_variant_builder_add(&builder, "{sv}", "beacon_loss",
802 g_variant_new_uint32(item->beacon_loss));
803 g_variant_builder_add(&builder, "{sv}", "signal",
804 g_variant_new_int32(item->rssi));
805 g_variant_builder_add(&builder, "{sv}", "signal_avg",
806 g_variant_new_int32(item->rssi_avg));
807 g_variant_builder_add(&builder, "{sv}", "tx_bitrate",
808 g_variant_new_uint32(item->tx_bitrate)); /* 10 times */
809 g_variant_builder_add(&builder, "{sv}", "rx_bitrate",
810 g_variant_new_uint32(item->rx_bitrate)); /* 10 times */
811 g_variant_builder_add(&builder, "{sv}", "mesh_llid",
812 g_variant_new_uint16(item->llid));
813 g_variant_builder_add(&builder, "{sv}", "mesh_plid",
814 g_variant_new_uint16(item->plid));
815 g_variant_builder_add(&builder, "{sv}", "mesh_plink",
816 g_variant_new_byte(item->mesh_plink)); /* 0 : DISCON, 1 : ESTAB */
817 g_variant_builder_add(&builder, "{sv}", "local_ps_mode",
818 g_variant_new_uint32(item->local_ps_mode)); /* 0 : INACTIVE, 1 : ACTIVE */
819 g_variant_builder_add(&builder, "{sv}", "peer_ps_mode",
820 g_variant_new_uint32(item->peer_ps_mode)); /* 0 : INACTIVE, 1 : ACTIVE */
821 g_variant_builder_add(&builder, "{sv}", "non_peer_ps_mode",
822 g_variant_new_uint32(item->non_peer_ps_mode)); /* 0 : INACTIVE, 1 : ACTIVE */
823 g_variant_builder_add(&builder, "{sv}", "authorized",
824 g_variant_new_boolean(item->authorized));
825 g_variant_builder_add(&builder, "{sv}", "associated",
826 g_variant_new_boolean(item->associated));
827 g_variant_builder_add(&builder, "{sv}", "preamble",
828 g_variant_new_boolean(item->preamble));
829 g_variant_builder_add(&builder, "{sv}", "WMM_WME",
830 g_variant_new_boolean(item->wme));
831 g_variant_builder_add(&builder, "{sv}", "MFP",
832 g_variant_new_boolean(item->mfp));
833 g_variant_builder_add(&builder, "{sv}", "TDLS_peer",
834 g_variant_new_boolean(item->tdls_peer));
835 g_variant_builder_add(&builder, "{sv}", "DTIM_period",
836 g_variant_new_byte(item->dtim_period));
837 g_variant_builder_add(&builder, "{sv}", "beacon_interval",
838 g_variant_new_uint16(item->beacon_interval));
839 g_variant_builder_add(&builder, "{sv}", "short_slot_time",
840 g_variant_new_boolean(item->short_slot_time));
841 g_variant_builder_add(&builder, "{sv}", "connected_time",
842 g_variant_new_uint32(item->connected_time));
843 g_variant_builder_close(&builder);
845 iter = g_list_next(iter);
848 station = g_variant_builder_end(&builder);
849 net_mesh_complete_get_saved_mesh_network(object, invocation, station, ret);
851 g_object_unref(station);
855 g_variant_builder_init(&builder, G_VARIANT_TYPE_VARDICT);
856 g_variant_builder_add(&builder, "{sv}", "station", g_variant_new_string("7c:dd:90:62:37:cf"));
857 g_variant_builder_add(&builder, "{sv}", "inactive_time", g_variant_new_uint32(1685));
858 g_variant_builder_add(&builder, "{sv}", "rx_bytes", g_variant_new_uint32(34174));
859 g_variant_builder_add(&builder, "{sv}", "rx_packets", g_variant_new_uint32(1181));
860 g_variant_builder_add(&builder, "{sv}", "tx_bytes", g_variant_new_uint32(6877));
861 g_variant_builder_add(&builder, "{sv}", "tx_packets", g_variant_new_uint32(76));
862 g_variant_builder_add(&builder, "{sv}", "tx_retries", g_variant_new_uint32(0));
863 g_variant_builder_add(&builder, "{sv}", "tx_failed", g_variant_new_uint32(0));
864 g_variant_builder_add(&builder, "{sv}", "beacon_loss", g_variant_new_uint32(0));
865 g_variant_builder_add(&builder, "{sv}", "signal", g_variant_new_int32(-64));
866 g_variant_builder_add(&builder, "{sv}", "signal_avg", g_variant_new_int32(-63));
867 g_variant_builder_add(&builder, "{sv}", "tx_bitrate", g_variant_new_uint32(540)); /* 10 times */
868 g_variant_builder_add(&builder, "{sv}", "rx_bitrate", g_variant_new_uint32(55)); /* 10 times */
869 g_variant_builder_add(&builder, "{sv}", "mesh_llid", g_variant_new_uint32(51731));
870 g_variant_builder_add(&builder, "{sv}", "mesh_plid", g_variant_new_uint32(35432));
871 g_variant_builder_add(&builder, "{sv}", "mesh_plink", g_variant_new_uint32(1)); /* 0 : DISCON, 1 : ESTAB */
872 g_variant_builder_add(&builder, "{sv}", "mesh_local_PS_mode", g_variant_new_uint32(1)); /* 0 : INACTIVE, 1 : ACTIVE */
873 g_variant_builder_add(&builder, "{sv}", "mesh_peer_PS_mode", g_variant_new_uint32(1)); /* 0 : INACTIVE, 1 : ACTIVE */
874 g_variant_builder_add(&builder, "{sv}", "mesh_none_peer_PS_mode", g_variant_new_uint32(1)); /* 0 : INACTIVE, 1 : ACTIVE */
875 g_variant_builder_add(&builder, "{sv}", "authorized", g_variant_new_boolean(TRUE));
876 g_variant_builder_add(&builder, "{sv}", "associated", g_variant_new_boolean(TRUE));
877 g_variant_builder_add(&builder, "{sv}", "preamble",g_variant_new_string("long"));
878 g_variant_builder_add(&builder, "{sv}", "WMM_WME", g_variant_new_boolean(TRUE));
879 g_variant_builder_add(&builder, "{sv}", "MFP", g_variant_new_boolean(FALSE));
880 g_variant_builder_add(&builder, "{sv}", "TDLS_peer", g_variant_new_boolean(FALSE));
881 g_variant_builder_add(&builder, "{sv}", "DTIM_period", g_variant_new_uint32(0));
882 g_variant_builder_add(&builder, "{sv}", "beacon_interval", g_variant_new_uint32(1000));
883 g_variant_builder_add(&builder, "{sv}", "short_slot_time", g_variant_new_boolean(TRUE));
884 g_variant_builder_add(&builder, "{sv}", "connected_time", g_variant_new_uint32(256));
885 station = g_variant_builder_end(&builder);
887 net_mesh_complete_get_station_info(object, invocation, station, ret);
889 g_object_unref(station);
894 static gboolean _meshd_dbus_handle_get_mpath_info(NetMesh *object,
895 GDBusMethodInvocation *invocation,
898 int ret = MESHD_ERROR_NONE;
899 GVariantBuilder builder;
900 GVariant* mpath_data;
903 mesh_service *service = (mesh_service *)user_data;
904 mesh_interface_s *info = service->interface_info;
906 /* Clear mesh path list */
907 g_list_free_full(service->mpath_list, _on_mpath_list_destroy);
908 service->mpath_list = NULL;
910 ret = mesh_request_get_mpath_info(
911 info->mesh_interface, &service->mpath_list);
912 if (MESHD_ERROR_NONE != ret) {
913 MESH_LOGE("Failed to mesh_request_get_mpath_info");
915 g_dbus_method_invocation_return_error(invocation,
916 G_DBUS_ERROR, G_DBUS_ERROR_FAILED, "Request Failed");
919 * Example) sh-3.2# iw mesh0 mpath dump
920 * DEST ADDR NEXT HOP IFACE SN METRIC QLEN EXPTIME DTIM DRET FLAGS
921 * 7c:dd:90:62:37:cf 7c:dd:90:62:37:cf mesh0 221 152 0 10 100 0 0x5
923 /* Get mesh path information and make variant data */
924 g_variant_builder_init(&builder, G_VARIANT_TYPE("aa{sv}"));
926 iter = service->mpath_list;
927 while (iter != NULL) {
928 mesh_mpath_info_s *item = (mesh_mpath_info_s*)iter->data;
930 g_variant_builder_open(&builder, G_VARIANT_TYPE_VARDICT);
931 g_variant_builder_add(&builder, "{sv}", "DEST_ADDR",
932 g_variant_new_string(item->dest_addr));
933 g_variant_builder_add(&builder, "{sv}", "NEXT_HOP",
934 g_variant_new_string(item->next_hop));
935 g_variant_builder_add(&builder, "{sv}", "IFACE",
936 g_variant_new_string(item->interface));
937 g_variant_builder_add(&builder, "{sv}", "SN",
938 g_variant_new_uint32(item->sn));
939 g_variant_builder_add(&builder, "{sv}", "METRIC",
940 g_variant_new_uint32(item->metric));
941 g_variant_builder_add(&builder, "{sv}", "QLEN",
942 g_variant_new_uint32(item->qlen));
943 g_variant_builder_add(&builder, "{sv}", "EXPTIME",
944 g_variant_new_uint32(item->exptime));
945 g_variant_builder_add(&builder, "{sv}", "DTIM",
946 g_variant_new_uint32(item->discovery_timeout));
947 g_variant_builder_add(&builder, "{sv}", "DRET",
948 g_variant_new_byte(item->discovery_retries));
949 g_variant_builder_add(&builder, "{sv}", "FLAGS",
950 g_variant_new_byte(item->flags));
951 g_variant_builder_close(&builder);
953 iter = g_list_next(iter);
956 mpath_data = g_variant_builder_end(&builder);
957 net_mesh_complete_get_mpath_info(object, invocation, mpath_data, ret);
959 g_object_unref(mpath_data);
965 static void _meshd_dbus_on_bus_acquired(GDBusConnection *conn, const gchar *name,
969 GError *error = NULL;
970 mesh_service *service = (mesh_service *)user_data;
974 meshd_dbus_object = net_mesh_skeleton_new();
975 if (NULL == meshd_dbus_object) {
976 MESH_LOGE("net_mesh_skeleton_new() Fail");
980 g_signal_connect(meshd_dbus_object, "handle-enable",
981 G_CALLBACK(_meshd_dbus_handle_enable), service);
982 g_signal_connect(meshd_dbus_object, "handle-disable",
983 G_CALLBACK(_meshd_dbus_handle_disable), service);
984 g_signal_connect(meshd_dbus_object, "handle-scan",
985 G_CALLBACK(_meshd_dbus_handle_scan), service);
986 g_signal_connect(meshd_dbus_object, "handle-specific-scan",
987 G_CALLBACK(_meshd_dbus_handle_specific_scan), service);
988 g_signal_connect(meshd_dbus_object, "handle-cancel-scan",
989 G_CALLBACK(_meshd_dbus_handle_cancel_scan), service);
990 g_signal_connect(meshd_dbus_object, "handle-get-found-mesh-networks",
991 G_CALLBACK(_meshd_dbus_handle_get_found_mesh_networks), service);
992 g_signal_connect(meshd_dbus_object, "handle-enable-mesh",
993 G_CALLBACK(_meshd_dbus_handle_enable_mesh), service);
994 g_signal_connect(meshd_dbus_object, "handle-disable-mesh",
995 G_CALLBACK(_meshd_dbus_handle_disable_mesh), service);
996 g_signal_connect(meshd_dbus_object, "handle-get-joined-mesh-network",
997 G_CALLBACK(_meshd_dbus_handle_get_joined_mesh_network), service);
998 g_signal_connect(meshd_dbus_object, "handle-set-gate",
999 G_CALLBACK(_meshd_dbus_handle_set_gate), service);
1000 g_signal_connect(meshd_dbus_object, "handle-unset-gate",
1001 G_CALLBACK(_meshd_dbus_handle_unset_gate), service);
1002 g_signal_connect(meshd_dbus_object, "handle-set-softap",
1003 G_CALLBACK(_meshd_dbus_handle_set_softap), service);
1004 g_signal_connect(meshd_dbus_object, "handle-enable-softap",
1005 G_CALLBACK(_meshd_dbus_handle_enable_softap), service);
1006 g_signal_connect(meshd_dbus_object, "handle-disable-softap",
1007 G_CALLBACK(_meshd_dbus_handle_disable_softap), service);
1008 g_signal_connect(meshd_dbus_object, "handle-add-mesh-network",
1009 G_CALLBACK(_meshd_dbus_handle_add_mesh_network), service);
1010 g_signal_connect(meshd_dbus_object, "handle-get-saved-mesh-network",
1011 G_CALLBACK(_meshd_dbus_handle_get_saved_mesh_network), service);
1012 g_signal_connect(meshd_dbus_object, "handle-select-saved-mesh-network",
1013 G_CALLBACK(_meshd_dbus_handle_select_saved_mesh_network), service);
1014 g_signal_connect(meshd_dbus_object, "handle-forget-saved-mesh-network",
1015 G_CALLBACK(_meshd_dbus_handle_forget_saved_mesh_network), service);
1016 g_signal_connect(meshd_dbus_object, "handle-set-interfaces",
1017 G_CALLBACK(_meshd_dbus_handle_set_interfaces), service);
1018 g_signal_connect(meshd_dbus_object, "handle-get-station-info",
1019 G_CALLBACK(_meshd_dbus_handle_get_station_info), service);
1020 g_signal_connect(meshd_dbus_object, "handle-get-mpath-info",
1021 G_CALLBACK(_meshd_dbus_handle_get_mpath_info), service);
1023 ret = g_dbus_interface_skeleton_export(G_DBUS_INTERFACE_SKELETON(meshd_dbus_object),
1024 conn, MESH_DBUS_OBJPATH, &error);
1026 MESH_LOGE("g_dbus_interface_skeleton_export() Fail(%s)", error->message);
1027 g_error_free(error);
1030 ret = _meshd_dbus_subscribe_name_owner_changed(conn);
1031 if (MESHD_ERROR_NONE != ret) {
1032 MESH_LOGE("_meshd_dbus_subscribe_name_owner_changed() Fail(%d)", ret);
1037 static void _meshd_dbus_on_name_lost(GDBusConnection *conn, const gchar *name,
1043 MESH_LOGD("Lost the name %s", name);
1046 static void _meshd_dbus_on_name_acquired(GDBusConnection *conn, const gchar *name,
1052 MESH_LOGD("Acquired the name %s", name);
1055 static gboolean _meshd_dbus_interface_init(mesh_service *service)
1058 meshd_check_null_ret_error("service", service, FALSE);
1060 id = g_bus_own_name(G_BUS_TYPE_SYSTEM,
1061 MESH_DBUS_INTERFACE,
1062 G_BUS_NAME_OWNER_FLAGS_REPLACE,
1063 _meshd_dbus_on_bus_acquired,
1064 _meshd_dbus_on_name_acquired,
1065 _meshd_dbus_on_name_lost,
1069 MESH_LOGE("g_bus_own_name() Fail");
1073 service->dbus_id = id;
1074 service->interface_info = g_new0(mesh_interface_s, 1);
1075 service->scanned_mesh_network = NULL;
1080 static void _meshd_dbus_deinit(mesh_service *service)
1082 mesh_interface_s *info = NULL;
1083 meshd_check_null_ret("service", service);
1085 g_bus_unown_name(service->dbus_id);
1087 info = service->interface_info;
1088 meshd_check_null_ret("info", info);
1089 if (info->bridge_interface)
1090 g_free(info->bridge_interface);
1091 if (info->base_interface)
1092 g_free(info->base_interface);
1093 if (info->mesh_interface)
1094 g_free(info->mesh_interface);
1095 if (info->softap_interface)
1096 g_free(info->softap_interface);
1097 if (info->external_interface)
1098 g_free(info->external_interface);
1100 if (service->joined_network) {
1101 g_free(service->joined_network->mesh_id);
1102 g_free(service->joined_network);
1103 service->joined_network = NULL;
1105 mesh_request_clear_saved_mesh_network(&service->saved_mesh_network);
1107 /* Clear scan list */
1108 g_list_free_full(service->scanned_mesh_network, _on_scan_result_destroy);
1109 service->scanned_mesh_network = NULL;
1111 g_free(service->interface_info);
1112 service->interface_info = NULL;
1115 /**< mesh service interface initialization */
1116 gboolean meshd_service_interface_init(mesh_service *service)
1119 meshd_check_null_ret_error("service", service, FALSE);
1121 /* Initialize dbus interface */
1122 ret = _meshd_dbus_interface_init(service);
1124 MESH_LOGE("zigbee_service_dbus_interface_init failed!!!");
1131 /**< Zigbee service interface de-initialization */
1132 void meshd_service_interface_deinit(mesh_service *service)
1134 meshd_check_null_ret("service", service);
1136 /* De-initialize dbus interface */
1137 _meshd_dbus_deinit(service);