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.
24 #include <wifi-manager.h>
27 #include "wmesh-log.h"
28 #include "wmesh-util.h"
29 #include "wmesh-gdbus.h"
30 #include "wmesh-service.h"
31 #include "wmesh-peer-monitor.h"
32 #include "wmesh-service-interface.h"
33 #include "wmesh-generated-code.h"
35 #include "wmesh-request.h"
36 #include "wmesh-interface.h"
38 static NetWmesh *meshd_dbus_object;
39 static Manager *meshd_activator_dbus_object;
41 /* global list to care resource handle for each client */
42 static GList *meshd_dbus_client_list;
43 static GMutex meshd_dbus_client_list_mutex;
45 typedef struct _meshd_dbus_client_s {
47 } meshd_dbus_client_s;
49 #define CASE_TO_STR(x) case x: return #x;
51 static const char* wifi_error_to_string(wifi_manager_error_e err)
54 /* CHECK: List all enum values here */
55 CASE_TO_STR(WIFI_MANAGER_ERROR_NONE)
56 CASE_TO_STR(WIFI_MANAGER_ERROR_INVALID_PARAMETER)
57 CASE_TO_STR(WIFI_MANAGER_ERROR_OUT_OF_MEMORY)
58 CASE_TO_STR(WIFI_MANAGER_ERROR_INVALID_OPERATION)
59 CASE_TO_STR(WIFI_MANAGER_ERROR_ADDRESS_FAMILY_NOT_SUPPORTED)
60 CASE_TO_STR(WIFI_MANAGER_ERROR_OPERATION_FAILED)
61 CASE_TO_STR(WIFI_MANAGER_ERROR_NO_CONNECTION)
62 CASE_TO_STR(WIFI_MANAGER_ERROR_NOW_IN_PROGRESS)
63 CASE_TO_STR(WIFI_MANAGER_ERROR_ALREADY_EXISTS)
64 CASE_TO_STR(WIFI_MANAGER_ERROR_OPERATION_ABORTED)
65 CASE_TO_STR(WIFI_MANAGER_ERROR_DHCP_FAILED)
66 CASE_TO_STR(WIFI_MANAGER_ERROR_INVALID_KEY)
67 CASE_TO_STR(WIFI_MANAGER_ERROR_NO_REPLY)
68 CASE_TO_STR(WIFI_MANAGER_ERROR_SECURITY_RESTRICTED)
69 CASE_TO_STR(WIFI_MANAGER_ERROR_ALREADY_INITIALIZED)
70 CASE_TO_STR(WIFI_MANAGER_ERROR_PERMISSION_DENIED)
71 CASE_TO_STR(WIFI_MANAGER_ERROR_NOT_SUPPORTED)
73 return "WIFI_MANAGER_ERROR_UNKNOWN";
77 NetWmesh* wmeshd_dbus_get_object()
79 return meshd_dbus_object;
82 int64_t wmeshd_dbus_generate_signal_number()
89 static int _wmeshd_dbus_client_list_cleanup(GList *client_list)
91 meshd_dbus_client_s *client;
93 wmeshd_check_null_ret_error("client_list", client_list, FALSE);
95 client = client_list->data;
97 free(client->bus_name);
98 client->bus_name = NULL;
100 g_list_free(client_list);
102 return WMESHD_ERROR_NONE;
105 static int _wmeshd_dbus_client_list_compare_bus_name(const void *a, const void *b)
107 const meshd_dbus_client_s *client = a;
109 return g_strcmp0(client->bus_name, b);
112 static inline GList* _wmeshd_dbus_client_list_find_client(const gchar *owner)
114 return g_list_find_custom(meshd_dbus_client_list, owner,
115 _wmeshd_dbus_client_list_compare_bus_name);
118 static void _wmeshd_dbus_name_owner_changed_cb(GDBusConnection *conn,
119 const gchar *sender_name,
120 const gchar *object_path,
121 const gchar *interface_name,
122 const gchar *signal_name,
123 GVariant *parameters,
127 GList *client = NULL;
128 gchar *name, *old_owner, *new_owner;
131 NOTUSED(sender_name);
132 NOTUSED(object_path);
133 NOTUSED(interface_name);
134 NOTUSED(signal_name);
137 g_variant_get(parameters, "(&s&s&s)", &name, &old_owner, &new_owner);
139 if (0 == strlen(new_owner)) {
140 g_mutex_lock(&meshd_dbus_client_list_mutex);
141 client = _wmeshd_dbus_client_list_find_client(old_owner);
142 if (client) { /* found bus name in our bus list */
143 WMESH_LOGD("bus(%s) stopped", old_owner);
144 meshd_dbus_client_list = g_list_remove_link(meshd_dbus_client_list, client);
146 g_mutex_unlock(&meshd_dbus_client_list_mutex);
149 ret = _wmeshd_dbus_client_list_cleanup(client);
150 if (WMESHD_ERROR_NONE != ret)
151 WMESH_LOGE("_wmeshd_dbus_client_list_cleanup() Fail(%d)", ret);
156 static int _wmeshd_dbus_subscribe_name_owner_changed(GDBusConnection *conn)
160 id = g_dbus_connection_signal_subscribe(conn,
161 "org.freedesktop.DBus", /* bus name */
162 "org.freedesktop.DBus", /* interface */
163 "NameOwnerChanged", /* member */
164 "/org/freedesktop/DBus", /* path */
166 G_DBUS_SIGNAL_FLAGS_NONE,
167 _wmeshd_dbus_name_owner_changed_cb,
171 WMESH_LOGE("g_dbus_connection_signal_subscribe() Fail");
172 return WMESHD_ERROR_IO_ERROR;
175 return WMESHD_ERROR_NONE;
178 static gboolean _wmeshd_dbus_handle_enable(Manager *object,
179 GDBusMethodInvocation *invocation,
182 int ret = WMESHD_ERROR_NONE;
183 wmesh_service *service = (wmesh_service *)user_data;
184 wmesh_interface_s *info = service->interface_info;
186 wifi_manager_h wifi_handle = NULL;
187 bool wifi_activated = false;
189 /* Initialize Wi-Fi driver */
190 ret = wifi_manager_initialize(&wifi_handle);
191 if (WIFI_MANAGER_ERROR_NONE != ret)
192 WMESH_LOGE("Failed to get wifi manager handle ! [%s(%X)]",
193 wifi_error_to_string(ret), ret);
195 wifi_manager_is_activated(wifi_handle, &wifi_activated);
196 if (false == wifi_activated) {
197 ret = wifi_manager_activate(wifi_handle, NULL, NULL);
198 if (WIFI_MANAGER_ERROR_NONE != ret)
199 WMESH_LOGE("Failed to activate wifi ! [%s(%X)]",
200 wifi_error_to_string(ret), ret);
202 wifi_manager_deinitialize(wifi_handle);
204 if (service->mesh_activated) {
205 /* Already activated */
206 manager_complete_enable(object, invocation, WMESHD_ERROR_NONE);
210 /* Do API response first */
211 manager_complete_enable(object, invocation, ret);
212 service->mesh_activated = TRUE;
214 wmeshd_check_null_ret_error("info", info, FALSE);
216 /* Register event handler first */
217 ret = wmesh_request_register_event_handler();
218 if (WMESHD_ERROR_IN_PROGRESS == ret) {
219 WMESH_LOGE("Currently set netlink event handler !! [%d]", ret);
220 ret = WMESHD_ERROR_NONE;
221 } else if (WMESHD_ERROR_NONE != ret) {
222 WMESH_LOGE("Failed to register mesh event handler !! [%d]", ret);
225 ret = wmesh_interface_initialize(service->interface_info);
226 if (WMESHD_ERROR_NONE != ret) {
227 WMESH_LOGE("Failed to wmesh_interface_initialize [%d]", ret);
232 net_wmesh_emit_mesh_enabled(wmeshd_dbus_get_object(), ret);
237 static gboolean _wmeshd_dbus_handle_disable(Manager *object,
238 GDBusMethodInvocation *invocation,
241 int ret = WMESHD_ERROR_NONE;
242 wmesh_service *service = (wmesh_service *)user_data;
243 wmesh_interface_s *info = service->interface_info;
245 wmeshd_check_null_ret_error("info", info, FALSE);
247 /* Make response first */
248 manager_complete_disable(object, invocation, ret);
250 ret = wmesh_request_unregister_event_handler();
251 if (WMESHD_ERROR_NONE != ret)
252 WMESH_LOGE("Failed to unregister mesh event handler !! [%d]", ret);
254 /* Terminate daemon */
255 wmeshd_service_exit(service);
260 static gboolean _wmeshd_dbus_handle_scan(NetWmesh *object,
261 GDBusMethodInvocation *invocation,
264 int ret = WMESHD_ERROR_NONE;
265 wmesh_service *service = (wmesh_service *)user_data;
266 wmesh_interface_s *info = service->interface_info;
268 wmeshd_check_null_ret_error("info", info, FALSE);
270 ret = wmesh_request_scan(service);
271 if (WMESHD_ERROR_NONE != ret)
272 WMESH_LOGE("Failed to wmesh_request_scan !");
274 net_wmesh_complete_scan(object, invocation, ret);
279 static gboolean _wmeshd_dbus_handle_specific_scan(NetWmesh *object,
280 GDBusMethodInvocation *invocation,
285 int ret = WMESHD_ERROR_NONE;
286 wmesh_service *service = (wmesh_service *)user_data;
287 wmesh_interface_s *info = service->interface_info;
289 wmeshd_check_null_ret_error("info", info, FALSE);
291 ret = wmesh_request_specific_scan(service, mesh_id, channel);
292 if (WMESHD_ERROR_NONE != ret)
293 WMESH_LOGE("Failed to wmesh_request_specific_scan !");
295 net_wmesh_complete_specific_scan(object, invocation, ret);
300 static gboolean _wmeshd_dbus_handle_cancel_scan(NetWmesh *object,
301 GDBusMethodInvocation *invocation,
304 int ret = WMESHD_ERROR_NONE;
305 wmesh_service *service = (wmesh_service *)user_data;
307 ret = wmesh_request_cancel_scan(service);
308 if (WMESHD_ERROR_NONE != ret)
309 WMESH_LOGE("Failed to wmesh_request_cancel_scan");
311 net_wmesh_complete_cancel_scan(object, invocation, ret);
316 static void _on_scan_result_destroy(gpointer data)
318 wmesh_scan_result_s *scan_item = (wmesh_scan_result_s *)data;
321 g_free(scan_item->mesh_id);
322 g_free(scan_item->bssid);
323 g_free(scan_item->object_path);
328 static void _on_peer_info_destroy(gpointer data)
330 wmesh_peer_info_s *peer = (wmesh_peer_info_s *)data;
332 g_free(peer->address);
336 static void _on_station_list_destroy(gpointer data)
338 wmesh_station_info_s *info = (wmesh_station_info_s*)data;
346 static void _on_mpath_list_destroy(gpointer data)
348 wmesh_mpath_info_s *info = (wmesh_mpath_info_s*)data;
351 g_free(info->dest_addr);
352 g_free(info->next_hop);
353 g_free(info->interface);
358 static gboolean _wmeshd_dbus_handle_get_found_mesh_networks(NetWmesh *object,
359 GDBusMethodInvocation *invocation,
362 int ret = WMESHD_ERROR_NONE;
363 wmesh_service *service = (wmesh_service *)user_data;
365 GVariantBuilder builder;
368 wmesh_scan_result_s *scan_item = NULL;
370 WMESH_LOGD("Request to get scanned mesh network list");
372 ret = wmesh_request_get_networks(service);
373 if (WMESHD_ERROR_NONE != ret)
374 WMESH_LOGE("Failed to wmesh_request_get_networks");
376 g_variant_builder_init(&builder, G_VARIANT_TYPE("aa{sv}"));
378 /* scanned_mesh_network would be filled above request */
379 iter = service->scanned_mesh_network;
380 while (iter != NULL) {
381 scan_item = (wmesh_scan_result_s*)iter->data;
383 g_variant_builder_open(&builder, G_VARIANT_TYPE_VARDICT);
384 g_variant_builder_add(&builder, "{sv}", "mesh_id",
385 g_variant_new_string(scan_item->mesh_id));
386 g_variant_builder_add(&builder, "{sv}", "bssid",
387 g_variant_new_string(scan_item->bssid));
388 g_variant_builder_add(&builder, "{sv}", "rssi",
389 g_variant_new_int32(scan_item->rssi));
390 g_variant_builder_add(&builder, "{sv}", "channel",
391 g_variant_new_uint32(scan_item->channel));
392 g_variant_builder_add(&builder, "{sv}", "data_rate",
393 g_variant_new_int32(scan_item->data_rate));
394 g_variant_builder_add(&builder, "{sv}", "security",
395 g_variant_new_uint32((int)scan_item->security));
396 g_variant_builder_add(&builder, "{sv}", "state",
397 g_variant_new_uint32(scan_item->state));
398 g_variant_builder_close(&builder);
400 iter = g_list_next(iter);
403 networks = g_variant_builder_end(&builder);
405 net_wmesh_complete_get_found_mesh_networks(object, invocation, networks, ret);
410 static gboolean _wmeshd_dbus_handle_enable_mesh(NetWmesh *object,
411 GDBusMethodInvocation *invocation,
414 int ret = WMESHD_ERROR_NONE;
415 wmesh_service *service = (wmesh_service *)user_data;
417 /* It handles creating virtual network and bridge */
418 ret = wmesh_request_enable_network(service);
419 if (WMESHD_ERROR_NONE != ret)
420 WMESH_LOGE("Failed to wmesh_request_enable_network [%d]", ret);
422 wmesh_start_monitor_service(service);
424 net_wmesh_complete_enable_mesh(object, invocation, ret);
429 static gboolean _wmeshd_dbus_handle_disable_mesh(NetWmesh *object,
430 GDBusMethodInvocation *invocation,
433 int ret = WMESHD_ERROR_NONE;
434 wmesh_service *service = (wmesh_service *)user_data;
435 wmesh_interface_s *info = service->interface_info;
437 wmeshd_check_null_ret_error("info", info, FALSE);
439 if (FALSE == service->mesh_activated) {
440 WMESH_LOGD("Mesh network is not activated yet");
441 ret = WMESHD_ERROR_OPERATION_FAILED;
442 net_wmesh_complete_disable_mesh(object, invocation, ret);
446 ret = wmesh_request_disable_network(service);
447 if (WMESHD_ERROR_NONE != ret)
448 WMESH_LOGE("Failed to disable mesh network !");
450 /* Stop Mesh Node Monitoring Service */
451 wmesh_stop_monitor_service(service);
453 net_wmesh_complete_disable_mesh(object, invocation, ret);
458 static gboolean _wmeshd_dbus_handle_is_mesh_enabled(NetWmesh *object,
459 GDBusMethodInvocation *invocation,
462 int ret = WMESHD_ERROR_NONE;
463 gboolean state = TRUE;
464 wmesh_service *service = (wmesh_service *)user_data;
466 /* It handles creating virtual network and bridge */
467 ret = wmesh_interface_check(service->interface_info->mesh_interface);
468 if (WMESHD_ERROR_NONE != ret) {
469 WMESH_LOGE("Mesh Interface doesn't exists");
473 net_wmesh_complete_is_mesh_enabled(object, invocation, state);
478 static gboolean _wmeshd_dbus_handle_is_joined(NetWmesh *object,
479 GDBusMethodInvocation *invocation,
482 int ret = WMESHD_ERROR_NONE;
483 gboolean state = FALSE;
484 wmesh_service *service = (wmesh_service *)user_data;
486 ret = wmesh_request_get_joined_network(service);
487 if (WMESHD_ERROR_NONE == ret) {
488 if (service->joined_network)
492 net_wmesh_complete_is_joined(object, invocation, state, ret);
497 static gboolean _wmeshd_dbus_handle_get_joined_mesh_network(NetWmesh *object,
498 GDBusMethodInvocation *invocation,
501 int ret = WMESHD_ERROR_NONE;
502 wmesh_service *service = (wmesh_service *)user_data;
503 wmesh_network_info_s *joined = NULL;
505 ret = wmesh_request_get_joined_network(service);
506 if (WMESHD_ERROR_NONE == ret) {
507 joined = service->joined_network;
509 net_wmesh_complete_get_joined_mesh_network(object, invocation,
510 joined->mesh_id, joined->bssid,
511 joined->channel, (int)joined->security,
514 net_wmesh_complete_get_joined_mesh_network(object, invocation,
515 "", "", 0, 0, 0, WMESHD_ERROR_NO_DATA);
518 net_wmesh_complete_get_joined_mesh_network(object, invocation,
519 "", "", 0, 0, 0, ret);
525 static gboolean _wmeshd_dbus_handle_get_connected_peers(NetWmesh *object,
526 GDBusMethodInvocation *invocation,
529 int ret = WMESHD_ERROR_NONE;
530 wmesh_service *service = (wmesh_service *)user_data;
532 GVariantBuilder builder;
535 wmesh_peer_info_s *peer = NULL;
537 WMESH_LOGD("Request to get connected peers");
539 ret = wmesh_request_get_connected_peers(service);
540 if (WMESHD_ERROR_NONE != ret)
541 WMESH_LOGE("Failed to wmesh_request_get_connected_peers");
542 g_variant_builder_init(&builder, G_VARIANT_TYPE("aa{sv}"));
544 iter = service->connected_mesh_peers;
545 while (iter != NULL) {
546 peer = (wmesh_peer_info_s*)iter->data;
548 g_variant_builder_open(&builder, G_VARIANT_TYPE_VARDICT);
549 g_variant_builder_add(&builder, "{sv}", "Address",
550 g_variant_new_string(peer->address));
551 g_variant_builder_close(&builder);
553 iter = g_list_next(iter);
556 peer_list = g_variant_builder_end(&builder);
558 net_wmesh_complete_get_connected_peers(object, invocation, peer_list, ret);
563 static gboolean _wmeshd_dbus_handle_set_gate(NetWmesh *object,
564 GDBusMethodInvocation *invocation, gint16 gate_announce, guint hwmp_root_mode,
565 gboolean stp, gpointer user_data)
567 int ret = WMESHD_ERROR_NONE;
568 wmesh_service *service = (wmesh_service *)user_data;
569 wmesh_interface_s *info = service->interface_info;
571 WMESH_LOGD("gate_announce = %d", gate_announce);
572 WMESH_LOGD("HWMP_Root_Mode = %d", hwmp_root_mode);
573 WMESH_LOGD("STP = %d", stp);
575 info->gate_announce = gate_announce;
576 info->hwmp_root_mode = hwmp_root_mode;
579 /* Set STP and gate_announce for connmand */
580 ret = wmesh_gdbus_set_mesh_gate(service);
581 if (WMESHD_ERROR_NONE != ret)
582 WMESH_LOGE("Failed to wmesh_gdbus_set_mesh_gate [%d]", ret);
584 /* Set STP and gate_announce right now */
585 ret = wmesh_request_set_mesh_gate(info->bridge_interface,
586 info->mesh_interface, info->external_interface);
587 if (WMESHD_ERROR_NONE != ret)
588 WMESH_LOGE("Failed to wmesh_gdbus_set_mesh_gate [%d]", ret);
591 net_wmesh_complete_set_gate(object, invocation, ret);
596 static gboolean _wmeshd_dbus_handle_unset_gate(NetWmesh *object,
597 GDBusMethodInvocation *invocation,
600 int ret = WMESHD_ERROR_NONE;
601 wmesh_service *service = (wmesh_service *)user_data;
602 wmesh_interface_s *info = service->interface_info;
604 info->gate_announce = 0;
605 info->hwmp_root_mode = 0;
608 /* Set STP and gate_announce for connmand */
609 ret = wmesh_gdbus_set_mesh_gate(service);
610 if (WMESHD_ERROR_NONE != ret)
611 WMESH_LOGE("Failed to wmesh_gdbus_set_mesh_gate [%d]", ret);
613 /* Unset STP and Gate Annouce right now */
614 ret = wmesh_request_unset_mesh_gate(info->bridge_interface,
615 info->mesh_interface, info->external_interface);
616 if (WMESHD_ERROR_NONE != ret)
617 WMESH_LOGE("Failed to wmesh_request_unset_mesh_gate [%d]", ret);
619 net_wmesh_complete_unset_gate(object, invocation, ret);
624 static gboolean _wmeshd_dbus_handle_set_softap(NetWmesh *object,
625 GDBusMethodInvocation *invocation,
626 gchar *ssid, gchar *passphrase,
627 gchar *mode, gint channel, gint visibility, gint max_sta,
628 gint security, gpointer user_data)
630 int ret = WMESHD_ERROR_NONE;
631 wmesh_service *service = (wmesh_service *)user_data;
632 wmesh_interface_s *info = service->interface_info;
634 WMESH_LOGD("SSID : %s", ssid);
635 WMESH_LOGD("mode : %s", mode);
636 WMESH_LOGD("channel : %d", channel);
637 WMESH_LOGD("visibility: %d", visibility);
638 WMESH_LOGD("max_sta : %d", max_sta);
639 WMESH_LOGD("security : %d", security);
641 /* Save softAP information */
642 ret = wmesh_request_set_softap_config(info->softap_interface,
643 ssid, mode, channel, visibility, max_sta,
644 security, passphrase);
645 if (WMESHD_ERROR_NONE != ret)
646 WMESH_LOGE("Failed to wmesh_request_set_softap_config [%d]", ret);
648 net_wmesh_complete_set_softap(object, invocation, ret);
653 static gboolean _wmeshd_dbus_handle_enable_softap(NetWmesh *object,
654 GDBusMethodInvocation *invocation, gpointer user_data)
656 int ret = WMESHD_ERROR_NONE;
657 wmesh_service *service = (wmesh_service *)user_data;
658 wmesh_interface_s *info = service->interface_info;
660 /* Check softAP interface and execute it */
661 ret = wmesh_request_enable_softap(info->bridge_interface, info->softap_interface);
662 if (WMESHD_ERROR_NONE != ret)
663 WMESH_LOGE("Failed to wmesh_request_enable_softap [%d]", ret);
665 net_wmesh_complete_enable_softap(object, invocation, ret);
670 static gboolean _wmeshd_dbus_handle_disable_softap(NetWmesh *object,
671 GDBusMethodInvocation *invocation, gpointer user_data)
673 int ret = WMESHD_ERROR_NONE;
674 wmesh_service *service = (wmesh_service *)user_data;
675 wmesh_interface_s *info = service->interface_info;
678 ret = wmesh_request_disable_softap(info->bridge_interface, info->softap_interface);
679 if (WMESHD_ERROR_NONE != ret)
680 WMESH_LOGE("Failed to wmesh_request_disable_softap [%d]", ret);
682 net_wmesh_complete_disable_softap(object, invocation, ret);
687 static gboolean _wmeshd_dbus_handle_create_mesh_network(NetWmesh *object,
688 GDBusMethodInvocation *invocation,
689 gchar *mesh_id, gint channel, gint security,
692 int ret = WMESHD_ERROR_NONE;
693 wmesh_service *service = (wmesh_service *)user_data;
694 wmeshd_security_type_e sec = (1 == security) ? WMESHD_SECURITY_SAE : WMESHD_SECURITY_NONE;
696 ret = wmesh_request_create_mesh_network(service, mesh_id, channel, sec);
698 net_wmesh_complete_create_mesh_network(object, invocation, ret);
703 static gboolean _wmeshd_dbus_handle_connect_mesh_network(NetWmesh *object,
704 GDBusMethodInvocation *invocation,
705 gchar *mesh_id, gint channel, gint security, gchar *passphrase,
708 int ret = WMESHD_ERROR_NONE;
709 wmesh_service *service = (wmesh_service *)user_data;
710 wmeshd_security_type_e sec = (1 == security) ? WMESHD_SECURITY_SAE : WMESHD_SECURITY_NONE;
712 ret = wmesh_request_connect_mesh_network(service, mesh_id, channel, sec, passphrase);
714 net_wmesh_complete_connect_mesh_network(object, invocation, ret);
718 static gboolean _wmeshd_dbus_handle_disconnect_mesh_network(NetWmesh *object,
719 GDBusMethodInvocation *invocation,
720 gchar *mesh_id, gint channel, gint security,
723 int ret = WMESHD_ERROR_NONE;
724 wmesh_service *service = (wmesh_service *)user_data;
725 wmeshd_security_type_e sec = (1 == security) ? WMESHD_SECURITY_SAE : WMESHD_SECURITY_NONE;
727 ret = wmesh_request_disconnect_mesh_network(service, mesh_id, channel, sec);
729 net_wmesh_complete_disconnect_mesh_network(object, invocation, ret);
734 static gboolean _wmeshd_dbus_handle_forget_mesh_network(NetWmesh *object,
735 GDBusMethodInvocation *invocation,
736 gchar *mesh_id, gint channel, gint security,
739 int ret = WMESHD_ERROR_NONE;
740 wmesh_service *service = (wmesh_service *)user_data;
741 wmeshd_security_type_e sec = (1 == security) ? WMESHD_SECURITY_SAE : WMESHD_SECURITY_NONE;
743 ret = wmesh_request_remove_mesh_network(service, mesh_id, channel, sec);
745 net_wmesh_complete_forget_mesh_network(object, invocation, ret);
750 static gboolean _wmeshd_dbus_handle_set_interfaces(NetWmesh *object,
751 GDBusMethodInvocation *invocation,
752 gchar *mesh, gchar *gate, gchar *softap,
755 int ret = WMESHD_ERROR_NONE;
756 wmesh_service *service = (wmesh_service *)user_data;
757 wmesh_interface_s *info = service->interface_info;
759 g_free(info->mesh_interface);
760 info->mesh_interface = g_strdup(mesh);
762 g_free(info->external_interface);
763 info->external_interface = g_strdup(gate);
765 g_free(info->softap_interface);
766 info->softap_interface = g_strdup(softap);
768 WMESH_LOGD("Interface configuration for mesh network :");
769 WMESH_LOGD(" Base : [%s]", info->base_interface);
770 WMESH_LOGD(" Mesh : [%s]", info->mesh_interface);
771 WMESH_LOGD(" Bridge : [%s]", info->bridge_interface);
772 WMESH_LOGD(" SoftAP : [%s]", info->softap_interface);
773 WMESH_LOGD(" External: [%s]", info->external_interface);
775 net_wmesh_complete_set_interfaces(object, invocation, ret);
780 static gboolean _wmeshd_dbus_handle_get_station_info(NetWmesh *object,
781 GDBusMethodInvocation *invocation,
784 int ret = WMESHD_ERROR_NONE;
786 GVariantBuilder builder;
790 wmesh_service *service = (wmesh_service *)user_data;
791 wmesh_interface_s *info = service->interface_info;
793 /* Clear mesh station list */
794 g_list_free_full(service->station_list, _on_station_list_destroy);
795 service->station_list = NULL;
797 ret = wmesh_request_get_station_info(
798 info->mesh_interface, &service->station_list);
799 if (WMESHD_ERROR_NONE != ret) {
800 WMESH_LOGE("Failed to wmesh_request_get_station_info");
802 g_dbus_method_invocation_return_error(invocation,
803 G_DBUS_ERROR, G_DBUS_ERROR_FAILED, "Request Failed");
806 * sh-3.2# iw mesh0 station dump
807 * Station 7c:dd:90:62:37:cf (on mesh0)
808 * inactive time: 1685 ms
817 * signal avg: -63 dBm
818 * tx bitrate: 54.0 MBit/s
819 * rx bitrate: 5.5 MBit/s
823 * mesh local PS mode: ACTIVE
824 * mesh peer PS mode: ACTIVE
825 * mesh non-peer PS mode: ACTIVE
834 * beacon interval:1000
835 * short slot time:yes
836 * connected time: 256 seconds
838 /* Get station information and make variant data */
839 g_variant_builder_init(&builder, G_VARIANT_TYPE("aa{sv}"));
841 iter = service->station_list;
842 while (iter != NULL) {
843 wmesh_station_info_s *item = (wmesh_station_info_s*)iter->data;
845 g_variant_builder_open(&builder, G_VARIANT_TYPE_VARDICT);
846 g_variant_builder_add(&builder, "{sv}", "bssid",
847 g_variant_new_string(item->bssid));
848 g_variant_builder_add(&builder, "{sv}", "inactive_time",
849 g_variant_new_uint32(item->inactive_time));
850 g_variant_builder_add(&builder, "{sv}", "rx_bytes",
851 g_variant_new_uint64(item->rx_bytes));
852 g_variant_builder_add(&builder, "{sv}", "rx_packets",
853 g_variant_new_uint32(item->rx_packets));
854 g_variant_builder_add(&builder, "{sv}", "tx_bytes",
855 g_variant_new_uint64(item->tx_bytes));
856 g_variant_builder_add(&builder, "{sv}", "tx_packets",
857 g_variant_new_uint32(item->tx_packets));
858 g_variant_builder_add(&builder, "{sv}", "tx_retries",
859 g_variant_new_uint32(item->tx_retries));
860 g_variant_builder_add(&builder, "{sv}", "tx_failed",
861 g_variant_new_uint32(item->tx_failed));
862 g_variant_builder_add(&builder, "{sv}", "beacon_loss",
863 g_variant_new_uint32(item->beacon_loss));
864 g_variant_builder_add(&builder, "{sv}", "beacon_rx",
865 g_variant_new_uint64(item->beacon_rx));
866 g_variant_builder_add(&builder, "{sv}", "rx_drop_misc",
867 g_variant_new_uint64(item->rx_drop_misc));
868 g_variant_builder_add(&builder, "{sv}", "signal",
869 g_variant_new_int32(item->rssi));
870 g_variant_builder_add(&builder, "{sv}", "signal_avg",
871 g_variant_new_int32(item->rssi_avg));
872 g_variant_builder_add(&builder, "{sv}", "tx_bitrate",
873 g_variant_new_uint32(item->tx_bitrate)); /* 10 times */
874 g_variant_builder_add(&builder, "{sv}", "rx_bitrate",
875 g_variant_new_uint32(item->rx_bitrate)); /* 10 times */
876 g_variant_builder_add(&builder, "{sv}", "mesh_llid",
877 g_variant_new_uint16(item->llid));
878 g_variant_builder_add(&builder, "{sv}", "mesh_plid",
879 g_variant_new_uint16(item->plid));
880 g_variant_builder_add(&builder, "{sv}", "mesh_plink",
881 g_variant_new_byte(item->mesh_plink)); /* 0 : DISCON, 1 : ESTAB */
882 g_variant_builder_add(&builder, "{sv}", "local_ps_mode",
883 g_variant_new_uint32(item->local_ps_mode)); /* 0 : INACTIVE, 1 : ACTIVE */
884 g_variant_builder_add(&builder, "{sv}", "peer_ps_mode",
885 g_variant_new_uint32(item->peer_ps_mode)); /* 0 : INACTIVE, 1 : ACTIVE */
886 g_variant_builder_add(&builder, "{sv}", "non_peer_ps_mode",
887 g_variant_new_uint32(item->non_peer_ps_mode)); /* 0 : INACTIVE, 1 : ACTIVE */
888 g_variant_builder_add(&builder, "{sv}", "authorized",
889 g_variant_new_boolean(item->authorized));
890 g_variant_builder_add(&builder, "{sv}", "associated",
891 g_variant_new_boolean(item->associated));
892 g_variant_builder_add(&builder, "{sv}", "preamble",
893 g_variant_new_boolean(item->preamble));
894 g_variant_builder_add(&builder, "{sv}", "WMM_WME",
895 g_variant_new_boolean(item->wme));
896 g_variant_builder_add(&builder, "{sv}", "MFP",
897 g_variant_new_boolean(item->mfp));
898 g_variant_builder_add(&builder, "{sv}", "TDLS_peer",
899 g_variant_new_boolean(item->tdls_peer));
900 g_variant_builder_add(&builder, "{sv}", "DTIM_period",
901 g_variant_new_byte(item->dtim_period));
902 g_variant_builder_add(&builder, "{sv}", "beacon_interval",
903 g_variant_new_uint16(item->beacon_interval));
904 g_variant_builder_add(&builder, "{sv}", "short_slot_time",
905 g_variant_new_boolean(item->short_slot_time));
906 g_variant_builder_add(&builder, "{sv}", "connected_time",
907 g_variant_new_uint32(item->connected_time));
908 g_variant_builder_close(&builder);
910 iter = g_list_next(iter);
913 station = g_variant_builder_end(&builder);
914 net_wmesh_complete_get_station_info(object, invocation, station, ret);
916 g_object_unref(station);
922 static gboolean _wmeshd_dbus_handle_get_mpath_info(NetWmesh *object,
923 GDBusMethodInvocation *invocation,
926 int ret = WMESHD_ERROR_NONE;
927 GVariantBuilder builder;
928 GVariant* mpath_data;
931 wmesh_service *service = (wmesh_service *)user_data;
932 wmesh_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 = wmesh_request_get_mpath_info(
939 info->mesh_interface, &service->mpath_list);
940 if (WMESHD_ERROR_NONE != ret) {
941 WMESH_LOGE("Failed to wmesh_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 wmesh_mpath_info_s *item = (wmesh_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_wmesh_complete_get_mpath_info(object, invocation, mpath_data, ret);
987 g_object_unref(mpath_data);
993 static gboolean _wmeshd_dbus_handle_get_meshconf_info(NetWmesh *object,
994 GDBusMethodInvocation *invocation,
997 int ret = WMESHD_ERROR_NONE;
998 GVariantBuilder builder;
999 GVariant* meshconf_data;
1000 wmesh_meshconf_info_s *item;
1002 wmesh_service *service = (wmesh_service *)user_data;
1004 ret = wmesh_request_get_meshconf_info(service);
1005 if (WMESHD_ERROR_NONE != ret) {
1006 WMESH_LOGE("Failed to wmesh_request_get_mpath_info");
1008 g_dbus_method_invocation_return_error(invocation,
1009 G_DBUS_ERROR, G_DBUS_ERROR_FAILED, "Request Failed");
1011 /* Get mesh path information and make variant data */
1012 g_variant_builder_init(&builder, G_VARIANT_TYPE("a{sv}"));
1014 item = service->meshconf;
1016 g_variant_builder_add(&builder, "{sv}", "RETRY_TIMEOUT",
1017 g_variant_new_uint16(item->retry_timeout));
1018 g_variant_builder_add(&builder, "{sv}", "HWMP_MAX_PREQ_RETRIES",
1019 g_variant_new_byte(item->hwmp_max_preq_retries));
1020 g_variant_builder_add(&builder, "{sv}", "CONFIRM_TIMEOUT",
1021 g_variant_new_uint16(item->confirm_timeout));
1022 g_variant_builder_add(&builder, "{sv}", "PATH_REFRESH_TIME",
1023 g_variant_new_uint32(item->path_refresh_time));
1024 g_variant_builder_add(&builder, "{sv}", "HOLDING_TIMEOUT",
1025 g_variant_new_uint16(item->holding_timeout));
1026 g_variant_builder_add(&builder, "{sv}", "MIN_DISC_TIMEOUT",
1027 g_variant_new_uint16(item->min_disc_timeout));
1028 g_variant_builder_add(&builder, "{sv}", "MAX_PEER_LINKS",
1029 g_variant_new_uint16(item->max_peer_links));
1030 g_variant_builder_add(&builder, "{sv}", "HWMP_PREQ_MIN_INTERVAL",
1031 g_variant_new_uint16(item->hwmp_preq_min_interval));
1032 g_variant_builder_add(&builder, "{sv}", "TTL",
1033 g_variant_new_byte(item->ttl));
1034 g_variant_builder_add(&builder, "{sv}", "HWMP_ACTIVE_PATH_TIMEOUT",
1035 g_variant_new_uint32(item->hwmp_active_path_timeout));
1036 g_variant_builder_add(&builder, "{sv}", "ELEMENT_TTL",
1037 g_variant_new_byte(item->element_ttl));
1038 g_variant_builder_add(&builder, "{sv}", "HWMP_RANN_INTERVAL",
1039 g_variant_new_uint16(item->hwmp_rann_interval));
1040 g_variant_builder_add(&builder, "{sv}", "GATE_ANNOUNCEMENTS",
1041 g_variant_new_byte(item->gate_announcements));
1044 meshconf_data = g_variant_builder_end(&builder);
1045 net_wmesh_complete_get_meshconf_info(object, invocation, meshconf_data,
1048 g_object_unref(meshconf_data);
1051 g_free(service->meshconf);
1056 static void _wmeshd_dbus_on_activator_bus_acquired(GDBusConnection *conn,
1057 const gchar *name, gpointer user_data)
1060 GError *error = NULL;
1061 wmesh_service *service = (wmesh_service *)user_data;
1065 meshd_activator_dbus_object = manager_skeleton_new();
1066 if (NULL == meshd_activator_dbus_object) {
1067 WMESH_LOGE("manager_skeleton_new() Fail");
1071 g_signal_connect(meshd_activator_dbus_object, "handle-enable",
1072 G_CALLBACK(_wmeshd_dbus_handle_enable), service);
1073 g_signal_connect(meshd_activator_dbus_object, "handle-disable",
1074 G_CALLBACK(_wmeshd_dbus_handle_disable), service);
1076 ret = g_dbus_interface_skeleton_export(
1077 G_DBUS_INTERFACE_SKELETON(meshd_activator_dbus_object),
1078 conn, WMESH_DBUS_MANAGER_OBJPATH, &error);
1080 WMESH_LOGE("g_dbus_interface_skeleton_export() Fail(%s)", error->message);
1081 g_error_free(error);
1085 static void _wmeshd_dbus_on_bus_acquired(GDBusConnection *conn, const gchar *name,
1089 GError *error = NULL;
1090 wmesh_service *service = (wmesh_service *)user_data;
1094 meshd_dbus_object = net_wmesh_skeleton_new();
1095 if (NULL == meshd_dbus_object) {
1096 WMESH_LOGE("net_wmesh_skeleton_new() Fail");
1100 g_signal_connect(meshd_dbus_object, "handle-scan",
1101 G_CALLBACK(_wmeshd_dbus_handle_scan), service);
1102 g_signal_connect(meshd_dbus_object, "handle-specific-scan",
1103 G_CALLBACK(_wmeshd_dbus_handle_specific_scan), service);
1104 g_signal_connect(meshd_dbus_object, "handle-cancel-scan",
1105 G_CALLBACK(_wmeshd_dbus_handle_cancel_scan), service);
1106 g_signal_connect(meshd_dbus_object, "handle-get-found-mesh-networks",
1107 G_CALLBACK(_wmeshd_dbus_handle_get_found_mesh_networks), service);
1108 g_signal_connect(meshd_dbus_object, "handle-enable-mesh",
1109 G_CALLBACK(_wmeshd_dbus_handle_enable_mesh), service);
1110 g_signal_connect(meshd_dbus_object, "handle-disable-mesh",
1111 G_CALLBACK(_wmeshd_dbus_handle_disable_mesh), service);
1112 g_signal_connect(meshd_dbus_object, "handle-is-mesh-enabled",
1113 G_CALLBACK(_wmeshd_dbus_handle_is_mesh_enabled), service);
1114 g_signal_connect(meshd_dbus_object, "handle-is-joined",
1115 G_CALLBACK(_wmeshd_dbus_handle_is_joined), service);
1116 g_signal_connect(meshd_dbus_object, "handle-get-joined-mesh-network",
1117 G_CALLBACK(_wmeshd_dbus_handle_get_joined_mesh_network), service);
1118 g_signal_connect(meshd_dbus_object, "handle-get-connected-peers",
1119 G_CALLBACK(_wmeshd_dbus_handle_get_connected_peers), service);
1120 g_signal_connect(meshd_dbus_object, "handle-set-gate",
1121 G_CALLBACK(_wmeshd_dbus_handle_set_gate), service);
1122 g_signal_connect(meshd_dbus_object, "handle-unset-gate",
1123 G_CALLBACK(_wmeshd_dbus_handle_unset_gate), service);
1124 g_signal_connect(meshd_dbus_object, "handle-set-softap",
1125 G_CALLBACK(_wmeshd_dbus_handle_set_softap), service);
1126 g_signal_connect(meshd_dbus_object, "handle-enable-softap",
1127 G_CALLBACK(_wmeshd_dbus_handle_enable_softap), service);
1128 g_signal_connect(meshd_dbus_object, "handle-disable-softap",
1129 G_CALLBACK(_wmeshd_dbus_handle_disable_softap), service);
1130 g_signal_connect(meshd_dbus_object, "handle-create-mesh-network",
1131 G_CALLBACK(_wmeshd_dbus_handle_create_mesh_network), service);
1132 g_signal_connect(meshd_dbus_object, "handle-connect-mesh-network",
1133 G_CALLBACK(_wmeshd_dbus_handle_connect_mesh_network), service);
1134 g_signal_connect(meshd_dbus_object, "handle-disconnect-mesh-network",
1135 G_CALLBACK(_wmeshd_dbus_handle_disconnect_mesh_network), service);
1136 g_signal_connect(meshd_dbus_object, "handle-forget-mesh-network",
1137 G_CALLBACK(_wmeshd_dbus_handle_forget_mesh_network), service);
1138 g_signal_connect(meshd_dbus_object, "handle-set-interfaces",
1139 G_CALLBACK(_wmeshd_dbus_handle_set_interfaces), service);
1140 g_signal_connect(meshd_dbus_object, "handle-get-station-info",
1141 G_CALLBACK(_wmeshd_dbus_handle_get_station_info), service);
1142 g_signal_connect(meshd_dbus_object, "handle-get-mpath-info",
1143 G_CALLBACK(_wmeshd_dbus_handle_get_mpath_info), service);
1144 g_signal_connect(meshd_dbus_object, "handle-get-meshconf-info",
1145 G_CALLBACK(_wmeshd_dbus_handle_get_meshconf_info), service);
1147 ret = g_dbus_interface_skeleton_export(G_DBUS_INTERFACE_SKELETON(meshd_dbus_object),
1148 conn, WMESH_DBUS_OBJPATH, &error);
1150 WMESH_LOGE("g_dbus_interface_skeleton_export() Fail(%s)", error->message);
1151 g_error_free(error);
1154 ret = _wmeshd_dbus_subscribe_name_owner_changed(conn);
1155 if (WMESHD_ERROR_NONE != ret) {
1156 WMESH_LOGE("_wmeshd_dbus_subscribe_name_owner_changed() Fail(%d)", ret);
1161 static void _wmeshd_dbus_on_name_lost(GDBusConnection *conn, const gchar *name,
1167 WMESH_LOGD("Lost the name %s", name);
1170 static void _wmeshd_dbus_on_name_acquired(GDBusConnection *conn, const gchar *name,
1176 WMESH_LOGD("Acquired the name %s", name);
1179 static gboolean _wmeshd_dbus_interface_init(wmesh_service *service)
1182 guint activation_dbus_id;
1183 wmeshd_check_null_ret_error("service", service, FALSE);
1185 id = g_bus_own_name(G_BUS_TYPE_SYSTEM,
1186 WMESH_DBUS_INTERFACE,
1187 G_BUS_NAME_OWNER_FLAGS_REPLACE,
1188 _wmeshd_dbus_on_bus_acquired,
1189 _wmeshd_dbus_on_name_acquired,
1190 _wmeshd_dbus_on_name_lost,
1194 WMESH_LOGE("g_bus_own_name() Fail");
1198 /* Get D-Bus owner to activate mesh service daemon */
1199 activation_dbus_id = g_bus_own_name(G_BUS_TYPE_SYSTEM,
1200 WMESH_DBUS_INTERFACE".manager",
1201 G_BUS_NAME_OWNER_FLAGS_REPLACE,
1202 _wmeshd_dbus_on_activator_bus_acquired,
1208 service->dbus_id = id;
1209 service->activation_dbus_id = activation_dbus_id;
1210 service->interface_info = g_new0(wmesh_interface_s, 1);
1211 service->scanned_mesh_network = NULL;
1213 /* Initialize DBus sendor logic */
1214 wmeshd_dbus_start(service);
1219 static void _wmeshd_dbus_deinit(wmesh_service *service)
1221 wmesh_interface_s *info = NULL;
1222 wmeshd_check_null_ret("service", service);
1224 /* De-Initialize DBus sendor logic */
1225 wmeshd_dbus_stop(service);
1227 g_bus_unown_name(service->dbus_id);
1228 g_bus_unown_name(service->activation_dbus_id);
1230 info = service->interface_info;
1231 wmeshd_check_null_ret("info", info);
1232 if (info->bridge_interface)
1233 g_free(info->bridge_interface);
1234 if (info->base_interface)
1235 g_free(info->base_interface);
1236 if (info->mesh_interface)
1237 g_free(info->mesh_interface);
1238 if (info->softap_interface)
1239 g_free(info->softap_interface);
1240 if (info->external_interface)
1241 g_free(info->external_interface);
1243 if (service->joined_network) {
1244 g_free(service->joined_network->mesh_id);
1245 g_free(service->joined_network->bssid);
1246 g_free(service->joined_network);
1247 service->joined_network = NULL;
1250 /* Clear scan list */
1251 if (service->scanned_mesh_network)
1252 g_list_free_full(service->scanned_mesh_network, _on_scan_result_destroy);
1253 service->scanned_mesh_network = NULL;
1255 /* Clear connected peers list */
1256 if (service->connected_mesh_peers)
1257 g_list_free_full(service->connected_mesh_peers, _on_peer_info_destroy);
1258 service->connected_mesh_peers = NULL;
1260 /* Clear mesh path list */
1261 if (service->mpath_list)
1262 g_list_free_full(service->mpath_list, _on_mpath_list_destroy);
1263 service->mpath_list = NULL;
1265 /* Clear mesh station list */
1266 if (service->station_list)
1267 g_list_free_full(service->station_list, _on_station_list_destroy);
1268 service->station_list = NULL;
1270 g_free(service->interface_info);
1271 service->interface_info = NULL;
1274 /**< Mesh service interface initialization */
1275 gboolean wmeshd_service_interface_init(wmesh_service *service)
1278 wmeshd_check_null_ret_error("service", service, FALSE);
1280 /* Initialize dbus interface */
1281 ret = _wmeshd_dbus_interface_init(service);
1283 WMESH_LOGE("_wmeshd_dbus_interface_init failed!!!");
1290 /**< Mesh service interface de-initialization */
1291 void wmeshd_service_interface_deinit(wmesh_service *service)
1293 wmeshd_check_null_ret("service", service);
1295 /* De-initialize dbus interface */
1296 _wmeshd_dbus_deinit(service);