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_joined(NetWmesh *object,
459 GDBusMethodInvocation *invocation,
462 int ret = WMESHD_ERROR_NONE;
463 gboolean state = FALSE;
464 wmesh_service *service = (wmesh_service *)user_data;
466 ret = wmesh_request_get_joined_network(service);
467 if (WMESHD_ERROR_NONE == ret) {
468 if (service->joined_network)
472 net_wmesh_complete_is_joined(object, invocation, state, ret);
477 static gboolean _wmeshd_dbus_handle_get_joined_mesh_network(NetWmesh *object,
478 GDBusMethodInvocation *invocation,
481 int ret = WMESHD_ERROR_NONE;
482 wmesh_service *service = (wmesh_service *)user_data;
483 wmesh_network_info_s *joined = NULL;
485 ret = wmesh_request_get_joined_network(service);
486 if (WMESHD_ERROR_NONE == ret) {
487 joined = service->joined_network;
489 net_wmesh_complete_get_joined_mesh_network(object, invocation,
490 joined->mesh_id, joined->bssid,
491 joined->channel, (int)joined->security,
494 net_wmesh_complete_get_joined_mesh_network(object, invocation,
495 "", "", 0, 0, 0, WMESHD_ERROR_NO_DATA);
498 net_wmesh_complete_get_joined_mesh_network(object, invocation,
499 "", "", 0, 0, 0, ret);
505 static gboolean _wmeshd_dbus_handle_get_connected_peers(NetWmesh *object,
506 GDBusMethodInvocation *invocation,
509 int ret = WMESHD_ERROR_NONE;
510 wmesh_service *service = (wmesh_service *)user_data;
512 GVariantBuilder builder;
515 wmesh_peer_info_s *peer = NULL;
517 WMESH_LOGD("Request to get connected peers");
519 ret = wmesh_request_get_connected_peers(service);
520 if (WMESHD_ERROR_NONE != ret)
521 WMESH_LOGE("Failed to wmesh_request_get_connected_peers");
522 g_variant_builder_init(&builder, G_VARIANT_TYPE("aa{sv}"));
524 iter = service->connected_mesh_peers;
525 while (iter != NULL) {
526 peer = (wmesh_peer_info_s*)iter->data;
528 g_variant_builder_open(&builder, G_VARIANT_TYPE_VARDICT);
529 g_variant_builder_add(&builder, "{sv}", "Address",
530 g_variant_new_string(peer->address));
531 g_variant_builder_close(&builder);
533 iter = g_list_next(iter);
536 peer_list = g_variant_builder_end(&builder);
538 net_wmesh_complete_get_connected_peers(object, invocation, peer_list, ret);
543 static gboolean _wmeshd_dbus_handle_set_gate(NetWmesh *object,
544 GDBusMethodInvocation *invocation, gint16 gate_announce, guint hwmp_root_mode,
545 gboolean stp, gpointer user_data)
547 int ret = WMESHD_ERROR_NONE;
548 wmesh_service *service = (wmesh_service *)user_data;
549 wmesh_interface_s *info = service->interface_info;
551 WMESH_LOGD("gate_announce = %d", gate_announce);
552 WMESH_LOGD("HWMP_Root_Mode = %d", hwmp_root_mode);
553 WMESH_LOGD("STP = %d", stp);
555 info->gate_announce = gate_announce;
556 info->hwmp_root_mode = hwmp_root_mode;
559 /* Set STP and gate_announce for connmand */
560 ret = wmesh_gdbus_set_mesh_gate(service);
561 if (WMESHD_ERROR_NONE != ret)
562 WMESH_LOGE("Failed to wmesh_gdbus_set_mesh_gate [%d]", ret);
564 /* Set STP and gate_announce right now */
565 ret = wmesh_request_set_mesh_gate(info->bridge_interface,
566 info->mesh_interface, info->external_interface);
567 if (WMESHD_ERROR_NONE != ret)
568 WMESH_LOGE("Failed to wmesh_gdbus_set_mesh_gate [%d]", ret);
571 net_wmesh_complete_set_gate(object, invocation, ret);
576 static gboolean _wmeshd_dbus_handle_unset_gate(NetWmesh *object,
577 GDBusMethodInvocation *invocation,
580 int ret = WMESHD_ERROR_NONE;
581 wmesh_service *service = (wmesh_service *)user_data;
582 wmesh_interface_s *info = service->interface_info;
584 info->gate_announce = 0;
585 info->hwmp_root_mode = 0;
588 /* Set STP and gate_announce for connmand */
589 ret = wmesh_gdbus_set_mesh_gate(service);
590 if (WMESHD_ERROR_NONE != ret)
591 WMESH_LOGE("Failed to wmesh_gdbus_set_mesh_gate [%d]", ret);
593 /* Unset STP and Gate Annouce right now */
594 ret = wmesh_request_unset_mesh_gate(info->bridge_interface,
595 info->mesh_interface, info->external_interface);
596 if (WMESHD_ERROR_NONE != ret)
597 WMESH_LOGE("Failed to wmesh_request_unset_mesh_gate [%d]", ret);
599 net_wmesh_complete_unset_gate(object, invocation, ret);
604 static gboolean _wmeshd_dbus_handle_set_softap(NetWmesh *object,
605 GDBusMethodInvocation *invocation,
606 gchar *ssid, gchar *passphrase,
607 gchar *mode, gint channel, gint visibility, gint max_sta,
608 gint security, gpointer user_data)
610 int ret = WMESHD_ERROR_NONE;
611 wmesh_service *service = (wmesh_service *)user_data;
612 wmesh_interface_s *info = service->interface_info;
614 WMESH_LOGD("SSID : %s", ssid);
615 WMESH_LOGD("mode : %s", mode);
616 WMESH_LOGD("channel : %d", channel);
617 WMESH_LOGD("visibility: %d", visibility);
618 WMESH_LOGD("max_sta : %d", max_sta);
619 WMESH_LOGD("security : %d", security);
621 /* Save softAP information */
622 ret = wmesh_request_set_softap_config(info->softap_interface,
623 ssid, mode, channel, visibility, max_sta,
624 security, passphrase);
625 if (WMESHD_ERROR_NONE != ret)
626 WMESH_LOGE("Failed to wmesh_request_set_softap_config [%d]", ret);
628 net_wmesh_complete_set_softap(object, invocation, ret);
633 static gboolean _wmeshd_dbus_handle_enable_softap(NetWmesh *object,
634 GDBusMethodInvocation *invocation, gpointer user_data)
636 int ret = WMESHD_ERROR_NONE;
637 wmesh_service *service = (wmesh_service *)user_data;
638 wmesh_interface_s *info = service->interface_info;
640 /* Check softAP interface and execute it */
641 ret = wmesh_request_enable_softap(info->bridge_interface, info->softap_interface);
642 if (WMESHD_ERROR_NONE != ret)
643 WMESH_LOGE("Failed to wmesh_request_enable_softap [%d]", ret);
645 net_wmesh_complete_enable_softap(object, invocation, ret);
650 static gboolean _wmeshd_dbus_handle_disable_softap(NetWmesh *object,
651 GDBusMethodInvocation *invocation, gpointer user_data)
653 int ret = WMESHD_ERROR_NONE;
654 wmesh_service *service = (wmesh_service *)user_data;
655 wmesh_interface_s *info = service->interface_info;
658 ret = wmesh_request_disable_softap(info->bridge_interface, info->softap_interface);
659 if (WMESHD_ERROR_NONE != ret)
660 WMESH_LOGE("Failed to wmesh_request_disable_softap [%d]", ret);
662 net_wmesh_complete_disable_softap(object, invocation, ret);
667 static gboolean _wmeshd_dbus_handle_create_mesh_network(NetWmesh *object,
668 GDBusMethodInvocation *invocation,
669 gchar *mesh_id, gint channel, gint security,
672 int ret = WMESHD_ERROR_NONE;
673 wmesh_service *service = (wmesh_service *)user_data;
674 wmeshd_security_type_e sec = (1 == security) ? WMESHD_SECURITY_SAE : WMESHD_SECURITY_NONE;
676 ret = wmesh_request_create_mesh_network(service, mesh_id, channel, sec);
678 net_wmesh_complete_create_mesh_network(object, invocation, ret);
683 static gboolean _wmeshd_dbus_handle_connect_mesh_network(NetWmesh *object,
684 GDBusMethodInvocation *invocation,
685 gchar *mesh_id, gint channel, gint security, gchar *passphrase,
688 int ret = WMESHD_ERROR_NONE;
689 wmesh_service *service = (wmesh_service *)user_data;
690 wmeshd_security_type_e sec = (1 == security) ? WMESHD_SECURITY_SAE : WMESHD_SECURITY_NONE;
692 ret = wmesh_request_connect_mesh_network(service, mesh_id, channel, sec, passphrase);
694 net_wmesh_complete_connect_mesh_network(object, invocation, ret);
698 static gboolean _wmeshd_dbus_handle_disconnect_mesh_network(NetWmesh *object,
699 GDBusMethodInvocation *invocation,
700 gchar *mesh_id, gint channel, gint security,
703 int ret = WMESHD_ERROR_NONE;
704 wmesh_service *service = (wmesh_service *)user_data;
705 wmeshd_security_type_e sec = (1 == security) ? WMESHD_SECURITY_SAE : WMESHD_SECURITY_NONE;
707 ret = wmesh_request_disconnect_mesh_network(service, mesh_id, channel, sec);
709 net_wmesh_complete_disconnect_mesh_network(object, invocation, ret);
714 static gboolean _wmeshd_dbus_handle_forget_mesh_network(NetWmesh *object,
715 GDBusMethodInvocation *invocation,
716 gchar *mesh_id, gint channel, gint security,
719 int ret = WMESHD_ERROR_NONE;
720 wmesh_service *service = (wmesh_service *)user_data;
721 wmeshd_security_type_e sec = (1 == security) ? WMESHD_SECURITY_SAE : WMESHD_SECURITY_NONE;
723 ret = wmesh_request_remove_mesh_network(service, mesh_id, channel, sec);
725 net_wmesh_complete_forget_mesh_network(object, invocation, ret);
730 static gboolean _wmeshd_dbus_handle_set_interfaces(NetWmesh *object,
731 GDBusMethodInvocation *invocation,
732 gchar *mesh, gchar *gate, gchar *softap,
735 int ret = WMESHD_ERROR_NONE;
736 wmesh_service *service = (wmesh_service *)user_data;
737 wmesh_interface_s *info = service->interface_info;
739 g_free(info->mesh_interface);
740 info->mesh_interface = g_strdup(mesh);
742 g_free(info->external_interface);
743 info->external_interface = g_strdup(gate);
745 g_free(info->softap_interface);
746 info->softap_interface = g_strdup(softap);
748 WMESH_LOGD("Interface configuration for mesh network :");
749 WMESH_LOGD(" Base : [%s]", info->base_interface);
750 WMESH_LOGD(" Mesh : [%s]", info->mesh_interface);
751 WMESH_LOGD(" Bridge : [%s]", info->bridge_interface);
752 WMESH_LOGD(" SoftAP : [%s]", info->softap_interface);
753 WMESH_LOGD(" External: [%s]", info->external_interface);
755 net_wmesh_complete_set_interfaces(object, invocation, ret);
760 static gboolean _wmeshd_dbus_handle_get_station_info(NetWmesh *object,
761 GDBusMethodInvocation *invocation,
764 int ret = WMESHD_ERROR_NONE;
766 GVariantBuilder builder;
770 wmesh_service *service = (wmesh_service *)user_data;
771 wmesh_interface_s *info = service->interface_info;
773 /* Clear mesh station list */
774 g_list_free_full(service->station_list, _on_station_list_destroy);
775 service->station_list = NULL;
777 ret = wmesh_request_get_station_info(
778 info->mesh_interface, &service->station_list);
779 if (WMESHD_ERROR_NONE != ret) {
780 WMESH_LOGE("Failed to wmesh_request_get_station_info");
782 g_dbus_method_invocation_return_error(invocation,
783 G_DBUS_ERROR, G_DBUS_ERROR_FAILED, "Request Failed");
786 * sh-3.2# iw mesh0 station dump
787 * Station 7c:dd:90:62:37:cf (on mesh0)
788 * inactive time: 1685 ms
797 * signal avg: -63 dBm
798 * tx bitrate: 54.0 MBit/s
799 * rx bitrate: 5.5 MBit/s
803 * mesh local PS mode: ACTIVE
804 * mesh peer PS mode: ACTIVE
805 * mesh non-peer PS mode: ACTIVE
814 * beacon interval:1000
815 * short slot time:yes
816 * connected time: 256 seconds
818 /* Get station information and make variant data */
819 g_variant_builder_init(&builder, G_VARIANT_TYPE("aa{sv}"));
821 iter = service->station_list;
822 while (iter != NULL) {
823 wmesh_station_info_s *item = (wmesh_station_info_s*)iter->data;
825 g_variant_builder_open(&builder, G_VARIANT_TYPE_VARDICT);
826 g_variant_builder_add(&builder, "{sv}", "bssid",
827 g_variant_new_string(item->bssid));
828 g_variant_builder_add(&builder, "{sv}", "inactive_time",
829 g_variant_new_uint32(item->inactive_time));
830 g_variant_builder_add(&builder, "{sv}", "rx_bytes",
831 g_variant_new_uint64(item->rx_bytes));
832 g_variant_builder_add(&builder, "{sv}", "rx_packets",
833 g_variant_new_uint32(item->rx_packets));
834 g_variant_builder_add(&builder, "{sv}", "tx_bytes",
835 g_variant_new_uint64(item->tx_bytes));
836 g_variant_builder_add(&builder, "{sv}", "tx_packets",
837 g_variant_new_uint32(item->tx_packets));
838 g_variant_builder_add(&builder, "{sv}", "tx_retries",
839 g_variant_new_uint32(item->tx_retries));
840 g_variant_builder_add(&builder, "{sv}", "tx_failed",
841 g_variant_new_uint32(item->tx_failed));
842 g_variant_builder_add(&builder, "{sv}", "beacon_loss",
843 g_variant_new_uint32(item->beacon_loss));
844 g_variant_builder_add(&builder, "{sv}", "beacon_rx",
845 g_variant_new_uint64(item->beacon_rx));
846 g_variant_builder_add(&builder, "{sv}", "rx_drop_misc",
847 g_variant_new_uint64(item->rx_drop_misc));
848 g_variant_builder_add(&builder, "{sv}", "signal",
849 g_variant_new_int32(item->rssi));
850 g_variant_builder_add(&builder, "{sv}", "signal_avg",
851 g_variant_new_int32(item->rssi_avg));
852 g_variant_builder_add(&builder, "{sv}", "tx_bitrate",
853 g_variant_new_uint32(item->tx_bitrate)); /* 10 times */
854 g_variant_builder_add(&builder, "{sv}", "rx_bitrate",
855 g_variant_new_uint32(item->rx_bitrate)); /* 10 times */
856 g_variant_builder_add(&builder, "{sv}", "mesh_llid",
857 g_variant_new_uint16(item->llid));
858 g_variant_builder_add(&builder, "{sv}", "mesh_plid",
859 g_variant_new_uint16(item->plid));
860 g_variant_builder_add(&builder, "{sv}", "mesh_plink",
861 g_variant_new_byte(item->mesh_plink)); /* 0 : DISCON, 1 : ESTAB */
862 g_variant_builder_add(&builder, "{sv}", "local_ps_mode",
863 g_variant_new_uint32(item->local_ps_mode)); /* 0 : INACTIVE, 1 : ACTIVE */
864 g_variant_builder_add(&builder, "{sv}", "peer_ps_mode",
865 g_variant_new_uint32(item->peer_ps_mode)); /* 0 : INACTIVE, 1 : ACTIVE */
866 g_variant_builder_add(&builder, "{sv}", "non_peer_ps_mode",
867 g_variant_new_uint32(item->non_peer_ps_mode)); /* 0 : INACTIVE, 1 : ACTIVE */
868 g_variant_builder_add(&builder, "{sv}", "authorized",
869 g_variant_new_boolean(item->authorized));
870 g_variant_builder_add(&builder, "{sv}", "associated",
871 g_variant_new_boolean(item->associated));
872 g_variant_builder_add(&builder, "{sv}", "preamble",
873 g_variant_new_boolean(item->preamble));
874 g_variant_builder_add(&builder, "{sv}", "WMM_WME",
875 g_variant_new_boolean(item->wme));
876 g_variant_builder_add(&builder, "{sv}", "MFP",
877 g_variant_new_boolean(item->mfp));
878 g_variant_builder_add(&builder, "{sv}", "TDLS_peer",
879 g_variant_new_boolean(item->tdls_peer));
880 g_variant_builder_add(&builder, "{sv}", "DTIM_period",
881 g_variant_new_byte(item->dtim_period));
882 g_variant_builder_add(&builder, "{sv}", "beacon_interval",
883 g_variant_new_uint16(item->beacon_interval));
884 g_variant_builder_add(&builder, "{sv}", "short_slot_time",
885 g_variant_new_boolean(item->short_slot_time));
886 g_variant_builder_add(&builder, "{sv}", "connected_time",
887 g_variant_new_uint32(item->connected_time));
888 g_variant_builder_close(&builder);
890 iter = g_list_next(iter);
893 station = g_variant_builder_end(&builder);
894 net_wmesh_complete_get_station_info(object, invocation, station, ret);
896 g_object_unref(station);
902 static gboolean _wmeshd_dbus_handle_get_mpath_info(NetWmesh *object,
903 GDBusMethodInvocation *invocation,
906 int ret = WMESHD_ERROR_NONE;
907 GVariantBuilder builder;
908 GVariant* mpath_data;
911 wmesh_service *service = (wmesh_service *)user_data;
912 wmesh_interface_s *info = service->interface_info;
914 /* Clear mesh path list */
915 g_list_free_full(service->mpath_list, _on_mpath_list_destroy);
916 service->mpath_list = NULL;
918 ret = wmesh_request_get_mpath_info(
919 info->mesh_interface, &service->mpath_list);
920 if (WMESHD_ERROR_NONE != ret) {
921 WMESH_LOGE("Failed to wmesh_request_get_mpath_info");
923 g_dbus_method_invocation_return_error(invocation,
924 G_DBUS_ERROR, G_DBUS_ERROR_FAILED, "Request Failed");
927 * Example) sh-3.2# iw mesh0 mpath dump
928 * DEST ADDR NEXT HOP IFACE SN METRIC QLEN EXPTIME DTIM DRET FLAGS
929 * 7c:dd:90:62:37:cf 7c:dd:90:62:37:cf mesh0 221 152 0 10 100 0 0x5
931 /* Get mesh path information and make variant data */
932 g_variant_builder_init(&builder, G_VARIANT_TYPE("aa{sv}"));
934 iter = service->mpath_list;
935 while (iter != NULL) {
936 wmesh_mpath_info_s *item = (wmesh_mpath_info_s*)iter->data;
938 g_variant_builder_open(&builder, G_VARIANT_TYPE_VARDICT);
939 g_variant_builder_add(&builder, "{sv}", "DEST_ADDR",
940 g_variant_new_string(item->dest_addr));
941 g_variant_builder_add(&builder, "{sv}", "NEXT_HOP",
942 g_variant_new_string(item->next_hop));
943 g_variant_builder_add(&builder, "{sv}", "IFACE",
944 g_variant_new_string(item->interface));
945 g_variant_builder_add(&builder, "{sv}", "SN",
946 g_variant_new_uint32(item->sn));
947 g_variant_builder_add(&builder, "{sv}", "METRIC",
948 g_variant_new_uint32(item->metric));
949 g_variant_builder_add(&builder, "{sv}", "QLEN",
950 g_variant_new_uint32(item->qlen));
951 g_variant_builder_add(&builder, "{sv}", "EXPTIME",
952 g_variant_new_uint32(item->exptime));
953 g_variant_builder_add(&builder, "{sv}", "DTIM",
954 g_variant_new_uint32(item->discovery_timeout));
955 g_variant_builder_add(&builder, "{sv}", "DRET",
956 g_variant_new_byte(item->discovery_retries));
957 g_variant_builder_add(&builder, "{sv}", "FLAGS",
958 g_variant_new_byte(item->flags));
959 g_variant_builder_close(&builder);
961 iter = g_list_next(iter);
964 mpath_data = g_variant_builder_end(&builder);
965 net_wmesh_complete_get_mpath_info(object, invocation, mpath_data, ret);
967 g_object_unref(mpath_data);
973 static void _wmeshd_dbus_on_activator_bus_acquired(GDBusConnection *conn,
974 const gchar *name, gpointer user_data)
977 GError *error = NULL;
978 wmesh_service *service = (wmesh_service *)user_data;
982 meshd_activator_dbus_object = manager_skeleton_new();
983 if (NULL == meshd_activator_dbus_object) {
984 WMESH_LOGE("manager_skeleton_new() Fail");
988 g_signal_connect(meshd_activator_dbus_object, "handle-enable",
989 G_CALLBACK(_wmeshd_dbus_handle_enable), service);
990 g_signal_connect(meshd_activator_dbus_object, "handle-disable",
991 G_CALLBACK(_wmeshd_dbus_handle_disable), service);
993 ret = g_dbus_interface_skeleton_export(
994 G_DBUS_INTERFACE_SKELETON(meshd_activator_dbus_object),
995 conn, WMESH_DBUS_MANAGER_OBJPATH, &error);
997 WMESH_LOGE("g_dbus_interface_skeleton_export() Fail(%s)", error->message);
1002 static void _wmeshd_dbus_on_bus_acquired(GDBusConnection *conn, const gchar *name,
1006 GError *error = NULL;
1007 wmesh_service *service = (wmesh_service *)user_data;
1011 meshd_dbus_object = net_wmesh_skeleton_new();
1012 if (NULL == meshd_dbus_object) {
1013 WMESH_LOGE("net_wmesh_skeleton_new() Fail");
1017 g_signal_connect(meshd_dbus_object, "handle-scan",
1018 G_CALLBACK(_wmeshd_dbus_handle_scan), service);
1019 g_signal_connect(meshd_dbus_object, "handle-specific-scan",
1020 G_CALLBACK(_wmeshd_dbus_handle_specific_scan), service);
1021 g_signal_connect(meshd_dbus_object, "handle-cancel-scan",
1022 G_CALLBACK(_wmeshd_dbus_handle_cancel_scan), service);
1023 g_signal_connect(meshd_dbus_object, "handle-get-found-mesh-networks",
1024 G_CALLBACK(_wmeshd_dbus_handle_get_found_mesh_networks), service);
1025 g_signal_connect(meshd_dbus_object, "handle-enable-mesh",
1026 G_CALLBACK(_wmeshd_dbus_handle_enable_mesh), service);
1027 g_signal_connect(meshd_dbus_object, "handle-disable-mesh",
1028 G_CALLBACK(_wmeshd_dbus_handle_disable_mesh), service);
1029 g_signal_connect(meshd_dbus_object, "handle-is-joined",
1030 G_CALLBACK(_wmeshd_dbus_handle_is_joined), service);
1031 g_signal_connect(meshd_dbus_object, "handle-get-joined-mesh-network",
1032 G_CALLBACK(_wmeshd_dbus_handle_get_joined_mesh_network), service);
1033 g_signal_connect(meshd_dbus_object, "handle-get-connected-peers",
1034 G_CALLBACK(_wmeshd_dbus_handle_get_connected_peers), service);
1035 g_signal_connect(meshd_dbus_object, "handle-set-gate",
1036 G_CALLBACK(_wmeshd_dbus_handle_set_gate), service);
1037 g_signal_connect(meshd_dbus_object, "handle-unset-gate",
1038 G_CALLBACK(_wmeshd_dbus_handle_unset_gate), service);
1039 g_signal_connect(meshd_dbus_object, "handle-set-softap",
1040 G_CALLBACK(_wmeshd_dbus_handle_set_softap), service);
1041 g_signal_connect(meshd_dbus_object, "handle-enable-softap",
1042 G_CALLBACK(_wmeshd_dbus_handle_enable_softap), service);
1043 g_signal_connect(meshd_dbus_object, "handle-disable-softap",
1044 G_CALLBACK(_wmeshd_dbus_handle_disable_softap), service);
1045 g_signal_connect(meshd_dbus_object, "handle-create-mesh-network",
1046 G_CALLBACK(_wmeshd_dbus_handle_create_mesh_network), service);
1047 g_signal_connect(meshd_dbus_object, "handle-connect-mesh-network",
1048 G_CALLBACK(_wmeshd_dbus_handle_connect_mesh_network), service);
1049 g_signal_connect(meshd_dbus_object, "handle-disconnect-mesh-network",
1050 G_CALLBACK(_wmeshd_dbus_handle_disconnect_mesh_network), service);
1051 g_signal_connect(meshd_dbus_object, "handle-forget-mesh-network",
1052 G_CALLBACK(_wmeshd_dbus_handle_forget_mesh_network), service);
1053 g_signal_connect(meshd_dbus_object, "handle-set-interfaces",
1054 G_CALLBACK(_wmeshd_dbus_handle_set_interfaces), service);
1055 g_signal_connect(meshd_dbus_object, "handle-get-station-info",
1056 G_CALLBACK(_wmeshd_dbus_handle_get_station_info), service);
1057 g_signal_connect(meshd_dbus_object, "handle-get-mpath-info",
1058 G_CALLBACK(_wmeshd_dbus_handle_get_mpath_info), service);
1060 ret = g_dbus_interface_skeleton_export(G_DBUS_INTERFACE_SKELETON(meshd_dbus_object),
1061 conn, WMESH_DBUS_OBJPATH, &error);
1063 WMESH_LOGE("g_dbus_interface_skeleton_export() Fail(%s)", error->message);
1064 g_error_free(error);
1067 ret = _wmeshd_dbus_subscribe_name_owner_changed(conn);
1068 if (WMESHD_ERROR_NONE != ret) {
1069 WMESH_LOGE("_wmeshd_dbus_subscribe_name_owner_changed() Fail(%d)", ret);
1074 static void _wmeshd_dbus_on_name_lost(GDBusConnection *conn, const gchar *name,
1080 WMESH_LOGD("Lost the name %s", name);
1083 static void _wmeshd_dbus_on_name_acquired(GDBusConnection *conn, const gchar *name,
1089 WMESH_LOGD("Acquired the name %s", name);
1092 static gboolean _wmeshd_dbus_interface_init(wmesh_service *service)
1095 guint activation_dbus_id;
1096 wmeshd_check_null_ret_error("service", service, FALSE);
1098 id = g_bus_own_name(G_BUS_TYPE_SYSTEM,
1099 WMESH_DBUS_INTERFACE,
1100 G_BUS_NAME_OWNER_FLAGS_REPLACE,
1101 _wmeshd_dbus_on_bus_acquired,
1102 _wmeshd_dbus_on_name_acquired,
1103 _wmeshd_dbus_on_name_lost,
1107 WMESH_LOGE("g_bus_own_name() Fail");
1111 /* Get D-Bus owner to activate mesh service daemon */
1112 activation_dbus_id = g_bus_own_name(G_BUS_TYPE_SYSTEM,
1113 WMESH_DBUS_INTERFACE".manager",
1114 G_BUS_NAME_OWNER_FLAGS_REPLACE,
1115 _wmeshd_dbus_on_activator_bus_acquired,
1121 service->dbus_id = id;
1122 service->activation_dbus_id = activation_dbus_id;
1123 service->interface_info = g_new0(wmesh_interface_s, 1);
1124 service->scanned_mesh_network = NULL;
1126 /* Initialize DBus sendor logic */
1127 wmeshd_dbus_start(service);
1132 static void _wmeshd_dbus_deinit(wmesh_service *service)
1134 wmesh_interface_s *info = NULL;
1135 wmeshd_check_null_ret("service", service);
1137 /* De-Initialize DBus sendor logic */
1138 wmeshd_dbus_stop(service);
1140 g_bus_unown_name(service->dbus_id);
1141 g_bus_unown_name(service->activation_dbus_id);
1143 info = service->interface_info;
1144 wmeshd_check_null_ret("info", info);
1145 if (info->bridge_interface)
1146 g_free(info->bridge_interface);
1147 if (info->base_interface)
1148 g_free(info->base_interface);
1149 if (info->mesh_interface)
1150 g_free(info->mesh_interface);
1151 if (info->softap_interface)
1152 g_free(info->softap_interface);
1153 if (info->external_interface)
1154 g_free(info->external_interface);
1156 if (service->joined_network) {
1157 g_free(service->joined_network->mesh_id);
1158 g_free(service->joined_network->bssid);
1159 g_free(service->joined_network);
1160 service->joined_network = NULL;
1163 /* Clear scan list */
1164 if (service->scanned_mesh_network)
1165 g_list_free_full(service->scanned_mesh_network, _on_scan_result_destroy);
1166 service->scanned_mesh_network = NULL;
1168 /* Clear connected peers list */
1169 if (service->connected_mesh_peers)
1170 g_list_free_full(service->connected_mesh_peers, _on_peer_info_destroy);
1171 service->connected_mesh_peers = NULL;
1173 /* Clear mesh path list */
1174 if (service->mpath_list)
1175 g_list_free_full(service->mpath_list, _on_mpath_list_destroy);
1176 service->mpath_list = NULL;
1178 /* Clear mesh station list */
1179 if (service->station_list)
1180 g_list_free_full(service->station_list, _on_station_list_destroy);
1181 service->station_list = NULL;
1183 g_free(service->interface_info);
1184 service->interface_info = NULL;
1187 /**< Mesh service interface initialization */
1188 gboolean wmeshd_service_interface_init(wmesh_service *service)
1191 wmeshd_check_null_ret_error("service", service, FALSE);
1193 /* Initialize dbus interface */
1194 ret = _wmeshd_dbus_interface_init(service);
1196 WMESH_LOGE("_wmeshd_dbus_interface_init failed!!!");
1203 /**< Mesh service interface de-initialization */
1204 void wmeshd_service_interface_deinit(wmesh_service *service)
1206 wmeshd_check_null_ret("service", service);
1208 /* De-initialize dbus interface */
1209 _wmeshd_dbus_deinit(service);