2 * Network Configuration Module
4 * Copyright (c) 2017 Samsung Electronics Co., Ltd. All rights reserved.
6 * Licensed under the Apache License, Version 2.0 (the "License");
7 * you may not use this file except in compliance with the License.
8 * You may obtain a copy of the License at
10 * http://www.apache.org/licenses/LICENSE-2.0
12 * Unless required by applicable law or agreed to in writing, software
13 * distributed under the License is distributed on an "AS IS" BASIS,
14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 * See the License for the specific language governing permissions and
16 * limitations under the License.
27 #include "mesh-util.h"
28 #include "mesh-gdbus.h"
29 #include "mesh-service.h"
30 #include "mesh-service-interface.h"
31 #include "mesh-generated-code.h"
33 #include "mesh-request.h"
34 #include "mesh-interface.h"
36 static NetMesh *meshd_dbus_object;
37 static Manager *meshd_activator_dbus_object;
39 /* global list to care resource handle for each client */
40 static GList *meshd_dbus_client_list;
41 static GMutex meshd_dbus_client_list_mutex;
43 typedef struct _meshd_dbus_client_s {
45 } meshd_dbus_client_s;
47 NetMesh* meshd_dbus_get_object()
49 return meshd_dbus_object;
52 int64_t meshd_dbus_generate_signal_number()
59 static int _meshd_dbus_client_list_cleanup(GList *client_list)
61 meshd_dbus_client_s *client;
63 meshd_check_null_ret_error("client_list", client_list, FALSE);
65 client = client_list->data;
67 free(client->bus_name);
68 client->bus_name = NULL;
70 g_list_free(client_list);
72 return MESHD_ERROR_NONE;
75 static int _meshd_dbus_client_list_compare_bus_name(const void *a, const void *b)
77 const meshd_dbus_client_s *client = a;
79 return g_strcmp0(client->bus_name, b);
82 static inline GList* _meshd_dbus_client_list_find_client(const gchar *owner)
84 return g_list_find_custom(meshd_dbus_client_list, owner,
85 _meshd_dbus_client_list_compare_bus_name);
88 static void _meshd_dbus_name_owner_changed_cb(GDBusConnection *conn,
89 const gchar *sender_name,
90 const gchar *object_path,
91 const gchar *interface_name,
92 const gchar *signal_name,
98 gchar *name, *old_owner, *new_owner;
101 NOTUSED(sender_name);
102 NOTUSED(object_path);
103 NOTUSED(interface_name);
104 NOTUSED(signal_name);
107 g_variant_get(parameters, "(&s&s&s)", &name, &old_owner, &new_owner);
109 if (0 == strlen(new_owner)) {
110 g_mutex_lock(&meshd_dbus_client_list_mutex);
111 client = _meshd_dbus_client_list_find_client(old_owner);
112 if (client) { /* found bus name in our bus list */
113 MESH_LOGD("bus(%s) stopped", old_owner);
114 meshd_dbus_client_list = g_list_remove_link(meshd_dbus_client_list, client);
116 g_mutex_unlock(&meshd_dbus_client_list_mutex);
119 ret = _meshd_dbus_client_list_cleanup(client);
120 if (MESHD_ERROR_NONE != ret)
121 MESH_LOGE("_meshd_dbus_client_list_cleanup() Fail(%d)", ret);
126 static int _meshd_dbus_subscribe_name_owner_changed(GDBusConnection *conn)
130 id = g_dbus_connection_signal_subscribe(conn,
131 "org.freedesktop.DBus", /* bus name */
132 "org.freedesktop.DBus", /* interface */
133 "NameOwnerChanged", /* member */
134 "/org/freedesktop/DBus", /* path */
136 G_DBUS_SIGNAL_FLAGS_NONE,
137 _meshd_dbus_name_owner_changed_cb,
141 MESH_LOGE("g_dbus_connection_signal_subscribe() Fail");
142 return MESHD_ERROR_IO_ERROR;
145 return MESHD_ERROR_NONE;
148 static gboolean _meshd_dbus_handle_enable(Manager *object,
149 GDBusMethodInvocation *invocation,
152 int ret = MESHD_ERROR_NONE;
153 mesh_service *service = (mesh_service *)user_data;
154 mesh_interface_s *info = service->interface_info;
156 if (service->mesh_activated) {
157 /* Already activated */
158 manager_complete_enable(object, invocation,
159 MESHD_ERROR_OPERATION_FAILED);
161 /* Do API response first */
162 manager_complete_enable(object, invocation, ret);
163 service->mesh_activated = TRUE;
166 meshd_check_null_ret_error("info", info, FALSE);
168 /* Register event handler first */
169 ret = mesh_request_register_event_handler();
170 if (MESHD_ERROR_NONE != ret) {
171 MESH_LOGE("Failed to register mesh event handler !! [%d]", ret);
174 ret = mesh_interface_initialize(service->interface_info);
175 if (MESHD_ERROR_NONE != ret) {
176 MESH_LOGE("Failed to mesh_interface_initialize [%d]", ret);
180 ret = mesh_request_load_saved_mesh_network(&service->saved_mesh_network);
181 if (MESHD_ERROR_NONE != ret) {
182 MESH_LOGE("Failed to mesh_request_load_saved_mesh_network [%d]", ret);
187 net_mesh_emit_mesh_enabled(meshd_dbus_get_object(), ret);
192 static gboolean _meshd_dbus_handle_disable(Manager *object,
193 GDBusMethodInvocation *invocation,
196 int ret = MESHD_ERROR_NONE;
197 mesh_service *service = (mesh_service *)user_data;
198 mesh_interface_s *info = service->interface_info;
200 meshd_check_null_ret_error("info", info, FALSE);
202 /* Make response first */
203 manager_complete_disable(object, invocation, ret);
205 ret = mesh_request_unregister_event_handler();
206 if (MESHD_ERROR_NONE != ret) {
207 MESH_LOGE("Failed to unregister mesh event handler !! [%d]", ret);
210 /* Terminate daemon */
211 meshd_service_exit(service);
216 static gboolean _meshd_dbus_handle_scan(NetMesh *object,
217 GDBusMethodInvocation *invocation,
220 int ret = MESHD_ERROR_NONE;
221 mesh_service *service = (mesh_service *)user_data;
222 mesh_interface_s *info = service->interface_info;
224 meshd_check_null_ret_error("info", info, FALSE);
226 ret = mesh_request_ipc_mesh_scan(service);
227 if (MESHD_ERROR_NONE != ret)
228 MESH_LOGE("Failed to mesh_request_ipc_mesh_scan !");
231 ret = mesh_request_scan(info->mesh_interface);
232 if (MESHD_ERROR_NONE != ret) {
233 MESH_LOGE("Failed to mesh_request_scan on mesh interface[%s] !",
234 info->mesh_interface);
238 if (MESHD_ERROR_IN_PROGRESS != ret) {
239 ret = mesh_request_scan(info->base_interface);
240 if (MESHD_ERROR_NONE != ret)
241 MESH_LOGE("Failed to mesh_request_scan on base interface[%s] !",
242 info->base_interface);
245 net_mesh_complete_scan(object, invocation, ret);
250 static gboolean _meshd_dbus_handle_specific_scan(NetMesh *object,
251 GDBusMethodInvocation *invocation,
256 int ret = MESHD_ERROR_NONE;
257 mesh_service *service = (mesh_service *)user_data;
258 mesh_interface_s *info = service->interface_info;
260 meshd_check_null_ret_error("info", info, FALSE);
262 ret = mesh_ipc_mesh_specific_scan(service, mesh_id, channel);
263 if (MESHD_ERROR_NONE != ret)
264 MESH_LOGE("Failed to mesh_request_specific_scan !");
267 ret = mesh_request_specific_scan(info->mesh_interface, mesh_id, channel);
268 if (MESHD_ERROR_NONE != ret) {
269 MESH_LOGE("Failed to mesh_request_specific_scan on mesh interface[%s]",
270 info->mesh_interface);
274 if (MESHD_ERROR_IN_PROGRESS != ret) {
275 ret = mesh_request_specific_scan(info->base_interface, mesh_id, channel);
276 if (MESHD_ERROR_NONE != ret)
277 MESH_LOGE("Failed to mesh_request_specific_scan on base interface[%s]",
278 info->base_interface);
281 net_mesh_complete_specific_scan(object, invocation, ret);
286 static gboolean _meshd_dbus_handle_cancel_scan(NetMesh *object,
287 GDBusMethodInvocation *invocation,
290 int ret = MESHD_ERROR_NONE;
291 mesh_service *service = (mesh_service *)user_data;
293 ret = mesh_request_ipc_mesh_cancel_scan(service);
294 if (MESHD_ERROR_NONE != ret) {
295 MESH_LOGE("Failed to mesh_request_ipc_mesh_cancel_scan");
298 net_mesh_complete_cancel_scan(object, invocation, ret);
303 static void _on_scan_result_destroy(gpointer data)
305 mesh_scan_result_s *scan_item = (mesh_scan_result_s *)data;
308 g_free(scan_item->mesh_id);
309 g_free(scan_item->bssid);
310 g_free(scan_item->object_path);
314 static void _on_station_list_destroy(gpointer data)
316 mesh_station_info_s *info = (mesh_station_info_s*)data;
324 static void _on_mpath_list_destroy(gpointer data)
326 mesh_mpath_info_s *info = (mesh_mpath_info_s*)data;
329 g_free(info->dest_addr);
330 g_free(info->next_hop);
331 g_free(info->interface);
336 static gboolean _meshd_dbus_handle_get_found_mesh_networks(NetMesh *object,
337 GDBusMethodInvocation *invocation,
340 int ret = MESHD_ERROR_NONE;
341 mesh_service *service = (mesh_service *)user_data;
342 //mesh_interface_s *info = service->interface_info;
344 GVariantBuilder builder;
347 mesh_scan_result_s *scan_item = NULL;
349 MESH_LOGD("Request to get scanned mesh network list");
351 ret = mesh_request_ipc_mesh_get_peers(service);
352 if (MESHD_ERROR_NONE != ret)
353 MESH_LOGE("Failed to mesh_request_ipc_mesh_get_peers");
356 ret = mesh_request_get_scan_result(info->mesh_interface, &service->scanned_mesh_network);
357 if (MESHD_ERROR_NONE != ret) {
358 MESH_LOGE("Failed to mesh_request_get_scan_result");
361 ret = mesh_request_get_scan_result(info->base_interface,
362 &service->scanned_mesh_network);
363 if (MESHD_ERROR_NONE != ret) {
364 MESH_LOGE("Failed to mesh_request_get_scan_result on base interface[%s]",
365 info->base_interface);
367 g_dbus_method_invocation_return_error(invocation,
368 G_DBUS_ERROR, G_DBUS_ERROR_FAILED, "Request Failed");
372 g_variant_builder_init(&builder, G_VARIANT_TYPE("aa{sv}"));
374 iter = service->scanned_mesh_network;
375 while (iter != NULL) {
376 scan_item = (mesh_scan_result_s*)iter->data;
378 g_variant_builder_open(&builder, G_VARIANT_TYPE_VARDICT);
379 g_variant_builder_add(&builder, "{sv}", "mesh_id",
380 g_variant_new_string(scan_item->mesh_id));
381 g_variant_builder_add(&builder, "{sv}", "bssid",
382 g_variant_new_string(scan_item->bssid));
383 g_variant_builder_add(&builder, "{sv}", "rssi",
384 g_variant_new_int32(scan_item->rssi));
385 g_variant_builder_add(&builder, "{sv}", "channel",
386 g_variant_new_uint32(scan_item->channel));
387 g_variant_builder_add(&builder, "{sv}", "security",
388 g_variant_new_uint32((int)scan_item->security));
389 g_variant_builder_add(&builder, "{sv}", "state",
390 g_variant_new_uint32(scan_item->state));
391 g_variant_builder_close(&builder);
393 iter = g_list_next(iter);
396 /* Clear scan list */
397 //g_list_free_full(service->scanned_mesh_network, _on_scan_result_destroy);
398 //service->scanned_mesh_network = NULL;
400 networks = g_variant_builder_end(&builder);
402 net_mesh_complete_get_found_mesh_networks(object, invocation, networks, ret);
407 static gboolean _meshd_dbus_handle_enable_mesh(NetMesh *object,
408 GDBusMethodInvocation *invocation,
411 int ret = MESHD_ERROR_NONE;
412 mesh_service *service = (mesh_service *)user_data;
413 //mesh_interface_s *info = service->interface_info;
415 #if 0 ///////////////////
416 /* Create or join mesh network and create bridge */
417 ret = mesh_request_enable_mesh(info->base_interface, info->mesh_interface,
418 service->saved_mesh_network, &service->joined_network);
419 if (MESHD_ERROR_NONE != ret) {
420 MESH_LOGE("Failed to mesh_request_enable_mesh [%d]", ret);
424 ret = mesh_request_create_bridge(info->bridge_interface, info->mesh_interface);
425 if (MESHD_ERROR_NONE != ret) {
426 MESH_LOGE("Failed to mesh_request_create_bridge [%d]", ret);
430 ret = mesh_request_ipc_enable_network(service);
431 if (MESHD_ERROR_NONE != ret) {
432 MESH_LOGE("Failed to mesh_request_ipc_enable_network [%d]", ret);
437 /* Detect external network state (i.e. Ethernet)
438 and decide to make gate enabled */
439 ret = mesh_request_set_mesh_gate(info->bridge_interface,
440 info->mesh_interface, info->external_interface);
441 if (MESHD_ERROR_NONE != ret) {
442 MESH_LOGE("Failed to mesh_request_set_mesh_gate [%d]", ret);
446 /* TODO: Check if specific scan is required */
447 ret = mesh_request_specific_scan(info->mesh_interface,
448 info->mesh_id, info->mesh_channel);
449 if (MESHD_ERROR_NONE != ret) {
450 MESH_LOGE("Failed to mesh_request_specific_scan [%d]", ret);
452 ret = mesh_request_get_scan_result(info->mesh_interface,
453 &service->scanned_mesh_network);
455 /* Request DHCP on bridge interface */
456 ret = mesh_request_dhcp(info->bridge_interface);
457 if (MESHD_ERROR_NONE != ret) {
458 MESH_LOGE("Failed to mesh_request_dhcp [%d]", ret);
461 /* TODO: Notify bridge status to Connman */
465 net_mesh_complete_enable_mesh(object, invocation, ret);
470 static gboolean _meshd_dbus_handle_disable_mesh(NetMesh *object,
471 GDBusMethodInvocation *invocation,
474 int ret = MESHD_ERROR_NONE;
475 mesh_service *service = (mesh_service *)user_data;
476 mesh_interface_s *info = service->interface_info;
478 meshd_check_null_ret_error("info", info, FALSE);
480 /* Destroy bridge and return from mesh to infra mode */
481 if (service->joined_network) {
482 g_free(service->joined_network->mesh_id);
483 g_free(service->joined_network);
484 service->joined_network = NULL;
487 if (FALSE == service->mesh_activated) {
488 MESH_LOGD("Mesh network is not activated yet");
489 ret = MESHD_ERROR_OPERATION_FAILED;
490 net_mesh_complete_disable_mesh(object, invocation, ret);
494 ret = mesh_request_ipc_disable_network(service);
495 if (MESHD_ERROR_NONE != ret) {
496 MESH_LOGE("Failed to disable mesh network !");
499 /* If DHCP is on progress, stop it */
500 ret = mesh_request_stop_dhcp();
501 if (MESHD_ERROR_NONE != ret) {
502 MESH_LOGE("Failed to stop DHCP request !");
505 ret = mesh_request_disable_mesh(info->mesh_interface);
506 if (MESHD_ERROR_NONE != ret) {
507 MESH_LOGE("Failed to mesh_request_disable_mesh_gate");
510 ret = mesh_request_remove_bridge(info->bridge_interface);
511 if (MESHD_ERROR_NONE != ret) {
512 MESH_LOGE("Failed to mesh_request_remove_bridge");
516 net_mesh_complete_disable_mesh(object, invocation, ret);
521 static gboolean _meshd_dbus_handle_get_joined_mesh_network(NetMesh *object,
522 GDBusMethodInvocation *invocation,
525 int ret = MESHD_ERROR_NONE;
526 mesh_service *service = (mesh_service *)user_data;
527 mesh_network_info_s *joined = NULL;
529 //gchar *meshid = strdup("meshnet");
530 //gchar *bssid = strdup("7c:dd:90:d8:2a:64");
531 //gint channel = 161;
532 //gint max_speed = 866;
533 ret = mesh_request_ipc_get_joined_network(service);
534 if (MESHD_ERROR_NONE == ret) {
535 joined = service->joined_network;
537 net_mesh_complete_get_joined_mesh_network(object, invocation,
538 joined->mesh_id, joined->bssid,
539 joined->channel, (int)joined->security,
542 net_mesh_complete_get_joined_mesh_network(object, invocation,
543 "", "", 0, 0, 0, MESHD_ERROR_NO_DATA);
546 net_mesh_complete_get_joined_mesh_network(object, invocation,
547 "", "", 0, 0, 0, ret);
553 static gboolean _meshd_dbus_handle_get_connected_peers(NetMesh *object,
554 GDBusMethodInvocation *invocation,
557 int ret = MESHD_ERROR_NONE;
558 mesh_service *service = (mesh_service *)user_data;
560 GVariantBuilder builder;
563 mesh_peer_info_s *peer = NULL;
565 MESH_LOGD("Request to get connected peers");
567 ret = mesh_ipc_get_connected_peers(service);
568 if (MESHD_ERROR_NONE != ret)
569 MESH_LOGE("Failed to mesh_ipc_get_connected_peers");
570 g_variant_builder_init(&builder, G_VARIANT_TYPE("aa{sv}"));
572 iter = service->connected_mesh_peers;
573 while (iter != NULL) {
574 peer = (mesh_peer_info_s*)iter->data;
576 g_variant_builder_open(&builder, G_VARIANT_TYPE_VARDICT);
577 g_variant_builder_add(&builder, "{sv}", "Address",
578 g_variant_new_string(peer->address));
579 g_variant_builder_close(&builder);
581 iter = g_list_next(iter);
584 peer_list = g_variant_builder_end(&builder);
586 net_mesh_complete_get_connected_peers(object, invocation, peer_list, ret);
591 static gboolean _meshd_dbus_handle_set_gate(NetMesh *object,
592 GDBusMethodInvocation *invocation, gboolean stp, gboolean gate_announce,
595 int ret = MESHD_ERROR_NONE;
596 mesh_service *service = (mesh_service *)user_data;
597 mesh_interface_s *info = service->interface_info;
599 MESH_LOGD("STP = %d", stp);
600 MESH_LOGD("gate_announce = %d", gate_announce);
602 /* Set STP and gate_announce */
603 ret = mesh_request_set_mesh_gate(info->bridge_interface,
604 info->mesh_interface, info->external_interface);
605 if (MESHD_ERROR_NONE != ret) {
606 MESH_LOGE("Failed to mesh_request_set_mesh_gate [%d]", ret);
609 net_mesh_complete_set_gate(object, invocation, ret);
614 static gboolean _meshd_dbus_handle_unset_gate(NetMesh *object,
615 GDBusMethodInvocation *invocation,
618 int ret = MESHD_ERROR_NONE;
619 mesh_service *service = (mesh_service *)user_data;
620 mesh_interface_s *info = service->interface_info;
622 ret = mesh_request_unset_mesh_gate(info->bridge_interface,
623 info->mesh_interface, info->external_interface);
624 if (MESHD_ERROR_NONE != ret) {
625 MESH_LOGE("Failed to mesh_request_unset_mesh_gate [%d]", ret);
627 net_mesh_complete_unset_gate(object, invocation, ret);
632 static gboolean _meshd_dbus_handle_set_softap(NetMesh *object,
633 GDBusMethodInvocation *invocation,
634 gchar *ssid, gchar *passphrase,
635 gchar *mode, gint channel, gint visibility, gint max_sta,
636 gint security, gpointer user_data)
638 int ret = MESHD_ERROR_NONE;
639 mesh_service *service = (mesh_service *)user_data;
640 mesh_interface_s *info = service->interface_info;
642 MESH_LOGD("SSID : %s", ssid);
643 MESH_LOGD("mode : %s", mode);
644 MESH_LOGD("channel : %d", channel);
645 MESH_LOGD("visibility: %d", visibility);
646 MESH_LOGD("max_sta : %d", max_sta);
647 MESH_LOGD("security : %d", security);
649 /* Save softAP information */
650 ret = mesh_request_set_softap_config(info->softap_interface,
651 ssid, mode, channel, visibility, max_sta,
652 security, passphrase);
653 if (MESHD_ERROR_NONE != ret) {
654 MESH_LOGE("Failed to mesh_request_set_softap_config [%d]", ret);
657 net_mesh_complete_set_softap(object, invocation, ret);
662 static gboolean _meshd_dbus_handle_enable_softap(NetMesh *object,
663 GDBusMethodInvocation *invocation, gpointer user_data)
665 int ret = MESHD_ERROR_NONE;
666 mesh_service *service = (mesh_service *)user_data;
667 mesh_interface_s *info = service->interface_info;
669 /* Check softAP interface and execute it */
670 ret = mesh_request_enable_softap(info->bridge_interface, info->softap_interface);
671 if (MESHD_ERROR_NONE != ret) {
672 MESH_LOGE("Failed to mesh_request_enable_softap [%d]", ret);
675 net_mesh_complete_enable_softap(object, invocation, ret);
680 static gboolean _meshd_dbus_handle_disable_softap(NetMesh *object,
681 GDBusMethodInvocation *invocation, gpointer user_data)
683 int ret = MESHD_ERROR_NONE;
684 mesh_service *service = (mesh_service *)user_data;
685 mesh_interface_s *info = service->interface_info;
688 ret = mesh_request_disable_softap(info->bridge_interface, info->softap_interface);
689 if (MESHD_ERROR_NONE != ret) {
690 MESH_LOGE("Failed to mesh_request_disable_softap [%d]", ret);
693 net_mesh_complete_disable_softap(object, invocation, ret);
698 static gboolean _meshd_dbus_handle_create_mesh_network(NetMesh *object,
699 GDBusMethodInvocation *invocation,
700 gchar *mesh_id, gint channel, gint security,
703 int ret = MESHD_ERROR_NONE;
704 mesh_service *service = (mesh_service *)user_data;
705 meshd_security_type_e sec = (1 == security) ? MESHD_SECURITY_SAE : MESHD_SECURITY_NONE;
707 //ret = mesh_request_add_mesh_network(&service->saved_mesh_network,
708 // mesh_id, channel, security);
709 ret = mesh_request_ipc_create_mesh_network(service, mesh_id, channel, sec);
711 net_mesh_complete_create_mesh_network(object, invocation, ret);
716 static gboolean _meshd_dbus_handle_get_saved_mesh_network(NetMesh *object,
717 GDBusMethodInvocation *invocation,
720 int ret = MESHD_ERROR_NONE;
721 mesh_service *service = (mesh_service *)user_data;
723 GVariantBuilder builder;
727 ret = mesh_request_get_saved_mesh_network(&service->saved_mesh_network);
728 if (MESHD_ERROR_NONE != ret) {
729 MESH_LOGE("Failed to mesh_request_get_saved_mesh_network");
731 g_dbus_method_invocation_return_error(invocation,
732 G_DBUS_ERROR, G_DBUS_ERROR_FAILED, "Request Failed");
734 /* TODO: Get station information and make variant data */
735 g_variant_builder_init(&builder, G_VARIANT_TYPE("aa{sv}"));
737 iter = service->saved_mesh_network;
738 while (iter != NULL) {
739 mesh_network_info_s *item = (mesh_network_info_s*)iter->data;
741 g_variant_builder_open(&builder, G_VARIANT_TYPE_VARDICT);
742 g_variant_builder_add(&builder, "{sv}", "mesh_id",
743 g_variant_new_string(item->mesh_id));
744 g_variant_builder_add(&builder, "{sv}", "channel",
745 g_variant_new_uint32(item->channel));
746 g_variant_builder_add(&builder, "{sv}", "security",
747 g_variant_new_uint32(item->security));
748 g_variant_builder_close(&builder);
750 iter = g_list_next(iter);
753 networks = g_variant_builder_end(&builder);
754 net_mesh_complete_get_saved_mesh_network(object, invocation, networks, ret);
760 static gboolean _meshd_dbus_handle_connect_mesh_network(NetMesh *object,
761 GDBusMethodInvocation *invocation,
762 gchar *mesh_id, gint channel, gint security, gchar *passphrase,
765 int ret = MESHD_ERROR_NONE;
766 mesh_service *service = (mesh_service *)user_data;
767 meshd_security_type_e sec = (1 == security) ? MESHD_SECURITY_SAE : MESHD_SECURITY_NONE;
768 //ret = mesh_request_select_saved_mesh_network(&service->saved_mesh_network,
769 // mesh_id, channel, security);
772 ret = mesh_request_ipc_connect_mesh_network(service, mesh_id, channel, sec, passphrase);
775 net_mesh_complete_connect_mesh_network(object, invocation, ret);
779 static gboolean _meshd_dbus_handle_disconnect_mesh_network(NetMesh *object,
780 GDBusMethodInvocation *invocation,
781 gchar *mesh_id, gint channel, gint security,
784 int ret = MESHD_ERROR_NONE;
785 mesh_service *service = (mesh_service *)user_data;
786 meshd_security_type_e sec = (1 == security) ? MESHD_SECURITY_SAE : MESHD_SECURITY_NONE;
788 ret = mesh_request_ipc_disconnect_mesh_network(service, mesh_id, channel, sec);
790 net_mesh_complete_disconnect_mesh_network(object, invocation, ret);
795 static gboolean _meshd_dbus_handle_forget_mesh_network(NetMesh *object,
796 GDBusMethodInvocation *invocation,
797 gchar *mesh_id, gint channel, gint security,
800 int ret = MESHD_ERROR_NONE;
801 mesh_service *service = (mesh_service *)user_data;
802 meshd_security_type_e sec = (1 == security) ? MESHD_SECURITY_SAE : MESHD_SECURITY_NONE;
804 //ret = mesh_request_forget_saved_mesh_network(&service->saved_mesh_network,
805 // mesh_id, channel, security);
806 ret = mesh_request_ipc_remove_mesh_network(service, mesh_id, channel, sec);
808 net_mesh_complete_forget_mesh_network(object, invocation, ret);
813 static gboolean _meshd_dbus_handle_set_interfaces(NetMesh *object,
814 GDBusMethodInvocation *invocation,
815 gchar *mesh, gchar *gate, gchar *softap,
818 int ret = MESHD_ERROR_NONE;
819 mesh_service *service = (mesh_service *)user_data;
820 mesh_interface_s *info = service->interface_info;
822 g_free(info->mesh_interface);
823 info->mesh_interface = g_strdup(mesh);
825 g_free(info->external_interface);
826 info->external_interface = g_strdup(gate);
828 g_free(info->softap_interface);
829 info->softap_interface = g_strdup(softap);
831 MESH_LOGD("Interface configuration for mesh network :");
832 MESH_LOGD(" Base : [%s]", info->base_interface);
833 MESH_LOGD(" Mesh : [%s]", info->mesh_interface);
834 MESH_LOGD(" Bridge : [%s]", info->bridge_interface);
835 MESH_LOGD(" SoftAP : [%s]", info->softap_interface);
836 MESH_LOGD(" External: [%s]", info->external_interface);
838 net_mesh_complete_set_interfaces(object, invocation, ret);
843 static gboolean _meshd_dbus_handle_get_station_info(NetMesh *object,
844 GDBusMethodInvocation *invocation,
847 int ret = MESHD_ERROR_NONE;
849 GVariantBuilder builder;
853 mesh_service *service = (mesh_service *)user_data;
854 mesh_interface_s *info = service->interface_info;
856 /* Clear mesh station list */
857 g_list_free_full(service->station_list, _on_station_list_destroy);
858 service->station_list = NULL;
860 ret = mesh_request_get_station_info(
861 info->mesh_interface, &service->station_list);
862 if (MESHD_ERROR_NONE != ret) {
863 MESH_LOGE("Failed to mesh_request_get_station_info");
865 g_dbus_method_invocation_return_error(invocation,
866 G_DBUS_ERROR, G_DBUS_ERROR_FAILED, "Request Failed");
869 * sh-3.2# iw mesh0 station dump
870 * Station 7c:dd:90:62:37:cf (on mesh0)
871 * inactive time: 1685 ms
880 * signal avg: -63 dBm
881 * tx bitrate: 54.0 MBit/s
882 * rx bitrate: 5.5 MBit/s
886 * mesh local PS mode: ACTIVE
887 * mesh peer PS mode: ACTIVE
888 * mesh non-peer PS mode: ACTIVE
897 * beacon interval:1000
898 * short slot time:yes
899 * connected time: 256 seconds
901 /* Get station information and make variant data */
902 g_variant_builder_init(&builder, G_VARIANT_TYPE("aa{sv}"));
904 iter = service->station_list;
905 while (iter != NULL) {
906 mesh_station_info_s *item = (mesh_station_info_s*)iter->data;
908 g_variant_builder_open(&builder, G_VARIANT_TYPE_VARDICT);
909 g_variant_builder_add(&builder, "{sv}", "bssid",
910 g_variant_new_string(item->bssid));
911 g_variant_builder_add(&builder, "{sv}", "inactive_time",
912 g_variant_new_uint32(item->inactive_time));
913 g_variant_builder_add(&builder, "{sv}", "rx_bytes",
914 g_variant_new_uint64(item->rx_bytes));
915 g_variant_builder_add(&builder, "{sv}", "rx_packets",
916 g_variant_new_uint32(item->rx_packets));
917 g_variant_builder_add(&builder, "{sv}", "tx_bytes",
918 g_variant_new_uint64(item->tx_bytes));
919 g_variant_builder_add(&builder, "{sv}", "tx_packets",
920 g_variant_new_uint32(item->tx_packets));
921 g_variant_builder_add(&builder, "{sv}", "tx_retries",
922 g_variant_new_uint32(item->tx_retries));
923 g_variant_builder_add(&builder, "{sv}", "tx_failed",
924 g_variant_new_uint32(item->tx_failed));
925 g_variant_builder_add(&builder, "{sv}", "beacon_loss",
926 g_variant_new_uint32(item->beacon_loss));
927 g_variant_builder_add(&builder, "{sv}", "beacon_rx",
928 g_variant_new_uint64(item->beacon_rx));
929 g_variant_builder_add(&builder, "{sv}", "rx_drop_misc",
930 g_variant_new_uint64(item->rx_drop_misc));
931 g_variant_builder_add(&builder, "{sv}", "signal",
932 g_variant_new_int32(item->rssi));
933 g_variant_builder_add(&builder, "{sv}", "signal_avg",
934 g_variant_new_int32(item->rssi_avg));
935 g_variant_builder_add(&builder, "{sv}", "tx_bitrate",
936 g_variant_new_uint32(item->tx_bitrate)); /* 10 times */
937 g_variant_builder_add(&builder, "{sv}", "rx_bitrate",
938 g_variant_new_uint32(item->rx_bitrate)); /* 10 times */
939 g_variant_builder_add(&builder, "{sv}", "mesh_llid",
940 g_variant_new_uint16(item->llid));
941 g_variant_builder_add(&builder, "{sv}", "mesh_plid",
942 g_variant_new_uint16(item->plid));
943 g_variant_builder_add(&builder, "{sv}", "mesh_plink",
944 g_variant_new_byte(item->mesh_plink)); /* 0 : DISCON, 1 : ESTAB */
945 g_variant_builder_add(&builder, "{sv}", "local_ps_mode",
946 g_variant_new_uint32(item->local_ps_mode)); /* 0 : INACTIVE, 1 : ACTIVE */
947 g_variant_builder_add(&builder, "{sv}", "peer_ps_mode",
948 g_variant_new_uint32(item->peer_ps_mode)); /* 0 : INACTIVE, 1 : ACTIVE */
949 g_variant_builder_add(&builder, "{sv}", "non_peer_ps_mode",
950 g_variant_new_uint32(item->non_peer_ps_mode)); /* 0 : INACTIVE, 1 : ACTIVE */
951 g_variant_builder_add(&builder, "{sv}", "authorized",
952 g_variant_new_boolean(item->authorized));
953 g_variant_builder_add(&builder, "{sv}", "associated",
954 g_variant_new_boolean(item->associated));
955 g_variant_builder_add(&builder, "{sv}", "preamble",
956 g_variant_new_boolean(item->preamble));
957 g_variant_builder_add(&builder, "{sv}", "WMM_WME",
958 g_variant_new_boolean(item->wme));
959 g_variant_builder_add(&builder, "{sv}", "MFP",
960 g_variant_new_boolean(item->mfp));
961 g_variant_builder_add(&builder, "{sv}", "TDLS_peer",
962 g_variant_new_boolean(item->tdls_peer));
963 g_variant_builder_add(&builder, "{sv}", "DTIM_period",
964 g_variant_new_byte(item->dtim_period));
965 g_variant_builder_add(&builder, "{sv}", "beacon_interval",
966 g_variant_new_uint16(item->beacon_interval));
967 g_variant_builder_add(&builder, "{sv}", "short_slot_time",
968 g_variant_new_boolean(item->short_slot_time));
969 g_variant_builder_add(&builder, "{sv}", "connected_time",
970 g_variant_new_uint32(item->connected_time));
971 g_variant_builder_close(&builder);
973 iter = g_list_next(iter);
976 station = g_variant_builder_end(&builder);
977 net_mesh_complete_get_station_info(object, invocation, station, ret);
979 g_object_unref(station);
983 g_variant_builder_init(&builder, G_VARIANT_TYPE_VARDICT);
984 g_variant_builder_add(&builder, "{sv}", "station", g_variant_new_string("7c:dd:90:62:37:cf"));
985 g_variant_builder_add(&builder, "{sv}", "inactive_time", g_variant_new_uint32(1685));
986 g_variant_builder_add(&builder, "{sv}", "rx_bytes", g_variant_new_uint32(34174));
987 g_variant_builder_add(&builder, "{sv}", "rx_packets", g_variant_new_uint32(1181));
988 g_variant_builder_add(&builder, "{sv}", "tx_bytes", g_variant_new_uint32(6877));
989 g_variant_builder_add(&builder, "{sv}", "tx_packets", g_variant_new_uint32(76));
990 g_variant_builder_add(&builder, "{sv}", "tx_retries", g_variant_new_uint32(0));
991 g_variant_builder_add(&builder, "{sv}", "tx_failed", g_variant_new_uint32(0));
992 g_variant_builder_add(&builder, "{sv}", "beacon_loss", g_variant_new_uint32(0));
993 g_variant_builder_add(&builder, "{sv}", "signal", g_variant_new_int32(-64));
994 g_variant_builder_add(&builder, "{sv}", "signal_avg", g_variant_new_int32(-63));
995 g_variant_builder_add(&builder, "{sv}", "tx_bitrate", g_variant_new_uint32(540)); /* 10 times */
996 g_variant_builder_add(&builder, "{sv}", "rx_bitrate", g_variant_new_uint32(55)); /* 10 times */
997 g_variant_builder_add(&builder, "{sv}", "mesh_llid", g_variant_new_uint32(51731));
998 g_variant_builder_add(&builder, "{sv}", "mesh_plid", g_variant_new_uint32(35432));
999 g_variant_builder_add(&builder, "{sv}", "mesh_plink", g_variant_new_uint32(1)); /* 0 : DISCON, 1 : ESTAB */
1000 g_variant_builder_add(&builder, "{sv}", "mesh_local_PS_mode", g_variant_new_uint32(1)); /* 0 : INACTIVE, 1 : ACTIVE */
1001 g_variant_builder_add(&builder, "{sv}", "mesh_peer_PS_mode", g_variant_new_uint32(1)); /* 0 : INACTIVE, 1 : ACTIVE */
1002 g_variant_builder_add(&builder, "{sv}", "mesh_none_peer_PS_mode", g_variant_new_uint32(1)); /* 0 : INACTIVE, 1 : ACTIVE */
1003 g_variant_builder_add(&builder, "{sv}", "authorized", g_variant_new_boolean(TRUE));
1004 g_variant_builder_add(&builder, "{sv}", "associated", g_variant_new_boolean(TRUE));
1005 g_variant_builder_add(&builder, "{sv}", "preamble",g_variant_new_string("long"));
1006 g_variant_builder_add(&builder, "{sv}", "WMM_WME", g_variant_new_boolean(TRUE));
1007 g_variant_builder_add(&builder, "{sv}", "MFP", g_variant_new_boolean(FALSE));
1008 g_variant_builder_add(&builder, "{sv}", "TDLS_peer", g_variant_new_boolean(FALSE));
1009 g_variant_builder_add(&builder, "{sv}", "DTIM_period", g_variant_new_uint32(0));
1010 g_variant_builder_add(&builder, "{sv}", "beacon_interval", g_variant_new_uint32(1000));
1011 g_variant_builder_add(&builder, "{sv}", "short_slot_time", g_variant_new_boolean(TRUE));
1012 g_variant_builder_add(&builder, "{sv}", "connected_time", g_variant_new_uint32(256));
1013 station = g_variant_builder_end(&builder);
1015 net_mesh_complete_get_station_info(object, invocation, station, ret);
1017 g_object_unref(station);
1022 static gboolean _meshd_dbus_handle_get_mpath_info(NetMesh *object,
1023 GDBusMethodInvocation *invocation,
1026 int ret = MESHD_ERROR_NONE;
1027 GVariantBuilder builder;
1028 GVariant* mpath_data;
1031 mesh_service *service = (mesh_service *)user_data;
1032 mesh_interface_s *info = service->interface_info;
1034 /* Clear mesh path list */
1035 g_list_free_full(service->mpath_list, _on_mpath_list_destroy);
1036 service->mpath_list = NULL;
1038 ret = mesh_request_get_mpath_info(
1039 info->mesh_interface, &service->mpath_list);
1040 if (MESHD_ERROR_NONE != ret) {
1041 MESH_LOGE("Failed to mesh_request_get_mpath_info");
1043 g_dbus_method_invocation_return_error(invocation,
1044 G_DBUS_ERROR, G_DBUS_ERROR_FAILED, "Request Failed");
1047 * Example) sh-3.2# iw mesh0 mpath dump
1048 * DEST ADDR NEXT HOP IFACE SN METRIC QLEN EXPTIME DTIM DRET FLAGS
1049 * 7c:dd:90:62:37:cf 7c:dd:90:62:37:cf mesh0 221 152 0 10 100 0 0x5
1051 /* Get mesh path information and make variant data */
1052 g_variant_builder_init(&builder, G_VARIANT_TYPE("aa{sv}"));
1054 iter = service->mpath_list;
1055 while (iter != NULL) {
1056 mesh_mpath_info_s *item = (mesh_mpath_info_s*)iter->data;
1058 g_variant_builder_open(&builder, G_VARIANT_TYPE_VARDICT);
1059 g_variant_builder_add(&builder, "{sv}", "DEST_ADDR",
1060 g_variant_new_string(item->dest_addr));
1061 g_variant_builder_add(&builder, "{sv}", "NEXT_HOP",
1062 g_variant_new_string(item->next_hop));
1063 g_variant_builder_add(&builder, "{sv}", "IFACE",
1064 g_variant_new_string(item->interface));
1065 g_variant_builder_add(&builder, "{sv}", "SN",
1066 g_variant_new_uint32(item->sn));
1067 g_variant_builder_add(&builder, "{sv}", "METRIC",
1068 g_variant_new_uint32(item->metric));
1069 g_variant_builder_add(&builder, "{sv}", "QLEN",
1070 g_variant_new_uint32(item->qlen));
1071 g_variant_builder_add(&builder, "{sv}", "EXPTIME",
1072 g_variant_new_uint32(item->exptime));
1073 g_variant_builder_add(&builder, "{sv}", "DTIM",
1074 g_variant_new_uint32(item->discovery_timeout));
1075 g_variant_builder_add(&builder, "{sv}", "DRET",
1076 g_variant_new_byte(item->discovery_retries));
1077 g_variant_builder_add(&builder, "{sv}", "FLAGS",
1078 g_variant_new_byte(item->flags));
1079 g_variant_builder_close(&builder);
1081 iter = g_list_next(iter);
1084 mpath_data = g_variant_builder_end(&builder);
1085 net_mesh_complete_get_mpath_info(object, invocation, mpath_data, ret);
1087 g_object_unref(mpath_data);
1093 static void _meshd_dbus_on_activator_bus_acquired(GDBusConnection *conn,
1094 const gchar *name, gpointer user_data)
1097 GError *error = NULL;
1098 mesh_service *service = (mesh_service *)user_data;
1102 meshd_activator_dbus_object = manager_skeleton_new();
1103 if (NULL == meshd_activator_dbus_object) {
1104 MESH_LOGE("manager_skeleton_new() Fail");
1108 g_signal_connect(meshd_activator_dbus_object, "handle-enable",
1109 G_CALLBACK(_meshd_dbus_handle_enable), service);
1110 g_signal_connect(meshd_activator_dbus_object, "handle-disable",
1111 G_CALLBACK(_meshd_dbus_handle_disable), service);
1113 ret = g_dbus_interface_skeleton_export(
1114 G_DBUS_INTERFACE_SKELETON(meshd_activator_dbus_object),
1115 conn, MESH_DBUS_MANAGER_OBJPATH, &error);
1117 MESH_LOGE("g_dbus_interface_skeleton_export() Fail(%s)", error->message);
1118 g_error_free(error);
1122 static void _meshd_dbus_on_bus_acquired(GDBusConnection *conn, const gchar *name,
1126 GError *error = NULL;
1127 mesh_service *service = (mesh_service *)user_data;
1131 meshd_dbus_object = net_mesh_skeleton_new();
1132 if (NULL == meshd_dbus_object) {
1133 MESH_LOGE("net_mesh_skeleton_new() Fail");
1137 g_signal_connect(meshd_dbus_object, "handle-scan",
1138 G_CALLBACK(_meshd_dbus_handle_scan), service);
1139 g_signal_connect(meshd_dbus_object, "handle-specific-scan",
1140 G_CALLBACK(_meshd_dbus_handle_specific_scan), service);
1141 g_signal_connect(meshd_dbus_object, "handle-cancel-scan",
1142 G_CALLBACK(_meshd_dbus_handle_cancel_scan), service);
1143 g_signal_connect(meshd_dbus_object, "handle-get-found-mesh-networks",
1144 G_CALLBACK(_meshd_dbus_handle_get_found_mesh_networks), service);
1145 g_signal_connect(meshd_dbus_object, "handle-enable-mesh",
1146 G_CALLBACK(_meshd_dbus_handle_enable_mesh), service);
1147 g_signal_connect(meshd_dbus_object, "handle-disable-mesh",
1148 G_CALLBACK(_meshd_dbus_handle_disable_mesh), service);
1149 g_signal_connect(meshd_dbus_object, "handle-get-joined-mesh-network",
1150 G_CALLBACK(_meshd_dbus_handle_get_joined_mesh_network), service);
1151 g_signal_connect(meshd_dbus_object, "handle-get-connected-peers",
1152 G_CALLBACK(_meshd_dbus_handle_get_connected_peers), service);
1153 g_signal_connect(meshd_dbus_object, "handle-set-gate",
1154 G_CALLBACK(_meshd_dbus_handle_set_gate), service);
1155 g_signal_connect(meshd_dbus_object, "handle-unset-gate",
1156 G_CALLBACK(_meshd_dbus_handle_unset_gate), service);
1157 g_signal_connect(meshd_dbus_object, "handle-set-softap",
1158 G_CALLBACK(_meshd_dbus_handle_set_softap), service);
1159 g_signal_connect(meshd_dbus_object, "handle-enable-softap",
1160 G_CALLBACK(_meshd_dbus_handle_enable_softap), service);
1161 g_signal_connect(meshd_dbus_object, "handle-disable-softap",
1162 G_CALLBACK(_meshd_dbus_handle_disable_softap), service);
1163 g_signal_connect(meshd_dbus_object, "handle-create-mesh-network",
1164 G_CALLBACK(_meshd_dbus_handle_create_mesh_network), service);
1165 g_signal_connect(meshd_dbus_object, "handle-connect-mesh-network",
1166 G_CALLBACK(_meshd_dbus_handle_connect_mesh_network), service);
1167 g_signal_connect(meshd_dbus_object, "handle-disconnect-mesh-network",
1168 G_CALLBACK(_meshd_dbus_handle_disconnect_mesh_network), service);
1169 g_signal_connect(meshd_dbus_object, "handle-forget-mesh-network",
1170 G_CALLBACK(_meshd_dbus_handle_forget_mesh_network), service);
1171 g_signal_connect(meshd_dbus_object, "handle-set-interfaces",
1172 G_CALLBACK(_meshd_dbus_handle_set_interfaces), service);
1173 g_signal_connect(meshd_dbus_object, "handle-get-station-info",
1174 G_CALLBACK(_meshd_dbus_handle_get_station_info), service);
1175 g_signal_connect(meshd_dbus_object, "handle-get-mpath-info",
1176 G_CALLBACK(_meshd_dbus_handle_get_mpath_info), service);
1178 ret = g_dbus_interface_skeleton_export(G_DBUS_INTERFACE_SKELETON(meshd_dbus_object),
1179 conn, MESH_DBUS_OBJPATH, &error);
1181 MESH_LOGE("g_dbus_interface_skeleton_export() Fail(%s)", error->message);
1182 g_error_free(error);
1185 ret = _meshd_dbus_subscribe_name_owner_changed(conn);
1186 if (MESHD_ERROR_NONE != ret) {
1187 MESH_LOGE("_meshd_dbus_subscribe_name_owner_changed() Fail(%d)", ret);
1192 static void _meshd_dbus_on_name_lost(GDBusConnection *conn, const gchar *name,
1198 MESH_LOGD("Lost the name %s", name);
1201 static void _meshd_dbus_on_name_acquired(GDBusConnection *conn, const gchar *name,
1207 MESH_LOGD("Acquired the name %s", name);
1210 static gboolean _meshd_dbus_interface_init(mesh_service *service)
1213 guint activation_dbus_id;
1214 meshd_check_null_ret_error("service", service, FALSE);
1216 id = g_bus_own_name(G_BUS_TYPE_SYSTEM,
1217 MESH_DBUS_INTERFACE,
1218 G_BUS_NAME_OWNER_FLAGS_REPLACE,
1219 _meshd_dbus_on_bus_acquired,
1220 _meshd_dbus_on_name_acquired,
1221 _meshd_dbus_on_name_lost,
1225 MESH_LOGE("g_bus_own_name() Fail");
1229 /* Get D-Bus owner to activate zigbee-daemon */
1230 activation_dbus_id = g_bus_own_name(G_BUS_TYPE_SYSTEM,
1231 MESH_DBUS_INTERFACE".manager",
1232 G_BUS_NAME_OWNER_FLAGS_REPLACE,
1233 _meshd_dbus_on_activator_bus_acquired,
1239 service->dbus_id = id;
1240 service->activation_dbus_id = activation_dbus_id;
1241 service->interface_info = g_new0(mesh_interface_s, 1);
1242 service->scanned_mesh_network = NULL;
1244 /* Initialize DBus sendor logic */
1245 meshd_dbus_start(service);
1250 static void _meshd_dbus_deinit(mesh_service *service)
1252 mesh_interface_s *info = NULL;
1253 meshd_check_null_ret("service", service);
1255 /* De-Initialize DBus sendor logic */
1256 meshd_dbus_stop(service);
1258 g_bus_unown_name(service->dbus_id);
1259 g_bus_unown_name(service->activation_dbus_id);
1261 info = service->interface_info;
1262 meshd_check_null_ret("info", info);
1263 if (info->bridge_interface)
1264 g_free(info->bridge_interface);
1265 if (info->base_interface)
1266 g_free(info->base_interface);
1267 if (info->mesh_interface)
1268 g_free(info->mesh_interface);
1269 if (info->softap_interface)
1270 g_free(info->softap_interface);
1271 if (info->external_interface)
1272 g_free(info->external_interface);
1274 if (service->joined_network) {
1275 g_free(service->joined_network->mesh_id);
1276 g_free(service->joined_network);
1277 service->joined_network = NULL;
1279 mesh_request_clear_saved_mesh_network(&service->saved_mesh_network);
1281 /* Clear scan list */
1282 g_list_free_full(service->scanned_mesh_network, _on_scan_result_destroy);
1283 service->scanned_mesh_network = NULL;
1285 g_free(service->interface_info);
1286 service->interface_info = NULL;
1289 /**< mesh service interface initialization */
1290 gboolean meshd_service_interface_init(mesh_service *service)
1293 meshd_check_null_ret_error("service", service, FALSE);
1295 /* Initialize dbus interface */
1296 ret = _meshd_dbus_interface_init(service);
1298 MESH_LOGE("zigbee_service_dbus_interface_init failed!!!");
1305 /**< Zigbee service interface de-initialization */
1306 void meshd_service_interface_deinit(mesh_service *service)
1308 meshd_check_null_ret("service", service);
1310 /* De-initialize dbus interface */
1311 _meshd_dbus_deinit(service);