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,
512 joined->state, joined->ipv4_type, joined->ipv4_address,
513 joined->ipv4_netmask, ret);
515 net_wmesh_complete_get_joined_mesh_network(object, invocation,
516 "", "", 0, 0, 0, 0, "", "", WMESHD_ERROR_NO_DATA);
519 net_wmesh_complete_get_joined_mesh_network(object, invocation,
520 "", "", 0, 0, 0, 0, "", "", ret);
526 static gboolean _wmeshd_dbus_handle_get_connected_peers(NetWmesh *object,
527 GDBusMethodInvocation *invocation,
530 int ret = WMESHD_ERROR_NONE;
531 wmesh_service *service = (wmesh_service *)user_data;
533 GVariantBuilder builder;
536 wmesh_peer_info_s *peer = NULL;
538 WMESH_LOGD("Request to get connected peers");
540 ret = wmesh_request_get_connected_peers(service);
541 if (WMESHD_ERROR_NONE != ret)
542 WMESH_LOGE("Failed to wmesh_request_get_connected_peers");
543 g_variant_builder_init(&builder, G_VARIANT_TYPE("aa{sv}"));
545 iter = service->connected_mesh_peers;
546 while (iter != NULL) {
547 peer = (wmesh_peer_info_s*)iter->data;
549 g_variant_builder_open(&builder, G_VARIANT_TYPE_VARDICT);
550 g_variant_builder_add(&builder, "{sv}", "Address",
551 g_variant_new_string(peer->address));
552 g_variant_builder_close(&builder);
554 iter = g_list_next(iter);
557 peer_list = g_variant_builder_end(&builder);
559 net_wmesh_complete_get_connected_peers(object, invocation, peer_list, ret);
564 static gboolean _wmeshd_dbus_handle_set_gate(NetWmesh *object,
565 GDBusMethodInvocation *invocation, gint16 gate_announce, guint hwmp_root_mode,
566 gboolean stp, gpointer user_data)
568 int ret = WMESHD_ERROR_NONE;
569 wmesh_service *service = (wmesh_service *)user_data;
570 wmesh_interface_s *info = service->interface_info;
572 WMESH_LOGD("gate_announce = %d", gate_announce);
573 WMESH_LOGD("HWMP_Root_Mode = %d", hwmp_root_mode);
574 WMESH_LOGD("STP = %d", stp);
576 info->gate_announce = gate_announce;
577 info->hwmp_root_mode = hwmp_root_mode;
580 /* Set STP and gate_announce for connmand */
581 ret = wmesh_gdbus_set_mesh_gate(service);
582 if (WMESHD_ERROR_NONE != ret)
583 WMESH_LOGE("Failed to wmesh_gdbus_set_mesh_gate [%d]", ret);
585 /* Set STP and gate_announce right now */
586 ret = wmesh_request_set_mesh_gate(info->bridge_interface,
587 info->mesh_interface, info->external_interface);
588 if (WMESHD_ERROR_NONE != ret)
589 WMESH_LOGE("Failed to wmesh_gdbus_set_mesh_gate [%d]", ret);
592 net_wmesh_complete_set_gate(object, invocation, ret);
597 static gboolean _wmeshd_dbus_handle_unset_gate(NetWmesh *object,
598 GDBusMethodInvocation *invocation,
601 int ret = WMESHD_ERROR_NONE;
602 wmesh_service *service = (wmesh_service *)user_data;
603 wmesh_interface_s *info = service->interface_info;
605 info->gate_announce = 0;
606 info->hwmp_root_mode = 0;
609 /* Set STP and gate_announce for connmand */
610 ret = wmesh_gdbus_set_mesh_gate(service);
611 if (WMESHD_ERROR_NONE != ret)
612 WMESH_LOGE("Failed to wmesh_gdbus_set_mesh_gate [%d]", ret);
614 /* Unset STP and Gate Annouce right now */
615 ret = wmesh_request_unset_mesh_gate(info->bridge_interface,
616 info->mesh_interface, info->external_interface);
617 if (WMESHD_ERROR_NONE != ret)
618 WMESH_LOGE("Failed to wmesh_request_unset_mesh_gate [%d]", ret);
620 net_wmesh_complete_unset_gate(object, invocation, ret);
625 static gboolean _wmeshd_dbus_handle_set_softap(NetWmesh *object,
626 GDBusMethodInvocation *invocation,
627 gchar *ssid, gchar *passphrase,
628 gchar *mode, gint channel, gint visibility, gint max_sta,
629 gint security, gpointer user_data)
631 int ret = WMESHD_ERROR_NONE;
632 wmesh_service *service = (wmesh_service *)user_data;
633 wmesh_interface_s *info = service->interface_info;
635 WMESH_LOGD("SSID : %s", ssid);
636 WMESH_LOGD("mode : %s", mode);
637 WMESH_LOGD("channel : %d", channel);
638 WMESH_LOGD("visibility: %d", visibility);
639 WMESH_LOGD("max_sta : %d", max_sta);
640 WMESH_LOGD("security : %d", security);
642 /* Save softAP information */
643 ret = wmesh_request_set_softap_config(info->softap_interface,
644 ssid, mode, channel, visibility, max_sta,
645 security, passphrase);
646 if (WMESHD_ERROR_NONE != ret)
647 WMESH_LOGE("Failed to wmesh_request_set_softap_config [%d]", ret);
649 net_wmesh_complete_set_softap(object, invocation, ret);
654 static gboolean _wmeshd_dbus_handle_enable_softap(NetWmesh *object,
655 GDBusMethodInvocation *invocation, gpointer user_data)
657 int ret = WMESHD_ERROR_NONE;
658 wmesh_service *service = (wmesh_service *)user_data;
659 wmesh_interface_s *info = service->interface_info;
661 /* Check softAP interface and execute it */
662 ret = wmesh_request_enable_softap(info->bridge_interface, info->softap_interface);
663 if (WMESHD_ERROR_NONE != ret)
664 WMESH_LOGE("Failed to wmesh_request_enable_softap [%d]", ret);
666 net_wmesh_complete_enable_softap(object, invocation, ret);
671 static gboolean _wmeshd_dbus_handle_disable_softap(NetWmesh *object,
672 GDBusMethodInvocation *invocation, gpointer user_data)
674 int ret = WMESHD_ERROR_NONE;
675 wmesh_service *service = (wmesh_service *)user_data;
676 wmesh_interface_s *info = service->interface_info;
679 ret = wmesh_request_disable_softap(info->bridge_interface, info->softap_interface);
680 if (WMESHD_ERROR_NONE != ret)
681 WMESH_LOGE("Failed to wmesh_request_disable_softap [%d]", ret);
683 net_wmesh_complete_disable_softap(object, invocation, ret);
688 static gboolean _wmeshd_dbus_handle_create_mesh_network(NetWmesh *object,
689 GDBusMethodInvocation *invocation,
690 gchar *mesh_id, gint channel, gint security,
693 int ret = WMESHD_ERROR_NONE;
694 wmesh_service *service = (wmesh_service *)user_data;
695 wmeshd_security_type_e sec = (1 == security) ? WMESHD_SECURITY_SAE : WMESHD_SECURITY_NONE;
697 ret = wmesh_request_create_mesh_network(service, mesh_id, channel, sec);
699 net_wmesh_complete_create_mesh_network(object, invocation, ret);
704 static gboolean _wmeshd_dbus_handle_connect_mesh_network(NetWmesh *object,
705 GDBusMethodInvocation *invocation,
706 gchar *mesh_id, gint channel, gint security, gchar *passphrase,
709 int ret = WMESHD_ERROR_NONE;
710 wmesh_service *service = (wmesh_service *)user_data;
711 wmeshd_security_type_e sec = (1 == security) ? WMESHD_SECURITY_SAE : WMESHD_SECURITY_NONE;
713 ret = wmesh_request_connect_mesh_network(service, mesh_id, channel, sec, passphrase);
715 net_wmesh_complete_connect_mesh_network(object, invocation, ret);
719 static gboolean _wmeshd_dbus_handle_disconnect_mesh_network(NetWmesh *object,
720 GDBusMethodInvocation *invocation,
721 gchar *mesh_id, gint channel, gint security,
724 int ret = WMESHD_ERROR_NONE;
725 wmesh_service *service = (wmesh_service *)user_data;
726 wmeshd_security_type_e sec = (1 == security) ? WMESHD_SECURITY_SAE : WMESHD_SECURITY_NONE;
728 ret = wmesh_request_disconnect_mesh_network(service, mesh_id, channel, sec);
730 net_wmesh_complete_disconnect_mesh_network(object, invocation, ret);
735 static gboolean _wmeshd_dbus_handle_forget_mesh_network(NetWmesh *object,
736 GDBusMethodInvocation *invocation,
737 gchar *mesh_id, gint channel, gint security,
740 int ret = WMESHD_ERROR_NONE;
741 wmesh_service *service = (wmesh_service *)user_data;
742 wmeshd_security_type_e sec = (1 == security) ? WMESHD_SECURITY_SAE : WMESHD_SECURITY_NONE;
744 ret = wmesh_request_remove_mesh_network(service, mesh_id, channel, sec);
746 net_wmesh_complete_forget_mesh_network(object, invocation, ret);
751 static gboolean _wmeshd_dbus_handle_set_interfaces(NetWmesh *object,
752 GDBusMethodInvocation *invocation,
753 gchar *mesh, gchar *gate, gchar *softap,
756 int ret = WMESHD_ERROR_NONE;
757 wmesh_service *service = (wmesh_service *)user_data;
758 wmesh_interface_s *info = service->interface_info;
760 g_free(info->mesh_interface);
761 info->mesh_interface = g_strdup(mesh);
763 g_free(info->external_interface);
764 info->external_interface = g_strdup(gate);
766 g_free(info->softap_interface);
767 info->softap_interface = g_strdup(softap);
769 WMESH_LOGD("Interface configuration for mesh network :");
770 WMESH_LOGD(" Base : [%s]", info->base_interface);
771 WMESH_LOGD(" Mesh : [%s]", info->mesh_interface);
772 WMESH_LOGD(" Bridge : [%s]", info->bridge_interface);
773 WMESH_LOGD(" SoftAP : [%s]", info->softap_interface);
774 WMESH_LOGD(" External: [%s]", info->external_interface);
776 net_wmesh_complete_set_interfaces(object, invocation, ret);
781 static gboolean _wmeshd_dbus_handle_get_station_info(NetWmesh *object,
782 GDBusMethodInvocation *invocation,
785 int ret = WMESHD_ERROR_NONE;
787 GVariantBuilder builder;
791 wmesh_service *service = (wmesh_service *)user_data;
792 wmesh_interface_s *info = service->interface_info;
794 /* Clear mesh station list */
795 g_list_free_full(service->station_list, _on_station_list_destroy);
796 service->station_list = NULL;
798 ret = wmesh_request_get_station_info(
799 info->mesh_interface, &service->station_list);
800 if (WMESHD_ERROR_NONE != ret) {
801 WMESH_LOGE("Failed to wmesh_request_get_station_info");
803 g_dbus_method_invocation_return_error(invocation,
804 G_DBUS_ERROR, G_DBUS_ERROR_FAILED, "Request Failed");
807 * sh-3.2# iw mesh0 station dump
808 * Station 7c:dd:90:62:37:cf (on mesh0)
809 * inactive time: 1685 ms
818 * signal avg: -63 dBm
819 * tx bitrate: 54.0 MBit/s
820 * rx bitrate: 5.5 MBit/s
824 * mesh local PS mode: ACTIVE
825 * mesh peer PS mode: ACTIVE
826 * mesh non-peer PS mode: ACTIVE
835 * beacon interval:1000
836 * short slot time:yes
837 * connected time: 256 seconds
839 /* Get station information and make variant data */
840 g_variant_builder_init(&builder, G_VARIANT_TYPE("aa{sv}"));
842 iter = service->station_list;
843 while (iter != NULL) {
844 wmesh_station_info_s *item = (wmesh_station_info_s*)iter->data;
846 g_variant_builder_open(&builder, G_VARIANT_TYPE_VARDICT);
847 g_variant_builder_add(&builder, "{sv}", "bssid",
848 g_variant_new_string(item->bssid));
849 g_variant_builder_add(&builder, "{sv}", "inactive_time",
850 g_variant_new_uint32(item->inactive_time));
851 g_variant_builder_add(&builder, "{sv}", "rx_bytes",
852 g_variant_new_uint64(item->rx_bytes));
853 g_variant_builder_add(&builder, "{sv}", "rx_packets",
854 g_variant_new_uint32(item->rx_packets));
855 g_variant_builder_add(&builder, "{sv}", "tx_bytes",
856 g_variant_new_uint64(item->tx_bytes));
857 g_variant_builder_add(&builder, "{sv}", "tx_packets",
858 g_variant_new_uint32(item->tx_packets));
859 g_variant_builder_add(&builder, "{sv}", "tx_retries",
860 g_variant_new_uint32(item->tx_retries));
861 g_variant_builder_add(&builder, "{sv}", "tx_failed",
862 g_variant_new_uint32(item->tx_failed));
863 g_variant_builder_add(&builder, "{sv}", "beacon_loss",
864 g_variant_new_uint32(item->beacon_loss));
865 g_variant_builder_add(&builder, "{sv}", "beacon_rx",
866 g_variant_new_uint64(item->beacon_rx));
867 g_variant_builder_add(&builder, "{sv}", "rx_drop_misc",
868 g_variant_new_uint64(item->rx_drop_misc));
869 g_variant_builder_add(&builder, "{sv}", "signal",
870 g_variant_new_int32(item->rssi));
871 g_variant_builder_add(&builder, "{sv}", "signal_avg",
872 g_variant_new_int32(item->rssi_avg));
873 g_variant_builder_add(&builder, "{sv}", "tx_bitrate",
874 g_variant_new_uint32(item->tx_bitrate)); /* 10 times */
875 g_variant_builder_add(&builder, "{sv}", "rx_bitrate",
876 g_variant_new_uint32(item->rx_bitrate)); /* 10 times */
877 g_variant_builder_add(&builder, "{sv}", "mesh_llid",
878 g_variant_new_uint16(item->llid));
879 g_variant_builder_add(&builder, "{sv}", "mesh_plid",
880 g_variant_new_uint16(item->plid));
881 g_variant_builder_add(&builder, "{sv}", "mesh_plink",
882 g_variant_new_byte(item->mesh_plink)); /* 0 : DISCON, 1 : ESTAB */
883 g_variant_builder_add(&builder, "{sv}", "local_ps_mode",
884 g_variant_new_uint32(item->local_ps_mode)); /* 0 : INACTIVE, 1 : ACTIVE */
885 g_variant_builder_add(&builder, "{sv}", "peer_ps_mode",
886 g_variant_new_uint32(item->peer_ps_mode)); /* 0 : INACTIVE, 1 : ACTIVE */
887 g_variant_builder_add(&builder, "{sv}", "non_peer_ps_mode",
888 g_variant_new_uint32(item->non_peer_ps_mode)); /* 0 : INACTIVE, 1 : ACTIVE */
889 g_variant_builder_add(&builder, "{sv}", "authorized",
890 g_variant_new_boolean(item->authorized));
891 g_variant_builder_add(&builder, "{sv}", "associated",
892 g_variant_new_boolean(item->associated));
893 g_variant_builder_add(&builder, "{sv}", "preamble",
894 g_variant_new_boolean(item->preamble));
895 g_variant_builder_add(&builder, "{sv}", "WMM_WME",
896 g_variant_new_boolean(item->wme));
897 g_variant_builder_add(&builder, "{sv}", "MFP",
898 g_variant_new_boolean(item->mfp));
899 g_variant_builder_add(&builder, "{sv}", "TDLS_peer",
900 g_variant_new_boolean(item->tdls_peer));
901 g_variant_builder_add(&builder, "{sv}", "DTIM_period",
902 g_variant_new_byte(item->dtim_period));
903 g_variant_builder_add(&builder, "{sv}", "beacon_interval",
904 g_variant_new_uint16(item->beacon_interval));
905 g_variant_builder_add(&builder, "{sv}", "short_slot_time",
906 g_variant_new_boolean(item->short_slot_time));
907 g_variant_builder_add(&builder, "{sv}", "connected_time",
908 g_variant_new_uint32(item->connected_time));
909 g_variant_builder_close(&builder);
911 iter = g_list_next(iter);
914 station = g_variant_builder_end(&builder);
915 net_wmesh_complete_get_station_info(object, invocation, station, ret);
917 g_object_unref(station);
923 static gboolean _wmeshd_dbus_handle_get_mpath_info(NetWmesh *object,
924 GDBusMethodInvocation *invocation,
927 int ret = WMESHD_ERROR_NONE;
928 GVariantBuilder builder;
929 GVariant* mpath_data;
932 wmesh_service *service = (wmesh_service *)user_data;
933 wmesh_interface_s *info = service->interface_info;
935 /* Clear mesh path list */
936 g_list_free_full(service->mpath_list, _on_mpath_list_destroy);
937 service->mpath_list = NULL;
939 ret = wmesh_request_get_mpath_info(
940 info->mesh_interface, &service->mpath_list);
941 if (WMESHD_ERROR_NONE != ret) {
942 WMESH_LOGE("Failed to wmesh_request_get_mpath_info");
944 g_dbus_method_invocation_return_error(invocation,
945 G_DBUS_ERROR, G_DBUS_ERROR_FAILED, "Request Failed");
948 * Example) sh-3.2# iw mesh0 mpath dump
949 * DEST ADDR NEXT HOP IFACE SN METRIC QLEN EXPTIME DTIM DRET FLAGS
950 * 7c:dd:90:62:37:cf 7c:dd:90:62:37:cf mesh0 221 152 0 10 100 0 0x5
952 /* Get mesh path information and make variant data */
953 g_variant_builder_init(&builder, G_VARIANT_TYPE("aa{sv}"));
955 iter = service->mpath_list;
956 while (iter != NULL) {
957 wmesh_mpath_info_s *item = (wmesh_mpath_info_s*)iter->data;
959 g_variant_builder_open(&builder, G_VARIANT_TYPE_VARDICT);
960 g_variant_builder_add(&builder, "{sv}", "DEST_ADDR",
961 g_variant_new_string(item->dest_addr));
962 g_variant_builder_add(&builder, "{sv}", "NEXT_HOP",
963 g_variant_new_string(item->next_hop));
964 g_variant_builder_add(&builder, "{sv}", "IFACE",
965 g_variant_new_string(item->interface));
966 g_variant_builder_add(&builder, "{sv}", "SN",
967 g_variant_new_uint32(item->sn));
968 g_variant_builder_add(&builder, "{sv}", "METRIC",
969 g_variant_new_uint32(item->metric));
970 g_variant_builder_add(&builder, "{sv}", "QLEN",
971 g_variant_new_uint32(item->qlen));
972 g_variant_builder_add(&builder, "{sv}", "EXPTIME",
973 g_variant_new_uint32(item->exptime));
974 g_variant_builder_add(&builder, "{sv}", "DTIM",
975 g_variant_new_uint32(item->discovery_timeout));
976 g_variant_builder_add(&builder, "{sv}", "DRET",
977 g_variant_new_byte(item->discovery_retries));
978 g_variant_builder_add(&builder, "{sv}", "FLAGS",
979 g_variant_new_byte(item->flags));
980 g_variant_builder_close(&builder);
982 iter = g_list_next(iter);
985 mpath_data = g_variant_builder_end(&builder);
986 net_wmesh_complete_get_mpath_info(object, invocation, mpath_data, ret);
988 g_object_unref(mpath_data);
994 static gboolean _wmeshd_dbus_handle_get_meshconf_info(NetWmesh *object,
995 GDBusMethodInvocation *invocation,
998 int ret = WMESHD_ERROR_NONE;
999 GVariantBuilder builder;
1000 GVariant* meshconf_data;
1001 wmesh_meshconf_info_s *item;
1003 wmesh_service *service = (wmesh_service *)user_data;
1005 ret = wmesh_request_get_meshconf_info(service);
1006 if (WMESHD_ERROR_NONE != ret) {
1007 WMESH_LOGE("Failed to wmesh_request_get_mpath_info");
1009 g_dbus_method_invocation_return_error(invocation,
1010 G_DBUS_ERROR, G_DBUS_ERROR_FAILED, "Request Failed");
1012 /* Get mesh path information and make variant data */
1013 g_variant_builder_init(&builder, G_VARIANT_TYPE("a{sv}"));
1015 item = service->meshconf;
1017 g_variant_builder_add(&builder, "{sv}", "RETRY_TIMEOUT",
1018 g_variant_new_uint16(item->retry_timeout));
1019 g_variant_builder_add(&builder, "{sv}", "HWMP_MAX_PREQ_RETRIES",
1020 g_variant_new_byte(item->hwmp_max_preq_retries));
1021 g_variant_builder_add(&builder, "{sv}", "CONFIRM_TIMEOUT",
1022 g_variant_new_uint16(item->confirm_timeout));
1023 g_variant_builder_add(&builder, "{sv}", "PATH_REFRESH_TIME",
1024 g_variant_new_uint32(item->path_refresh_time));
1025 g_variant_builder_add(&builder, "{sv}", "HOLDING_TIMEOUT",
1026 g_variant_new_uint16(item->holding_timeout));
1027 g_variant_builder_add(&builder, "{sv}", "MIN_DISC_TIMEOUT",
1028 g_variant_new_uint16(item->min_disc_timeout));
1029 g_variant_builder_add(&builder, "{sv}", "MAX_PEER_LINKS",
1030 g_variant_new_uint16(item->max_peer_links));
1031 g_variant_builder_add(&builder, "{sv}", "HWMP_PREQ_MIN_INTERVAL",
1032 g_variant_new_uint16(item->hwmp_preq_min_interval));
1033 g_variant_builder_add(&builder, "{sv}", "TTL",
1034 g_variant_new_byte(item->ttl));
1035 g_variant_builder_add(&builder, "{sv}", "HWMP_ACTIVE_PATH_TIMEOUT",
1036 g_variant_new_uint32(item->hwmp_active_path_timeout));
1037 g_variant_builder_add(&builder, "{sv}", "ELEMENT_TTL",
1038 g_variant_new_byte(item->element_ttl));
1039 g_variant_builder_add(&builder, "{sv}", "HWMP_RANN_INTERVAL",
1040 g_variant_new_uint16(item->hwmp_rann_interval));
1041 g_variant_builder_add(&builder, "{sv}", "GATE_ANNOUNCEMENTS",
1042 g_variant_new_byte(item->gate_announcements));
1045 meshconf_data = g_variant_builder_end(&builder);
1046 net_wmesh_complete_get_meshconf_info(object, invocation, meshconf_data,
1049 g_object_unref(meshconf_data);
1052 g_free(service->meshconf);
1057 static void _wmeshd_dbus_on_activator_bus_acquired(GDBusConnection *conn,
1058 const gchar *name, gpointer user_data)
1061 GError *error = NULL;
1062 wmesh_service *service = (wmesh_service *)user_data;
1066 meshd_activator_dbus_object = manager_skeleton_new();
1067 if (NULL == meshd_activator_dbus_object) {
1068 WMESH_LOGE("manager_skeleton_new() Fail");
1072 g_signal_connect(meshd_activator_dbus_object, "handle-enable",
1073 G_CALLBACK(_wmeshd_dbus_handle_enable), service);
1074 g_signal_connect(meshd_activator_dbus_object, "handle-disable",
1075 G_CALLBACK(_wmeshd_dbus_handle_disable), service);
1077 ret = g_dbus_interface_skeleton_export(
1078 G_DBUS_INTERFACE_SKELETON(meshd_activator_dbus_object),
1079 conn, WMESH_DBUS_MANAGER_OBJPATH, &error);
1081 WMESH_LOGE("g_dbus_interface_skeleton_export() Fail(%s)", error->message);
1082 g_error_free(error);
1086 static void _wmeshd_dbus_on_bus_acquired(GDBusConnection *conn, const gchar *name,
1090 GError *error = NULL;
1091 wmesh_service *service = (wmesh_service *)user_data;
1095 meshd_dbus_object = net_wmesh_skeleton_new();
1096 if (NULL == meshd_dbus_object) {
1097 WMESH_LOGE("net_wmesh_skeleton_new() Fail");
1101 g_signal_connect(meshd_dbus_object, "handle-scan",
1102 G_CALLBACK(_wmeshd_dbus_handle_scan), service);
1103 g_signal_connect(meshd_dbus_object, "handle-specific-scan",
1104 G_CALLBACK(_wmeshd_dbus_handle_specific_scan), service);
1105 g_signal_connect(meshd_dbus_object, "handle-cancel-scan",
1106 G_CALLBACK(_wmeshd_dbus_handle_cancel_scan), service);
1107 g_signal_connect(meshd_dbus_object, "handle-get-found-mesh-networks",
1108 G_CALLBACK(_wmeshd_dbus_handle_get_found_mesh_networks), service);
1109 g_signal_connect(meshd_dbus_object, "handle-enable-mesh",
1110 G_CALLBACK(_wmeshd_dbus_handle_enable_mesh), service);
1111 g_signal_connect(meshd_dbus_object, "handle-disable-mesh",
1112 G_CALLBACK(_wmeshd_dbus_handle_disable_mesh), service);
1113 g_signal_connect(meshd_dbus_object, "handle-is-mesh-enabled",
1114 G_CALLBACK(_wmeshd_dbus_handle_is_mesh_enabled), service);
1115 g_signal_connect(meshd_dbus_object, "handle-is-joined",
1116 G_CALLBACK(_wmeshd_dbus_handle_is_joined), service);
1117 g_signal_connect(meshd_dbus_object, "handle-get-joined-mesh-network",
1118 G_CALLBACK(_wmeshd_dbus_handle_get_joined_mesh_network), service);
1119 g_signal_connect(meshd_dbus_object, "handle-get-connected-peers",
1120 G_CALLBACK(_wmeshd_dbus_handle_get_connected_peers), service);
1121 g_signal_connect(meshd_dbus_object, "handle-set-gate",
1122 G_CALLBACK(_wmeshd_dbus_handle_set_gate), service);
1123 g_signal_connect(meshd_dbus_object, "handle-unset-gate",
1124 G_CALLBACK(_wmeshd_dbus_handle_unset_gate), service);
1125 g_signal_connect(meshd_dbus_object, "handle-set-softap",
1126 G_CALLBACK(_wmeshd_dbus_handle_set_softap), service);
1127 g_signal_connect(meshd_dbus_object, "handle-enable-softap",
1128 G_CALLBACK(_wmeshd_dbus_handle_enable_softap), service);
1129 g_signal_connect(meshd_dbus_object, "handle-disable-softap",
1130 G_CALLBACK(_wmeshd_dbus_handle_disable_softap), service);
1131 g_signal_connect(meshd_dbus_object, "handle-create-mesh-network",
1132 G_CALLBACK(_wmeshd_dbus_handle_create_mesh_network), service);
1133 g_signal_connect(meshd_dbus_object, "handle-connect-mesh-network",
1134 G_CALLBACK(_wmeshd_dbus_handle_connect_mesh_network), service);
1135 g_signal_connect(meshd_dbus_object, "handle-disconnect-mesh-network",
1136 G_CALLBACK(_wmeshd_dbus_handle_disconnect_mesh_network), service);
1137 g_signal_connect(meshd_dbus_object, "handle-forget-mesh-network",
1138 G_CALLBACK(_wmeshd_dbus_handle_forget_mesh_network), service);
1139 g_signal_connect(meshd_dbus_object, "handle-set-interfaces",
1140 G_CALLBACK(_wmeshd_dbus_handle_set_interfaces), service);
1141 g_signal_connect(meshd_dbus_object, "handle-get-station-info",
1142 G_CALLBACK(_wmeshd_dbus_handle_get_station_info), service);
1143 g_signal_connect(meshd_dbus_object, "handle-get-mpath-info",
1144 G_CALLBACK(_wmeshd_dbus_handle_get_mpath_info), service);
1145 g_signal_connect(meshd_dbus_object, "handle-get-meshconf-info",
1146 G_CALLBACK(_wmeshd_dbus_handle_get_meshconf_info), service);
1148 ret = g_dbus_interface_skeleton_export(G_DBUS_INTERFACE_SKELETON(meshd_dbus_object),
1149 conn, WMESH_DBUS_OBJPATH, &error);
1151 WMESH_LOGE("g_dbus_interface_skeleton_export() Fail(%s)", error->message);
1152 g_error_free(error);
1155 ret = _wmeshd_dbus_subscribe_name_owner_changed(conn);
1156 if (WMESHD_ERROR_NONE != ret) {
1157 WMESH_LOGE("_wmeshd_dbus_subscribe_name_owner_changed() Fail(%d)", ret);
1162 static void _wmeshd_dbus_on_name_lost(GDBusConnection *conn, const gchar *name,
1168 WMESH_LOGD("Lost the name %s", name);
1171 static void _wmeshd_dbus_on_name_acquired(GDBusConnection *conn, const gchar *name,
1177 WMESH_LOGD("Acquired the name %s", name);
1180 static gboolean _wmeshd_dbus_interface_init(wmesh_service *service)
1183 guint activation_dbus_id;
1184 wmeshd_check_null_ret_error("service", service, FALSE);
1186 id = g_bus_own_name(G_BUS_TYPE_SYSTEM,
1187 WMESH_DBUS_INTERFACE,
1188 G_BUS_NAME_OWNER_FLAGS_REPLACE,
1189 _wmeshd_dbus_on_bus_acquired,
1190 _wmeshd_dbus_on_name_acquired,
1191 _wmeshd_dbus_on_name_lost,
1195 WMESH_LOGE("g_bus_own_name() Fail");
1199 /* Get D-Bus owner to activate mesh service daemon */
1200 activation_dbus_id = g_bus_own_name(G_BUS_TYPE_SYSTEM,
1201 WMESH_DBUS_INTERFACE".manager",
1202 G_BUS_NAME_OWNER_FLAGS_REPLACE,
1203 _wmeshd_dbus_on_activator_bus_acquired,
1209 service->dbus_id = id;
1210 service->activation_dbus_id = activation_dbus_id;
1211 service->interface_info = g_new0(wmesh_interface_s, 1);
1212 service->scanned_mesh_network = NULL;
1214 /* Initialize DBus sendor logic */
1215 wmeshd_dbus_start(service);
1220 static void _wmeshd_dbus_deinit(wmesh_service *service)
1222 wmesh_interface_s *info = NULL;
1223 wmeshd_check_null_ret("service", service);
1225 /* De-Initialize DBus sendor logic */
1226 wmeshd_dbus_stop(service);
1228 g_bus_unown_name(service->dbus_id);
1229 g_bus_unown_name(service->activation_dbus_id);
1231 info = service->interface_info;
1232 wmeshd_check_null_ret("info", info);
1233 if (info->bridge_interface)
1234 g_free(info->bridge_interface);
1235 if (info->base_interface)
1236 g_free(info->base_interface);
1237 if (info->mesh_interface)
1238 g_free(info->mesh_interface);
1239 if (info->softap_interface)
1240 g_free(info->softap_interface);
1241 if (info->external_interface)
1242 g_free(info->external_interface);
1244 if (service->joined_network) {
1245 g_free(service->joined_network->mesh_id);
1246 g_free(service->joined_network->bssid);
1247 g_free(service->joined_network);
1248 service->joined_network = NULL;
1251 /* Clear scan list */
1252 if (service->scanned_mesh_network)
1253 g_list_free_full(service->scanned_mesh_network, _on_scan_result_destroy);
1254 service->scanned_mesh_network = NULL;
1256 /* Clear connected peers list */
1257 if (service->connected_mesh_peers)
1258 g_list_free_full(service->connected_mesh_peers, _on_peer_info_destroy);
1259 service->connected_mesh_peers = NULL;
1261 /* Clear mesh path list */
1262 if (service->mpath_list)
1263 g_list_free_full(service->mpath_list, _on_mpath_list_destroy);
1264 service->mpath_list = NULL;
1266 /* Clear mesh station list */
1267 if (service->station_list)
1268 g_list_free_full(service->station_list, _on_station_list_destroy);
1269 service->station_list = NULL;
1271 g_free(service->interface_info);
1272 service->interface_info = NULL;
1275 /**< Mesh service interface initialization */
1276 gboolean wmeshd_service_interface_init(wmesh_service *service)
1279 wmeshd_check_null_ret_error("service", service, FALSE);
1281 /* Initialize dbus interface */
1282 ret = _wmeshd_dbus_interface_init(service);
1284 WMESH_LOGE("_wmeshd_dbus_interface_init failed!!!");
1291 /**< Mesh service interface de-initialization */
1292 void wmeshd_service_interface_deinit(wmesh_service *service)
1294 wmeshd_check_null_ret("service", service);
1296 /* De-initialize dbus interface */
1297 _wmeshd_dbus_deinit(service);