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-gdbus.h"
29 #include "mesh-service.h"
30 #include "mesh-service-interface.h"
31 #include "mesh-generated-code.h"
33 #include "mesh-request.h"
34 #include "mesh-interface.h"
36 static NetMesh *meshd_dbus_object;
37 static Manager *meshd_activator_dbus_object;
39 /* global list to care resource handle for each client */
40 static GList *meshd_dbus_client_list;
41 static GMutex meshd_dbus_client_list_mutex;
43 typedef struct _meshd_dbus_client_s {
45 } meshd_dbus_client_s;
47 NetMesh* meshd_dbus_get_object()
49 return meshd_dbus_object;
52 int64_t meshd_dbus_generate_signal_number()
59 static int _meshd_dbus_client_list_cleanup(GList *client_list)
61 meshd_dbus_client_s *client;
63 meshd_check_null_ret_error("client_list", client_list, FALSE);
65 client = client_list->data;
67 free(client->bus_name);
68 client->bus_name = NULL;
70 g_list_free(client_list);
72 return MESHD_ERROR_NONE;
75 static int _meshd_dbus_client_list_compare_bus_name(const void *a, const void *b)
77 const meshd_dbus_client_s *client = a;
79 return g_strcmp0(client->bus_name, b);
82 static inline GList* _meshd_dbus_client_list_find_client(const gchar *owner)
84 return g_list_find_custom(meshd_dbus_client_list, owner,
85 _meshd_dbus_client_list_compare_bus_name);
88 static void _meshd_dbus_name_owner_changed_cb(GDBusConnection *conn,
89 const gchar *sender_name,
90 const gchar *object_path,
91 const gchar *interface_name,
92 const gchar *signal_name,
98 gchar *name, *old_owner, *new_owner;
101 NOTUSED(sender_name);
102 NOTUSED(object_path);
103 NOTUSED(interface_name);
104 NOTUSED(signal_name);
107 g_variant_get(parameters, "(&s&s&s)", &name, &old_owner, &new_owner);
109 if (0 == strlen(new_owner)) {
110 g_mutex_lock(&meshd_dbus_client_list_mutex);
111 client = _meshd_dbus_client_list_find_client(old_owner);
112 if (client) { /* found bus name in our bus list */
113 MESH_LOGD("bus(%s) stopped", old_owner);
114 meshd_dbus_client_list = g_list_remove_link(meshd_dbus_client_list, client);
116 g_mutex_unlock(&meshd_dbus_client_list_mutex);
119 ret = _meshd_dbus_client_list_cleanup(client);
120 if (MESHD_ERROR_NONE != ret)
121 MESH_LOGE("_meshd_dbus_client_list_cleanup() Fail(%d)", ret);
126 static int _meshd_dbus_subscribe_name_owner_changed(GDBusConnection *conn)
130 id = g_dbus_connection_signal_subscribe(conn,
131 "org.freedesktop.DBus", /* bus name */
132 "org.freedesktop.DBus", /* interface */
133 "NameOwnerChanged", /* member */
134 "/org/freedesktop/DBus", /* path */
136 G_DBUS_SIGNAL_FLAGS_NONE,
137 _meshd_dbus_name_owner_changed_cb,
141 MESH_LOGE("g_dbus_connection_signal_subscribe() Fail");
142 return MESHD_ERROR_IO_ERROR;
145 return MESHD_ERROR_NONE;
148 static gboolean _meshd_dbus_handle_enable(Manager *object,
149 GDBusMethodInvocation *invocation,
152 int ret = MESHD_ERROR_NONE;
153 mesh_service *service = (mesh_service *)user_data;
154 mesh_interface_s *info = service->interface_info;
156 if (service->mesh_activated) {
157 /* Already activated */
158 manager_complete_enable(object, invocation,
159 MESHD_ERROR_OPERATION_FAILED);
161 /* Do API response first */
162 manager_complete_enable(object, invocation, ret);
163 service->mesh_activated = TRUE;
166 meshd_check_null_ret_error("info", info, FALSE);
168 /* Register event handler first */
169 ret = mesh_request_register_event_handler();
170 if (MESHD_ERROR_NONE != ret) {
171 MESH_LOGE("Failed to register mesh event handler !! [%d]", ret);
174 ret = mesh_interface_initialize(service->interface_info);
175 if (MESHD_ERROR_NONE != ret) {
176 MESH_LOGE("Failed to mesh_interface_initialize [%d]", ret);
180 ret = mesh_request_load_saved_mesh_network(&service->saved_mesh_network);
181 if (MESHD_ERROR_NONE != ret) {
182 MESH_LOGE("Failed to mesh_request_load_saved_mesh_network [%d]", ret);
187 net_mesh_emit_mesh_enabled(meshd_dbus_get_object(), ret);
192 static gboolean _meshd_dbus_handle_disable(Manager *object,
193 GDBusMethodInvocation *invocation,
196 int ret = MESHD_ERROR_NONE;
197 mesh_service *service = (mesh_service *)user_data;
198 mesh_interface_s *info = service->interface_info;
200 meshd_check_null_ret_error("info", info, FALSE);
202 /* Make response first */
203 manager_complete_disable(object, invocation, ret);
205 ret = mesh_request_unregister_event_handler();
206 if (MESHD_ERROR_NONE != ret) {
207 MESH_LOGE("Failed to unregister mesh event handler !! [%d]", ret);
210 /* Terminate daemon */
211 meshd_service_exit(service);
216 static gboolean _meshd_dbus_handle_scan(NetMesh *object,
217 GDBusMethodInvocation *invocation,
220 int ret = MESHD_ERROR_NONE;
221 mesh_service *service = (mesh_service *)user_data;
222 mesh_interface_s *info = service->interface_info;
224 meshd_check_null_ret_error("info", info, FALSE);
226 ret = mesh_request_scan(service);
227 if (MESHD_ERROR_NONE != ret)
228 MESH_LOGE("Failed to mesh_request_scan !");
230 net_mesh_complete_scan(object, invocation, ret);
235 static gboolean _meshd_dbus_handle_specific_scan(NetMesh *object,
236 GDBusMethodInvocation *invocation,
241 int ret = MESHD_ERROR_NONE;
242 mesh_service *service = (mesh_service *)user_data;
243 mesh_interface_s *info = service->interface_info;
245 meshd_check_null_ret_error("info", info, FALSE);
247 ret = mesh_request_specific_scan(service, mesh_id, channel);
248 if (MESHD_ERROR_NONE != ret)
249 MESH_LOGE("Failed to mesh_request_specific_scan !");
251 net_mesh_complete_specific_scan(object, invocation, ret);
256 static gboolean _meshd_dbus_handle_cancel_scan(NetMesh *object,
257 GDBusMethodInvocation *invocation,
260 int ret = MESHD_ERROR_NONE;
261 mesh_service *service = (mesh_service *)user_data;
263 ret = mesh_request_cancel_scan(service);
264 if (MESHD_ERROR_NONE != ret) {
265 MESH_LOGE("Failed to mesh_request_cancel_scan");
268 net_mesh_complete_cancel_scan(object, invocation, ret);
273 static void _on_scan_result_destroy(gpointer data)
275 mesh_scan_result_s *scan_item = (mesh_scan_result_s *)data;
278 g_free(scan_item->mesh_id);
279 g_free(scan_item->bssid);
280 g_free(scan_item->object_path);
285 static void _on_peer_info_destroy(gpointer data)
287 mesh_peer_info_s *peer = (mesh_peer_info_s *)data;
289 g_free(peer->address);
293 static void _on_station_list_destroy(gpointer data)
295 mesh_station_info_s *info = (mesh_station_info_s*)data;
303 static void _on_mpath_list_destroy(gpointer data)
305 mesh_mpath_info_s *info = (mesh_mpath_info_s*)data;
308 g_free(info->dest_addr);
309 g_free(info->next_hop);
310 g_free(info->interface);
315 static gboolean _meshd_dbus_handle_get_found_mesh_networks(NetMesh *object,
316 GDBusMethodInvocation *invocation,
319 int ret = MESHD_ERROR_NONE;
320 mesh_service *service = (mesh_service *)user_data;
322 GVariantBuilder builder;
325 mesh_scan_result_s *scan_item = NULL;
327 MESH_LOGD("Request to get scanned mesh network list");
329 ret = mesh_request_get_networks(service);
330 if (MESHD_ERROR_NONE != ret)
331 MESH_LOGE("Failed to mesh_request_get_networks");
333 g_variant_builder_init(&builder, G_VARIANT_TYPE("aa{sv}"));
335 /* scanned_mesh_network would be filled above request */
336 iter = service->scanned_mesh_network;
337 while (iter != NULL) {
338 scan_item = (mesh_scan_result_s*)iter->data;
340 g_variant_builder_open(&builder, G_VARIANT_TYPE_VARDICT);
341 g_variant_builder_add(&builder, "{sv}", "mesh_id",
342 g_variant_new_string(scan_item->mesh_id));
343 g_variant_builder_add(&builder, "{sv}", "bssid",
344 g_variant_new_string(scan_item->bssid));
345 g_variant_builder_add(&builder, "{sv}", "rssi",
346 g_variant_new_int32(scan_item->rssi));
347 g_variant_builder_add(&builder, "{sv}", "channel",
348 g_variant_new_uint32(scan_item->channel));
349 g_variant_builder_add(&builder, "{sv}", "security",
350 g_variant_new_uint32((int)scan_item->security));
351 g_variant_builder_add(&builder, "{sv}", "state",
352 g_variant_new_uint32(scan_item->state));
353 g_variant_builder_close(&builder);
355 iter = g_list_next(iter);
358 networks = g_variant_builder_end(&builder);
360 net_mesh_complete_get_found_mesh_networks(object, invocation, networks, ret);
365 static gboolean _meshd_dbus_handle_enable_mesh(NetMesh *object,
366 GDBusMethodInvocation *invocation,
369 int ret = MESHD_ERROR_NONE;
370 mesh_service *service = (mesh_service *)user_data;
372 /* It handles creating virtual network and bridge */
373 ret = mesh_request_enable_network(service);
374 if (MESHD_ERROR_NONE != ret)
375 MESH_LOGE("Failed to mesh_request_enable_network [%d]", ret);
378 /* Detect external network state (i.e. Ethernet)
379 and decide to make gate enabled */
380 ret = mesh_request_set_mesh_gate(info->bridge_interface,
381 info->mesh_interface, info->external_interface);
382 if (MESHD_ERROR_NONE != ret) {
383 MESH_LOGE("Failed to mesh_request_set_mesh_gate [%d]", ret);
387 net_mesh_complete_enable_mesh(object, invocation, ret);
392 static gboolean _meshd_dbus_handle_disable_mesh(NetMesh *object,
393 GDBusMethodInvocation *invocation,
396 int ret = MESHD_ERROR_NONE;
397 mesh_service *service = (mesh_service *)user_data;
398 mesh_interface_s *info = service->interface_info;
400 meshd_check_null_ret_error("info", info, FALSE);
402 if (FALSE == service->mesh_activated) {
403 MESH_LOGD("Mesh network is not activated yet");
404 ret = MESHD_ERROR_OPERATION_FAILED;
405 net_mesh_complete_disable_mesh(object, invocation, ret);
409 ret = mesh_request_disable_network(service);
410 if (MESHD_ERROR_NONE != ret) {
411 MESH_LOGE("Failed to disable mesh network !");
415 net_mesh_complete_disable_mesh(object, invocation, ret);
420 static gboolean _meshd_dbus_handle_get_joined_mesh_network(NetMesh *object,
421 GDBusMethodInvocation *invocation,
424 int ret = MESHD_ERROR_NONE;
425 mesh_service *service = (mesh_service *)user_data;
426 mesh_network_info_s *joined = NULL;
428 ret = mesh_request_get_joined_network(service);
429 if (MESHD_ERROR_NONE == ret) {
430 joined = service->joined_network;
432 net_mesh_complete_get_joined_mesh_network(object, invocation,
433 joined->mesh_id, joined->bssid,
434 joined->channel, (int)joined->security,
437 net_mesh_complete_get_joined_mesh_network(object, invocation,
438 "", "", 0, 0, 0, MESHD_ERROR_NO_DATA);
441 net_mesh_complete_get_joined_mesh_network(object, invocation,
442 "", "", 0, 0, 0, ret);
448 static gboolean _meshd_dbus_handle_get_connected_peers(NetMesh *object,
449 GDBusMethodInvocation *invocation,
452 int ret = MESHD_ERROR_NONE;
453 mesh_service *service = (mesh_service *)user_data;
455 GVariantBuilder builder;
458 mesh_peer_info_s *peer = NULL;
460 MESH_LOGD("Request to get connected peers");
462 ret = mesh_request_get_connected_peers(service);
463 if (MESHD_ERROR_NONE != ret)
464 MESH_LOGE("Failed to mesh_request_get_connected_peers");
465 g_variant_builder_init(&builder, G_VARIANT_TYPE("aa{sv}"));
467 iter = service->connected_mesh_peers;
468 while (iter != NULL) {
469 peer = (mesh_peer_info_s*)iter->data;
471 g_variant_builder_open(&builder, G_VARIANT_TYPE_VARDICT);
472 g_variant_builder_add(&builder, "{sv}", "Address",
473 g_variant_new_string(peer->address));
474 g_variant_builder_close(&builder);
476 iter = g_list_next(iter);
479 peer_list = g_variant_builder_end(&builder);
481 net_mesh_complete_get_connected_peers(object, invocation, peer_list, ret);
486 static gboolean _meshd_dbus_handle_set_gate(NetMesh *object,
487 GDBusMethodInvocation *invocation, gboolean stp, gboolean gate_announce,
490 int ret = MESHD_ERROR_NONE;
491 mesh_service *service = (mesh_service *)user_data;
492 mesh_interface_s *info = service->interface_info;
494 MESH_LOGD("STP = %d", stp);
495 MESH_LOGD("gate_announce = %d", gate_announce);
497 /* Set STP and gate_announce */
498 ret = mesh_request_set_mesh_gate(info->bridge_interface,
499 info->mesh_interface, info->external_interface);
500 if (MESHD_ERROR_NONE != ret) {
501 MESH_LOGE("Failed to mesh_request_set_mesh_gate [%d]", ret);
504 net_mesh_complete_set_gate(object, invocation, ret);
509 static gboolean _meshd_dbus_handle_unset_gate(NetMesh *object,
510 GDBusMethodInvocation *invocation,
513 int ret = MESHD_ERROR_NONE;
514 mesh_service *service = (mesh_service *)user_data;
515 mesh_interface_s *info = service->interface_info;
517 ret = mesh_request_unset_mesh_gate(info->bridge_interface,
518 info->mesh_interface, info->external_interface);
519 if (MESHD_ERROR_NONE != ret) {
520 MESH_LOGE("Failed to mesh_request_unset_mesh_gate [%d]", ret);
522 net_mesh_complete_unset_gate(object, invocation, ret);
527 static gboolean _meshd_dbus_handle_set_softap(NetMesh *object,
528 GDBusMethodInvocation *invocation,
529 gchar *ssid, gchar *passphrase,
530 gchar *mode, gint channel, gint visibility, gint max_sta,
531 gint security, gpointer user_data)
533 int ret = MESHD_ERROR_NONE;
534 mesh_service *service = (mesh_service *)user_data;
535 mesh_interface_s *info = service->interface_info;
537 MESH_LOGD("SSID : %s", ssid);
538 MESH_LOGD("mode : %s", mode);
539 MESH_LOGD("channel : %d", channel);
540 MESH_LOGD("visibility: %d", visibility);
541 MESH_LOGD("max_sta : %d", max_sta);
542 MESH_LOGD("security : %d", security);
544 /* Save softAP information */
545 ret = mesh_request_set_softap_config(info->softap_interface,
546 ssid, mode, channel, visibility, max_sta,
547 security, passphrase);
548 if (MESHD_ERROR_NONE != ret) {
549 MESH_LOGE("Failed to mesh_request_set_softap_config [%d]", ret);
552 net_mesh_complete_set_softap(object, invocation, ret);
557 static gboolean _meshd_dbus_handle_enable_softap(NetMesh *object,
558 GDBusMethodInvocation *invocation, gpointer user_data)
560 int ret = MESHD_ERROR_NONE;
561 mesh_service *service = (mesh_service *)user_data;
562 mesh_interface_s *info = service->interface_info;
564 /* Check softAP interface and execute it */
565 ret = mesh_request_enable_softap(info->bridge_interface, info->softap_interface);
566 if (MESHD_ERROR_NONE != ret) {
567 MESH_LOGE("Failed to mesh_request_enable_softap [%d]", ret);
570 net_mesh_complete_enable_softap(object, invocation, ret);
575 static gboolean _meshd_dbus_handle_disable_softap(NetMesh *object,
576 GDBusMethodInvocation *invocation, gpointer user_data)
578 int ret = MESHD_ERROR_NONE;
579 mesh_service *service = (mesh_service *)user_data;
580 mesh_interface_s *info = service->interface_info;
583 ret = mesh_request_disable_softap(info->bridge_interface, info->softap_interface);
584 if (MESHD_ERROR_NONE != ret) {
585 MESH_LOGE("Failed to mesh_request_disable_softap [%d]", ret);
588 net_mesh_complete_disable_softap(object, invocation, ret);
593 static gboolean _meshd_dbus_handle_create_mesh_network(NetMesh *object,
594 GDBusMethodInvocation *invocation,
595 gchar *mesh_id, gint channel, gint security,
598 int ret = MESHD_ERROR_NONE;
599 mesh_service *service = (mesh_service *)user_data;
600 meshd_security_type_e sec = (1 == security) ? MESHD_SECURITY_SAE : MESHD_SECURITY_NONE;
602 ret = mesh_request_create_mesh_network(service, mesh_id, channel, sec);
604 net_mesh_complete_create_mesh_network(object, invocation, ret);
609 static gboolean _meshd_dbus_handle_connect_mesh_network(NetMesh *object,
610 GDBusMethodInvocation *invocation,
611 gchar *mesh_id, gint channel, gint security, gchar *passphrase,
614 int ret = MESHD_ERROR_NONE;
615 mesh_service *service = (mesh_service *)user_data;
616 meshd_security_type_e sec = (1 == security) ? MESHD_SECURITY_SAE : MESHD_SECURITY_NONE;
618 ret = mesh_request_connect_mesh_network(service, mesh_id, channel, sec, passphrase);
620 net_mesh_complete_connect_mesh_network(object, invocation, ret);
624 static gboolean _meshd_dbus_handle_disconnect_mesh_network(NetMesh *object,
625 GDBusMethodInvocation *invocation,
626 gchar *mesh_id, gint channel, gint security,
629 int ret = MESHD_ERROR_NONE;
630 mesh_service *service = (mesh_service *)user_data;
631 meshd_security_type_e sec = (1 == security) ? MESHD_SECURITY_SAE : MESHD_SECURITY_NONE;
633 ret = mesh_request_disconnect_mesh_network(service, mesh_id, channel, sec);
635 net_mesh_complete_disconnect_mesh_network(object, invocation, ret);
640 static gboolean _meshd_dbus_handle_forget_mesh_network(NetMesh *object,
641 GDBusMethodInvocation *invocation,
642 gchar *mesh_id, gint channel, gint security,
645 int ret = MESHD_ERROR_NONE;
646 mesh_service *service = (mesh_service *)user_data;
647 meshd_security_type_e sec = (1 == security) ? MESHD_SECURITY_SAE : MESHD_SECURITY_NONE;
649 ret = mesh_request_remove_mesh_network(service, mesh_id, channel, sec);
651 net_mesh_complete_forget_mesh_network(object, invocation, ret);
656 static gboolean _meshd_dbus_handle_set_interfaces(NetMesh *object,
657 GDBusMethodInvocation *invocation,
658 gchar *mesh, gchar *gate, gchar *softap,
661 int ret = MESHD_ERROR_NONE;
662 mesh_service *service = (mesh_service *)user_data;
663 mesh_interface_s *info = service->interface_info;
665 g_free(info->mesh_interface);
666 info->mesh_interface = g_strdup(mesh);
668 g_free(info->external_interface);
669 info->external_interface = g_strdup(gate);
671 g_free(info->softap_interface);
672 info->softap_interface = g_strdup(softap);
674 MESH_LOGD("Interface configuration for mesh network :");
675 MESH_LOGD(" Base : [%s]", info->base_interface);
676 MESH_LOGD(" Mesh : [%s]", info->mesh_interface);
677 MESH_LOGD(" Bridge : [%s]", info->bridge_interface);
678 MESH_LOGD(" SoftAP : [%s]", info->softap_interface);
679 MESH_LOGD(" External: [%s]", info->external_interface);
681 net_mesh_complete_set_interfaces(object, invocation, ret);
686 static gboolean _meshd_dbus_handle_get_station_info(NetMesh *object,
687 GDBusMethodInvocation *invocation,
690 int ret = MESHD_ERROR_NONE;
692 GVariantBuilder builder;
696 mesh_service *service = (mesh_service *)user_data;
697 mesh_interface_s *info = service->interface_info;
699 /* Clear mesh station list */
700 g_list_free_full(service->station_list, _on_station_list_destroy);
701 service->station_list = NULL;
703 ret = mesh_request_get_station_info(
704 info->mesh_interface, &service->station_list);
705 if (MESHD_ERROR_NONE != ret) {
706 MESH_LOGE("Failed to mesh_request_get_station_info");
708 g_dbus_method_invocation_return_error(invocation,
709 G_DBUS_ERROR, G_DBUS_ERROR_FAILED, "Request Failed");
712 * sh-3.2# iw mesh0 station dump
713 * Station 7c:dd:90:62:37:cf (on mesh0)
714 * inactive time: 1685 ms
723 * signal avg: -63 dBm
724 * tx bitrate: 54.0 MBit/s
725 * rx bitrate: 5.5 MBit/s
729 * mesh local PS mode: ACTIVE
730 * mesh peer PS mode: ACTIVE
731 * mesh non-peer PS mode: ACTIVE
740 * beacon interval:1000
741 * short slot time:yes
742 * connected time: 256 seconds
744 /* Get station information and make variant data */
745 g_variant_builder_init(&builder, G_VARIANT_TYPE("aa{sv}"));
747 iter = service->station_list;
748 while (iter != NULL) {
749 mesh_station_info_s *item = (mesh_station_info_s*)iter->data;
751 g_variant_builder_open(&builder, G_VARIANT_TYPE_VARDICT);
752 g_variant_builder_add(&builder, "{sv}", "bssid",
753 g_variant_new_string(item->bssid));
754 g_variant_builder_add(&builder, "{sv}", "inactive_time",
755 g_variant_new_uint32(item->inactive_time));
756 g_variant_builder_add(&builder, "{sv}", "rx_bytes",
757 g_variant_new_uint64(item->rx_bytes));
758 g_variant_builder_add(&builder, "{sv}", "rx_packets",
759 g_variant_new_uint32(item->rx_packets));
760 g_variant_builder_add(&builder, "{sv}", "tx_bytes",
761 g_variant_new_uint64(item->tx_bytes));
762 g_variant_builder_add(&builder, "{sv}", "tx_packets",
763 g_variant_new_uint32(item->tx_packets));
764 g_variant_builder_add(&builder, "{sv}", "tx_retries",
765 g_variant_new_uint32(item->tx_retries));
766 g_variant_builder_add(&builder, "{sv}", "tx_failed",
767 g_variant_new_uint32(item->tx_failed));
768 g_variant_builder_add(&builder, "{sv}", "beacon_loss",
769 g_variant_new_uint32(item->beacon_loss));
770 g_variant_builder_add(&builder, "{sv}", "beacon_rx",
771 g_variant_new_uint64(item->beacon_rx));
772 g_variant_builder_add(&builder, "{sv}", "rx_drop_misc",
773 g_variant_new_uint64(item->rx_drop_misc));
774 g_variant_builder_add(&builder, "{sv}", "signal",
775 g_variant_new_int32(item->rssi));
776 g_variant_builder_add(&builder, "{sv}", "signal_avg",
777 g_variant_new_int32(item->rssi_avg));
778 g_variant_builder_add(&builder, "{sv}", "tx_bitrate",
779 g_variant_new_uint32(item->tx_bitrate)); /* 10 times */
780 g_variant_builder_add(&builder, "{sv}", "rx_bitrate",
781 g_variant_new_uint32(item->rx_bitrate)); /* 10 times */
782 g_variant_builder_add(&builder, "{sv}", "mesh_llid",
783 g_variant_new_uint16(item->llid));
784 g_variant_builder_add(&builder, "{sv}", "mesh_plid",
785 g_variant_new_uint16(item->plid));
786 g_variant_builder_add(&builder, "{sv}", "mesh_plink",
787 g_variant_new_byte(item->mesh_plink)); /* 0 : DISCON, 1 : ESTAB */
788 g_variant_builder_add(&builder, "{sv}", "local_ps_mode",
789 g_variant_new_uint32(item->local_ps_mode)); /* 0 : INACTIVE, 1 : ACTIVE */
790 g_variant_builder_add(&builder, "{sv}", "peer_ps_mode",
791 g_variant_new_uint32(item->peer_ps_mode)); /* 0 : INACTIVE, 1 : ACTIVE */
792 g_variant_builder_add(&builder, "{sv}", "non_peer_ps_mode",
793 g_variant_new_uint32(item->non_peer_ps_mode)); /* 0 : INACTIVE, 1 : ACTIVE */
794 g_variant_builder_add(&builder, "{sv}", "authorized",
795 g_variant_new_boolean(item->authorized));
796 g_variant_builder_add(&builder, "{sv}", "associated",
797 g_variant_new_boolean(item->associated));
798 g_variant_builder_add(&builder, "{sv}", "preamble",
799 g_variant_new_boolean(item->preamble));
800 g_variant_builder_add(&builder, "{sv}", "WMM_WME",
801 g_variant_new_boolean(item->wme));
802 g_variant_builder_add(&builder, "{sv}", "MFP",
803 g_variant_new_boolean(item->mfp));
804 g_variant_builder_add(&builder, "{sv}", "TDLS_peer",
805 g_variant_new_boolean(item->tdls_peer));
806 g_variant_builder_add(&builder, "{sv}", "DTIM_period",
807 g_variant_new_byte(item->dtim_period));
808 g_variant_builder_add(&builder, "{sv}", "beacon_interval",
809 g_variant_new_uint16(item->beacon_interval));
810 g_variant_builder_add(&builder, "{sv}", "short_slot_time",
811 g_variant_new_boolean(item->short_slot_time));
812 g_variant_builder_add(&builder, "{sv}", "connected_time",
813 g_variant_new_uint32(item->connected_time));
814 g_variant_builder_close(&builder);
816 iter = g_list_next(iter);
819 station = g_variant_builder_end(&builder);
820 net_mesh_complete_get_station_info(object, invocation, station, ret);
822 g_object_unref(station);
828 static gboolean _meshd_dbus_handle_get_mpath_info(NetMesh *object,
829 GDBusMethodInvocation *invocation,
832 int ret = MESHD_ERROR_NONE;
833 GVariantBuilder builder;
834 GVariant* mpath_data;
837 mesh_service *service = (mesh_service *)user_data;
838 mesh_interface_s *info = service->interface_info;
840 /* Clear mesh path list */
841 g_list_free_full(service->mpath_list, _on_mpath_list_destroy);
842 service->mpath_list = NULL;
844 ret = mesh_request_get_mpath_info(
845 info->mesh_interface, &service->mpath_list);
846 if (MESHD_ERROR_NONE != ret) {
847 MESH_LOGE("Failed to mesh_request_get_mpath_info");
849 g_dbus_method_invocation_return_error(invocation,
850 G_DBUS_ERROR, G_DBUS_ERROR_FAILED, "Request Failed");
853 * Example) sh-3.2# iw mesh0 mpath dump
854 * DEST ADDR NEXT HOP IFACE SN METRIC QLEN EXPTIME DTIM DRET FLAGS
855 * 7c:dd:90:62:37:cf 7c:dd:90:62:37:cf mesh0 221 152 0 10 100 0 0x5
857 /* Get mesh path information and make variant data */
858 g_variant_builder_init(&builder, G_VARIANT_TYPE("aa{sv}"));
860 iter = service->mpath_list;
861 while (iter != NULL) {
862 mesh_mpath_info_s *item = (mesh_mpath_info_s*)iter->data;
864 g_variant_builder_open(&builder, G_VARIANT_TYPE_VARDICT);
865 g_variant_builder_add(&builder, "{sv}", "DEST_ADDR",
866 g_variant_new_string(item->dest_addr));
867 g_variant_builder_add(&builder, "{sv}", "NEXT_HOP",
868 g_variant_new_string(item->next_hop));
869 g_variant_builder_add(&builder, "{sv}", "IFACE",
870 g_variant_new_string(item->interface));
871 g_variant_builder_add(&builder, "{sv}", "SN",
872 g_variant_new_uint32(item->sn));
873 g_variant_builder_add(&builder, "{sv}", "METRIC",
874 g_variant_new_uint32(item->metric));
875 g_variant_builder_add(&builder, "{sv}", "QLEN",
876 g_variant_new_uint32(item->qlen));
877 g_variant_builder_add(&builder, "{sv}", "EXPTIME",
878 g_variant_new_uint32(item->exptime));
879 g_variant_builder_add(&builder, "{sv}", "DTIM",
880 g_variant_new_uint32(item->discovery_timeout));
881 g_variant_builder_add(&builder, "{sv}", "DRET",
882 g_variant_new_byte(item->discovery_retries));
883 g_variant_builder_add(&builder, "{sv}", "FLAGS",
884 g_variant_new_byte(item->flags));
885 g_variant_builder_close(&builder);
887 iter = g_list_next(iter);
890 mpath_data = g_variant_builder_end(&builder);
891 net_mesh_complete_get_mpath_info(object, invocation, mpath_data, ret);
893 g_object_unref(mpath_data);
899 static void _meshd_dbus_on_activator_bus_acquired(GDBusConnection *conn,
900 const gchar *name, gpointer user_data)
903 GError *error = NULL;
904 mesh_service *service = (mesh_service *)user_data;
908 meshd_activator_dbus_object = manager_skeleton_new();
909 if (NULL == meshd_activator_dbus_object) {
910 MESH_LOGE("manager_skeleton_new() Fail");
914 g_signal_connect(meshd_activator_dbus_object, "handle-enable",
915 G_CALLBACK(_meshd_dbus_handle_enable), service);
916 g_signal_connect(meshd_activator_dbus_object, "handle-disable",
917 G_CALLBACK(_meshd_dbus_handle_disable), service);
919 ret = g_dbus_interface_skeleton_export(
920 G_DBUS_INTERFACE_SKELETON(meshd_activator_dbus_object),
921 conn, MESH_DBUS_MANAGER_OBJPATH, &error);
923 MESH_LOGE("g_dbus_interface_skeleton_export() Fail(%s)", error->message);
928 static void _meshd_dbus_on_bus_acquired(GDBusConnection *conn, const gchar *name,
932 GError *error = NULL;
933 mesh_service *service = (mesh_service *)user_data;
937 meshd_dbus_object = net_mesh_skeleton_new();
938 if (NULL == meshd_dbus_object) {
939 MESH_LOGE("net_mesh_skeleton_new() Fail");
943 g_signal_connect(meshd_dbus_object, "handle-scan",
944 G_CALLBACK(_meshd_dbus_handle_scan), service);
945 g_signal_connect(meshd_dbus_object, "handle-specific-scan",
946 G_CALLBACK(_meshd_dbus_handle_specific_scan), service);
947 g_signal_connect(meshd_dbus_object, "handle-cancel-scan",
948 G_CALLBACK(_meshd_dbus_handle_cancel_scan), service);
949 g_signal_connect(meshd_dbus_object, "handle-get-found-mesh-networks",
950 G_CALLBACK(_meshd_dbus_handle_get_found_mesh_networks), service);
951 g_signal_connect(meshd_dbus_object, "handle-enable-mesh",
952 G_CALLBACK(_meshd_dbus_handle_enable_mesh), service);
953 g_signal_connect(meshd_dbus_object, "handle-disable-mesh",
954 G_CALLBACK(_meshd_dbus_handle_disable_mesh), service);
955 g_signal_connect(meshd_dbus_object, "handle-get-joined-mesh-network",
956 G_CALLBACK(_meshd_dbus_handle_get_joined_mesh_network), service);
957 g_signal_connect(meshd_dbus_object, "handle-get-connected-peers",
958 G_CALLBACK(_meshd_dbus_handle_get_connected_peers), service);
959 g_signal_connect(meshd_dbus_object, "handle-set-gate",
960 G_CALLBACK(_meshd_dbus_handle_set_gate), service);
961 g_signal_connect(meshd_dbus_object, "handle-unset-gate",
962 G_CALLBACK(_meshd_dbus_handle_unset_gate), service);
963 g_signal_connect(meshd_dbus_object, "handle-set-softap",
964 G_CALLBACK(_meshd_dbus_handle_set_softap), service);
965 g_signal_connect(meshd_dbus_object, "handle-enable-softap",
966 G_CALLBACK(_meshd_dbus_handle_enable_softap), service);
967 g_signal_connect(meshd_dbus_object, "handle-disable-softap",
968 G_CALLBACK(_meshd_dbus_handle_disable_softap), service);
969 g_signal_connect(meshd_dbus_object, "handle-create-mesh-network",
970 G_CALLBACK(_meshd_dbus_handle_create_mesh_network), service);
971 g_signal_connect(meshd_dbus_object, "handle-connect-mesh-network",
972 G_CALLBACK(_meshd_dbus_handle_connect_mesh_network), service);
973 g_signal_connect(meshd_dbus_object, "handle-disconnect-mesh-network",
974 G_CALLBACK(_meshd_dbus_handle_disconnect_mesh_network), service);
975 g_signal_connect(meshd_dbus_object, "handle-forget-mesh-network",
976 G_CALLBACK(_meshd_dbus_handle_forget_mesh_network), service);
977 g_signal_connect(meshd_dbus_object, "handle-set-interfaces",
978 G_CALLBACK(_meshd_dbus_handle_set_interfaces), service);
979 g_signal_connect(meshd_dbus_object, "handle-get-station-info",
980 G_CALLBACK(_meshd_dbus_handle_get_station_info), service);
981 g_signal_connect(meshd_dbus_object, "handle-get-mpath-info",
982 G_CALLBACK(_meshd_dbus_handle_get_mpath_info), service);
984 ret = g_dbus_interface_skeleton_export(G_DBUS_INTERFACE_SKELETON(meshd_dbus_object),
985 conn, MESH_DBUS_OBJPATH, &error);
987 MESH_LOGE("g_dbus_interface_skeleton_export() Fail(%s)", error->message);
991 ret = _meshd_dbus_subscribe_name_owner_changed(conn);
992 if (MESHD_ERROR_NONE != ret) {
993 MESH_LOGE("_meshd_dbus_subscribe_name_owner_changed() Fail(%d)", ret);
998 static void _meshd_dbus_on_name_lost(GDBusConnection *conn, const gchar *name,
1004 MESH_LOGD("Lost the name %s", name);
1007 static void _meshd_dbus_on_name_acquired(GDBusConnection *conn, const gchar *name,
1013 MESH_LOGD("Acquired the name %s", name);
1016 static gboolean _meshd_dbus_interface_init(mesh_service *service)
1019 guint activation_dbus_id;
1020 meshd_check_null_ret_error("service", service, FALSE);
1022 id = g_bus_own_name(G_BUS_TYPE_SYSTEM,
1023 MESH_DBUS_INTERFACE,
1024 G_BUS_NAME_OWNER_FLAGS_REPLACE,
1025 _meshd_dbus_on_bus_acquired,
1026 _meshd_dbus_on_name_acquired,
1027 _meshd_dbus_on_name_lost,
1031 MESH_LOGE("g_bus_own_name() Fail");
1035 /* Get D-Bus owner to activate mesh service daemon */
1036 activation_dbus_id = g_bus_own_name(G_BUS_TYPE_SYSTEM,
1037 MESH_DBUS_INTERFACE".manager",
1038 G_BUS_NAME_OWNER_FLAGS_REPLACE,
1039 _meshd_dbus_on_activator_bus_acquired,
1045 service->dbus_id = id;
1046 service->activation_dbus_id = activation_dbus_id;
1047 service->interface_info = g_new0(mesh_interface_s, 1);
1048 service->scanned_mesh_network = NULL;
1050 /* Initialize DBus sendor logic */
1051 meshd_dbus_start(service);
1056 static void _meshd_dbus_deinit(mesh_service *service)
1058 mesh_interface_s *info = NULL;
1059 meshd_check_null_ret("service", service);
1061 /* De-Initialize DBus sendor logic */
1062 meshd_dbus_stop(service);
1064 g_bus_unown_name(service->dbus_id);
1065 g_bus_unown_name(service->activation_dbus_id);
1067 info = service->interface_info;
1068 meshd_check_null_ret("info", info);
1069 if (info->bridge_interface)
1070 g_free(info->bridge_interface);
1071 if (info->base_interface)
1072 g_free(info->base_interface);
1073 if (info->mesh_interface)
1074 g_free(info->mesh_interface);
1075 if (info->softap_interface)
1076 g_free(info->softap_interface);
1077 if (info->external_interface)
1078 g_free(info->external_interface);
1080 if (service->joined_network) {
1081 g_free(service->joined_network->mesh_id);
1082 g_free(service->joined_network->bssid);
1083 g_free(service->joined_network);
1084 service->joined_network = NULL;
1087 /* Clear scan list */
1088 g_list_free_full(service->scanned_mesh_network, _on_scan_result_destroy);
1089 service->scanned_mesh_network = NULL;
1091 /* Clear connected peers list */
1092 g_list_free_full(service->connected_mesh_peers, _on_peer_info_destroy);
1093 service->connected_mesh_peers = NULL;
1095 g_free(service->interface_info);
1096 service->interface_info = NULL;
1099 /**< Mesh service interface initialization */
1100 gboolean meshd_service_interface_init(mesh_service *service)
1103 meshd_check_null_ret_error("service", service, FALSE);
1105 /* Initialize dbus interface */
1106 ret = _meshd_dbus_interface_init(service);
1108 MESH_LOGE("_meshd_dbus_interface_init failed!!!");
1115 /**< Mesh service interface de-initialization */
1116 void meshd_service_interface_deinit(mesh_service *service)
1118 meshd_check_null_ret("service", service);
1120 /* De-initialize dbus interface */
1121 _meshd_dbus_deinit(service);