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-service.h"
29 #include "mesh-service-interface.h"
30 #include "mesh-generated-code.h"
32 #include "mesh-request.h"
33 #include "mesh-interface.h"
35 static NetMesh *meshd_dbus_object;
37 /* global list to care resource handle for each client */
38 static GList *meshd_dbus_client_list;
39 static GMutex meshd_dbus_client_list_mutex;
41 typedef struct _meshd_dbus_client_s {
43 } meshd_dbus_client_s;
45 NetMesh* meshd_dbus_get_object()
47 return meshd_dbus_object;
50 int64_t meshd_dbus_generate_signal_number()
57 static int _meshd_dbus_client_list_cleanup(GList *client_list)
59 meshd_dbus_client_s *client;
61 meshd_check_null_ret_error("client_list", client_list, FALSE);
63 client = client_list->data;
65 free(client->bus_name);
66 client->bus_name = NULL;
68 g_list_free(client_list);
70 return MESHD_ERROR_NONE;
73 static int _meshd_dbus_client_list_compare_bus_name(const void *a, const void *b)
75 const meshd_dbus_client_s *client = a;
77 return g_strcmp0(client->bus_name, b);
80 static inline GList* _meshd_dbus_client_list_find_client(const gchar *owner)
82 return g_list_find_custom(meshd_dbus_client_list, owner,
83 _meshd_dbus_client_list_compare_bus_name);
86 static void _meshd_dbus_name_owner_changed_cb(GDBusConnection *conn,
87 const gchar *sender_name,
88 const gchar *object_path,
89 const gchar *interface_name,
90 const gchar *signal_name,
96 gchar *name, *old_owner, *new_owner;
100 NOTUSED(object_path);
101 NOTUSED(interface_name);
102 NOTUSED(signal_name);
105 g_variant_get(parameters, "(&s&s&s)", &name, &old_owner, &new_owner);
107 if (0 == strlen(new_owner)) {
108 g_mutex_lock(&meshd_dbus_client_list_mutex);
109 client = _meshd_dbus_client_list_find_client(old_owner);
110 if (client) { /* found bus name in our bus list */
111 MESH_LOGD("bus(%s) stopped", old_owner);
112 meshd_dbus_client_list = g_list_remove_link(meshd_dbus_client_list, client);
114 g_mutex_unlock(&meshd_dbus_client_list_mutex);
117 ret = _meshd_dbus_client_list_cleanup(client);
118 if (MESHD_ERROR_NONE != ret)
119 MESH_LOGE("_meshd_dbus_client_list_cleanup() Fail(%d)", ret);
124 static int _meshd_dbus_subscribe_name_owner_changed(GDBusConnection *conn)
128 id = g_dbus_connection_signal_subscribe(conn,
129 "org.freedesktop.DBus", /* bus name */
130 "org.freedesktop.DBus", /* interface */
131 "NameOwnerChanged", /* member */
132 "/org/freedesktop/DBus", /* path */
134 G_DBUS_SIGNAL_FLAGS_NONE,
135 _meshd_dbus_name_owner_changed_cb,
139 MESH_LOGE("g_dbus_connection_signal_subscribe() Fail");
140 return MESHD_ERROR_IO_ERROR;
143 return MESHD_ERROR_NONE;
146 static gboolean _meshd_dbus_handle_enable(NetMesh *object,
147 GDBusMethodInvocation *invocation,
150 int ret = MESHD_ERROR_NONE;
151 mesh_service *service = (mesh_service *)user_data;
152 mesh_interface_s *info = service->interface_info;
154 if (service->mesh_activated) {
155 /* Already activated */
156 net_mesh_complete_enable(object, invocation,
157 MESHD_ERROR_OPERATION_FAILED);
159 /* Do API response first */
160 net_mesh_complete_enable(object, invocation, ret);
161 service->mesh_activated = TRUE;
164 meshd_check_null_ret_error("info", info, FALSE);
166 /* Register event handler first */
167 ret = mesh_request_register_event_handler();
168 if (MESHD_ERROR_NONE != ret) {
169 MESH_LOGE("Failed to register mesh event handler !! [%d]", ret);
172 ret = mesh_interface_initialize(service->interface_info);
173 if (MESHD_ERROR_NONE != ret) {
174 MESH_LOGE("Failed to mesh_interface_initialize [%d]", ret);
179 net_mesh_emit_mesh_enabled(object, ret);
184 static gboolean _meshd_dbus_handle_disable(NetMesh *object,
185 GDBusMethodInvocation *invocation,
188 int ret = MESHD_ERROR_NONE;
189 mesh_service *service = (mesh_service *)user_data;
190 mesh_interface_s *info = service->interface_info;
192 meshd_check_null_ret_error("info", info, FALSE);
194 /* Make response first */
195 net_mesh_complete_disable(object, invocation, ret);
197 ret = mesh_request_unregister_event_handler();
198 if (MESHD_ERROR_NONE != ret) {
199 MESH_LOGE("Failed to unregister mesh event handler !! [%d]", ret);
202 /* Terminate daemon */
203 meshd_service_exit(service);
208 static gboolean _meshd_dbus_handle_scan(NetMesh *object,
209 GDBusMethodInvocation *invocation,
212 int ret = MESHD_ERROR_NONE;
213 mesh_service *service = (mesh_service *)user_data;
214 mesh_interface_s *info = service->interface_info;
216 meshd_check_null_ret_error("info", info, FALSE);
218 ret = mesh_request_scan(info->mesh_interface);
219 if (MESHD_ERROR_NONE != ret) {
220 MESH_LOGE("Failed to mesh_request_scan on mesh interface[%s] !",
221 info->mesh_interface);
225 if (MESHD_ERROR_IN_PROGRESS != ret) {
226 ret = mesh_request_scan(info->base_interface);
227 if (MESHD_ERROR_NONE != ret)
228 MESH_LOGE("Failed to mesh_request_scan on base interface[%s] !",
229 info->base_interface);
232 net_mesh_complete_scan(object, invocation, ret);
237 static gboolean _meshd_dbus_handle_specific_scan(NetMesh *object,
238 GDBusMethodInvocation *invocation,
243 int ret = MESHD_ERROR_NONE;
244 mesh_service *service = (mesh_service *)user_data;
245 mesh_interface_s *info = service->interface_info;
247 meshd_check_null_ret_error("info", info, FALSE);
249 ret = mesh_request_specific_scan(info->mesh_interface, mesh_id, channel);
250 if (MESHD_ERROR_NONE != ret) {
251 MESH_LOGE("Failed to mesh_request_specific_scan on mesh interface[%s]",
252 info->mesh_interface);
256 if (MESHD_ERROR_IN_PROGRESS != ret) {
257 ret = mesh_request_specific_scan(info->base_interface, mesh_id, channel);
258 if (MESHD_ERROR_NONE != ret)
259 MESH_LOGE("Failed to mesh_request_specific_scan on base interface[%s]",
260 info->base_interface);
263 net_mesh_complete_specific_scan(object, invocation, ret);
268 static gboolean _meshd_dbus_handle_cancel_scan(NetMesh *object,
269 GDBusMethodInvocation *invocation,
272 int ret = MESHD_ERROR_NONE;
273 mesh_service *service = (mesh_service *)user_data;
274 mesh_interface_s *info = service->interface_info;
276 ret = mesh_request_cancel_scan(info->mesh_interface);
277 if (MESHD_ERROR_NONE != ret) {
278 MESH_LOGE("Failed to mesh_request_cancel_scan");
281 net_mesh_complete_cancel_scan(object, invocation, ret);
286 static void _on_scan_result_destroy(gpointer data)
288 mesh_scan_result_s *scan_item = (mesh_scan_result_s *)data;
291 g_free(scan_item->mesh_id);
292 g_free(scan_item->bssid);
296 static void _on_station_list_destroy(gpointer data)
298 mesh_station_info_s *info = (mesh_station_info_s*)data;
306 static void _on_mpath_list_destroy(gpointer data)
308 mesh_mpath_info_s *info = (mesh_mpath_info_s*)data;
311 g_free(info->dest_addr);
312 g_free(info->next_hop);
313 g_free(info->interface);
318 static gboolean _meshd_dbus_handle_get_found_mesh_networks(NetMesh *object,
319 GDBusMethodInvocation *invocation,
322 int ret = MESHD_ERROR_NONE;
323 mesh_service *service = (mesh_service *)user_data;
324 mesh_interface_s *info = service->interface_info;
326 GVariantBuilder builder;
329 mesh_scan_result_s *scan_item = NULL;
331 MESH_LOGD("Request to get scanned mesh network list");
333 ret = mesh_request_get_scan_result(info->mesh_interface, &service->scanned_mesh_network);
334 if (MESHD_ERROR_NONE != ret) {
335 MESH_LOGE("Failed to mesh_request_get_scan_result");
338 ret = mesh_request_get_scan_result(info->base_interface,
339 &service->scanned_mesh_network);
340 if (MESHD_ERROR_NONE != ret) {
341 MESH_LOGE("Failed to mesh_request_get_scan_result on base interface[%s]",
342 info->base_interface);
344 g_dbus_method_invocation_return_error(invocation,
345 G_DBUS_ERROR, G_DBUS_ERROR_FAILED, "Request Failed");
349 g_variant_builder_init(&builder, G_VARIANT_TYPE("aa{sv}"));
351 iter = service->scanned_mesh_network;
352 while (iter != NULL) {
353 scan_item = (mesh_scan_result_s*)iter->data;
355 g_variant_builder_open(&builder, G_VARIANT_TYPE_VARDICT);
356 g_variant_builder_add(&builder, "{sv}", "mesh_id",
357 g_variant_new_string(scan_item->mesh_id));
358 g_variant_builder_add(&builder, "{sv}", "bssid",
359 g_variant_new_string(scan_item->bssid));
360 g_variant_builder_add(&builder, "{sv}", "rssi",
361 g_variant_new_int32(scan_item->rssi));
362 g_variant_builder_add(&builder, "{sv}", "channel",
363 g_variant_new_uint32(scan_item->channel));
364 g_variant_builder_close(&builder);
366 iter = g_list_next(iter);
369 /* Clear scan list */
370 g_list_free_full(service->scanned_mesh_network, _on_scan_result_destroy);
371 service->scanned_mesh_network = NULL;
373 networks = g_variant_builder_end(&builder);
374 net_mesh_complete_get_found_mesh_networks(object, invocation, networks, ret);
379 static gboolean _meshd_dbus_handle_enable_mesh(NetMesh *object,
380 GDBusMethodInvocation *invocation,
383 int ret = MESHD_ERROR_NONE;
384 mesh_service *service = (mesh_service *)user_data;
385 mesh_interface_s *info = service->interface_info;
387 /* Create or join mesh network and create bridge */
388 ret = mesh_request_enable_mesh(info->base_interface, info->mesh_interface);
389 if (MESHD_ERROR_NONE != ret) {
390 MESH_LOGE("Failed to mesh_request_enable_mesh [%d]", ret);
394 ret = mesh_request_create_bridge(info->bridge_interface, info->mesh_interface);
395 if (MESHD_ERROR_NONE != ret) {
396 MESH_LOGE("Failed to mesh_request_create_bridge [%d]", ret);
401 ret = mesh_request_join_mesh(info->mesh_interface,
402 service->saved_mesh_network, &service->joined_network);
403 if (MESHD_ERROR_NONE != ret) {
404 MESH_LOGE("Failed to mesh_request_join_mesh [%d]", ret);
408 /* Detect external network state (i.e. Ethernet)
409 and decide to make gate enabled */
410 ret = mesh_request_set_mesh_gate(info->bridge_interface,
411 info->mesh_interface, info->external_interface);
412 if (MESHD_ERROR_NONE != ret) {
413 MESH_LOGE("Failed to mesh_request_set_mesh_gate [%d]", ret);
417 /* TODO: Check if specific scan is required */
418 ret = mesh_request_specific_scan(info->mesh_interface,
419 info->mesh_id, info->mesh_channel);
420 if (MESHD_ERROR_NONE != ret) {
421 MESH_LOGE("Failed to mesh_request_specific_scan [%d]", ret);
423 ret = mesh_request_get_scan_result(info->mesh_interface,
424 &service->scanned_mesh_network);
427 /* Request DHCP on bridge interface */
428 ret = mesh_request_dhcp(info->bridge_interface);
429 if (MESHD_ERROR_NONE != ret) {
430 MESH_LOGE("Failed to mesh_request_dhcp [%d]", ret);
433 /* TODO: Notify bridge status to Connman */
436 net_mesh_complete_enable_mesh(object, invocation, ret);
441 static gboolean _meshd_dbus_handle_disable_mesh(NetMesh *object,
442 GDBusMethodInvocation *invocation,
445 int ret = MESHD_ERROR_NONE;
446 mesh_service *service = (mesh_service *)user_data;
447 mesh_interface_s *info = service->interface_info;
449 meshd_check_null_ret_error("info", info, FALSE);
451 /* Destroy bridge and return from mesh to infra mode */
452 if (service->joined_network) {
453 g_free(service->joined_network->mesh_id);
454 g_free(service->joined_network);
455 service->joined_network = NULL;
458 if (FALSE == service->mesh_activated) {
459 MESH_LOGD("Mesh network is not activated yet");
460 ret = MESHD_ERROR_OPERATION_FAILED;
461 net_mesh_complete_disable_mesh(object, invocation, ret);
465 ret = mesh_request_disable_mesh(info->mesh_interface);
466 if (MESHD_ERROR_NONE != ret) {
467 MESH_LOGE("Failed to mesh_request_disable_mesh_gate");
470 ret = mesh_request_remove_bridge(info->bridge_interface);
471 if (MESHD_ERROR_NONE != ret) {
472 MESH_LOGE("Failed to mesh_request_remove_bridge");
476 net_mesh_complete_disable_mesh(object, invocation, ret);
478 /* Make notification */
479 mesh_notify_left_network();
484 static gboolean _meshd_dbus_handle_get_joined_mesh_network(NetMesh *object,
485 GDBusMethodInvocation *invocation,
488 int ret = MESHD_ERROR_NONE;
489 mesh_service *service = (mesh_service *)user_data;
490 mesh_network_info_s *joined = service->joined_network;
492 //gchar *meshid = strdup("meshnet");
493 //gchar *bssid = strdup("7c:dd:90:d8:2a:64");
494 //gint channel = 161;
495 //gint max_speed = 866;
498 net_mesh_complete_get_joined_mesh_network(object, invocation,
499 joined->mesh_id, joined->bssid, joined->channel, ret);
501 net_mesh_complete_get_joined_mesh_network(object, invocation,
502 "", "", 0, MESHD_ERROR_NO_DATA);
508 static gboolean _meshd_dbus_handle_set_gate(NetMesh *object,
509 GDBusMethodInvocation *invocation, gboolean stp, gboolean gate_announce,
512 int ret = MESHD_ERROR_NONE;
513 mesh_service *service = (mesh_service *)user_data;
514 mesh_interface_s *info = service->interface_info;
516 MESH_LOGD("STP = %d", stp);
517 MESH_LOGD("gate_announce = %d", gate_announce);
519 /* Set STP and gate_announce */
520 ret = mesh_request_set_mesh_gate(info->bridge_interface,
521 info->mesh_interface, info->external_interface);
522 if (MESHD_ERROR_NONE != ret) {
523 MESH_LOGE("Failed to mesh_request_set_mesh_gate [%d]", ret);
526 net_mesh_complete_set_gate(object, invocation, ret);
531 static gboolean _meshd_dbus_handle_unset_gate(NetMesh *object,
532 GDBusMethodInvocation *invocation,
535 int ret = MESHD_ERROR_NONE;
536 mesh_service *service = (mesh_service *)user_data;
537 mesh_interface_s *info = service->interface_info;
539 ret = mesh_request_unset_mesh_gate(info->bridge_interface,
540 info->mesh_interface, info->external_interface);
541 if (MESHD_ERROR_NONE != ret) {
542 MESH_LOGE("Failed to mesh_request_unset_mesh_gate [%d]", ret);
544 net_mesh_complete_unset_gate(object, invocation, ret);
549 static gboolean _meshd_dbus_handle_set_softap(NetMesh *object,
550 GDBusMethodInvocation *invocation,
551 gchar *ssid, gchar *passphrase,
552 gchar *mode, gint channel, gint visibility, gint max_sta,
553 gint security, gpointer user_data)
555 int ret = MESHD_ERROR_NONE;
556 mesh_service *service = (mesh_service *)user_data;
557 mesh_interface_s *info = service->interface_info;
559 MESH_LOGD("SSID : %s", ssid);
560 MESH_LOGD("mode : %s", mode);
561 MESH_LOGD("channel : %d", channel);
562 MESH_LOGD("visibility: %d", visibility);
563 MESH_LOGD("max_sta : %d", max_sta);
564 MESH_LOGD("security : %d", security);
566 /* Save softAP information */
567 ret = mesh_request_set_softap_config(info->softap_interface,
568 ssid, mode, channel, visibility, max_sta,
569 security, passphrase);
570 if (MESHD_ERROR_NONE != ret) {
571 MESH_LOGE("Failed to mesh_request_set_softap_config [%d]", ret);
574 net_mesh_complete_set_softap(object, invocation, ret);
579 static gboolean _meshd_dbus_handle_enable_softap(NetMesh *object,
580 GDBusMethodInvocation *invocation, gpointer user_data)
582 int ret = MESHD_ERROR_NONE;
583 mesh_service *service = (mesh_service *)user_data;
584 mesh_interface_s *info = service->interface_info;
586 /* Check softAP interface and execute it */
587 ret = mesh_request_enable_softap(info->bridge_interface, info->softap_interface);
588 if (MESHD_ERROR_NONE != ret) {
589 MESH_LOGE("Failed to mesh_request_enable_softap [%d]", ret);
592 net_mesh_complete_enable_softap(object, invocation, ret);
597 static gboolean _meshd_dbus_handle_disable_softap(NetMesh *object,
598 GDBusMethodInvocation *invocation, gpointer user_data)
600 int ret = MESHD_ERROR_NONE;
601 mesh_service *service = (mesh_service *)user_data;
602 mesh_interface_s *info = service->interface_info;
605 ret = mesh_request_disable_softap(info->bridge_interface, info->softap_interface);
606 if (MESHD_ERROR_NONE != ret) {
607 MESH_LOGE("Failed to mesh_request_disable_softap [%d]", ret);
610 net_mesh_complete_disable_softap(object, invocation, ret);
615 static gboolean _meshd_dbus_handle_add_mesh_network(NetMesh *object,
616 GDBusMethodInvocation *invocation,
617 gchar *mesh_id, gint channel, gint security,
620 int ret = MESHD_ERROR_NONE;
621 mesh_service *service = (mesh_service *)user_data;
623 ret = mesh_request_add_mesh_network(&service->saved_mesh_network,
624 mesh_id, channel, security);
626 net_mesh_complete_add_mesh_network(object, invocation, ret);
631 static gboolean _meshd_dbus_handle_get_saved_mesh_network(NetMesh *object,
632 GDBusMethodInvocation *invocation,
635 int ret = MESHD_ERROR_NONE;
636 mesh_service *service = (mesh_service *)user_data;
638 GVariantBuilder builder;
642 ret = mesh_request_get_saved_mesh_network(&service->saved_mesh_network);
643 if (MESHD_ERROR_NONE != ret) {
644 MESH_LOGE("Failed to mesh_request_get_saved_mesh_network");
646 g_dbus_method_invocation_return_error(invocation,
647 G_DBUS_ERROR, G_DBUS_ERROR_FAILED, "Request Failed");
649 /* TODO: Get station information and make variant data */
650 g_variant_builder_init(&builder, G_VARIANT_TYPE("aa{sv}"));
652 iter = service->saved_mesh_network;
653 while (iter != NULL) {
654 mesh_network_info_s *item = (mesh_network_info_s*)iter->data;
656 g_variant_builder_open(&builder, G_VARIANT_TYPE_VARDICT);
657 g_variant_builder_add(&builder, "{sv}", "mesh_id",
658 g_variant_new_string(item->mesh_id));
659 g_variant_builder_add(&builder, "{sv}", "channel",
660 g_variant_new_uint32(item->channel));
661 g_variant_builder_add(&builder, "{sv}", "security",
662 g_variant_new_uint32(item->security));
663 g_variant_builder_close(&builder);
665 iter = g_list_next(iter);
668 networks = g_variant_builder_end(&builder);
669 net_mesh_complete_get_saved_mesh_network(object, invocation, networks, ret);
675 static gboolean _meshd_dbus_handle_select_saved_mesh_network(NetMesh *object,
676 GDBusMethodInvocation *invocation,
677 gchar *mesh_id, gint channel, gint security,
680 int ret = MESHD_ERROR_NONE;
681 mesh_service *service = (mesh_service *)user_data;
683 ret = mesh_request_select_saved_mesh_network(&service->saved_mesh_network,
684 mesh_id, channel, security);
686 net_mesh_complete_select_saved_mesh_network(object, invocation, ret);
691 static gboolean _meshd_dbus_handle_forget_saved_mesh_network(NetMesh *object,
692 GDBusMethodInvocation *invocation,
693 gchar *mesh_id, gint channel, gint security,
696 int ret = MESHD_ERROR_NONE;
697 mesh_service *service = (mesh_service *)user_data;
699 ret = mesh_request_forget_saved_mesh_network(&service->saved_mesh_network,
700 mesh_id, channel, security);
702 net_mesh_complete_forget_saved_mesh_network(object, invocation, ret);
707 static gboolean _meshd_dbus_handle_set_interfaces(NetMesh *object,
708 GDBusMethodInvocation *invocation,
709 gchar *mesh, gchar *gate, gchar *softap,
712 int ret = MESHD_ERROR_NONE;
713 mesh_service *service = (mesh_service *)user_data;
714 mesh_interface_s *info = service->interface_info;
716 g_free(info->mesh_interface);
717 info->mesh_interface = g_strdup(mesh);
719 g_free(info->external_interface);
720 info->external_interface = g_strdup(gate);
722 g_free(info->softap_interface);
723 info->softap_interface = g_strdup(softap);
725 net_mesh_complete_set_interfaces(object, invocation, ret);
730 static gboolean _meshd_dbus_handle_get_station_info(NetMesh *object,
731 GDBusMethodInvocation *invocation,
734 int ret = MESHD_ERROR_NONE;
736 GVariantBuilder builder;
740 mesh_service *service = (mesh_service *)user_data;
741 mesh_interface_s *info = service->interface_info;
743 /* Clear mesh station list */
744 g_list_free_full(service->station_list, _on_station_list_destroy);
745 service->station_list = NULL;
747 ret = mesh_request_get_station_info(
748 info->mesh_interface, &service->station_list);
749 if (MESHD_ERROR_NONE != ret) {
750 MESH_LOGE("Failed to mesh_request_get_station_info");
752 g_dbus_method_invocation_return_error(invocation,
753 G_DBUS_ERROR, G_DBUS_ERROR_FAILED, "Request Failed");
756 * sh-3.2# iw mesh0 station dump
757 * Station 7c:dd:90:62:37:cf (on mesh0)
758 * inactive time: 1685 ms
767 * signal avg: -63 dBm
768 * tx bitrate: 54.0 MBit/s
769 * rx bitrate: 5.5 MBit/s
773 * mesh local PS mode: ACTIVE
774 * mesh peer PS mode: ACTIVE
775 * mesh non-peer PS mode: ACTIVE
784 * beacon interval:1000
785 * short slot time:yes
786 * connected time: 256 seconds
788 /* Get station information and make variant data */
789 g_variant_builder_init(&builder, G_VARIANT_TYPE("aa{sv}"));
791 iter = service->station_list;
792 while (iter != NULL) {
793 mesh_station_info_s *item = (mesh_station_info_s*)iter->data;
795 g_variant_builder_open(&builder, G_VARIANT_TYPE_VARDICT);
796 g_variant_builder_add(&builder, "{sv}", "bssid",
797 g_variant_new_string(item->bssid));
798 g_variant_builder_add(&builder, "{sv}", "inactive_time",
799 g_variant_new_uint32(item->inactive_time));
800 g_variant_builder_add(&builder, "{sv}", "rx_bytes",
801 g_variant_new_uint64(item->rx_bytes));
802 g_variant_builder_add(&builder, "{sv}", "rx_packets",
803 g_variant_new_uint32(item->rx_packets));
804 g_variant_builder_add(&builder, "{sv}", "tx_bytes",
805 g_variant_new_uint64(item->tx_bytes));
806 g_variant_builder_add(&builder, "{sv}", "tx_packets",
807 g_variant_new_uint32(item->tx_packets));
808 g_variant_builder_add(&builder, "{sv}", "tx_retries",
809 g_variant_new_uint32(item->tx_retries));
810 g_variant_builder_add(&builder, "{sv}", "tx_failed",
811 g_variant_new_uint32(item->tx_failed));
812 g_variant_builder_add(&builder, "{sv}", "beacon_loss",
813 g_variant_new_uint32(item->beacon_loss));
814 g_variant_builder_add(&builder, "{sv}", "signal",
815 g_variant_new_int32(item->rssi));
816 g_variant_builder_add(&builder, "{sv}", "signal_avg",
817 g_variant_new_int32(item->rssi_avg));
818 g_variant_builder_add(&builder, "{sv}", "tx_bitrate",
819 g_variant_new_uint32(item->tx_bitrate)); /* 10 times */
820 g_variant_builder_add(&builder, "{sv}", "rx_bitrate",
821 g_variant_new_uint32(item->rx_bitrate)); /* 10 times */
822 g_variant_builder_add(&builder, "{sv}", "mesh_llid",
823 g_variant_new_uint16(item->llid));
824 g_variant_builder_add(&builder, "{sv}", "mesh_plid",
825 g_variant_new_uint16(item->plid));
826 g_variant_builder_add(&builder, "{sv}", "mesh_plink",
827 g_variant_new_byte(item->mesh_plink)); /* 0 : DISCON, 1 : ESTAB */
828 g_variant_builder_add(&builder, "{sv}", "local_ps_mode",
829 g_variant_new_uint32(item->local_ps_mode)); /* 0 : INACTIVE, 1 : ACTIVE */
830 g_variant_builder_add(&builder, "{sv}", "peer_ps_mode",
831 g_variant_new_uint32(item->peer_ps_mode)); /* 0 : INACTIVE, 1 : ACTIVE */
832 g_variant_builder_add(&builder, "{sv}", "non_peer_ps_mode",
833 g_variant_new_uint32(item->non_peer_ps_mode)); /* 0 : INACTIVE, 1 : ACTIVE */
834 g_variant_builder_add(&builder, "{sv}", "authorized",
835 g_variant_new_boolean(item->authorized));
836 g_variant_builder_add(&builder, "{sv}", "associated",
837 g_variant_new_boolean(item->associated));
838 g_variant_builder_add(&builder, "{sv}", "preamble",
839 g_variant_new_boolean(item->preamble));
840 g_variant_builder_add(&builder, "{sv}", "WMM_WME",
841 g_variant_new_boolean(item->wme));
842 g_variant_builder_add(&builder, "{sv}", "MFP",
843 g_variant_new_boolean(item->mfp));
844 g_variant_builder_add(&builder, "{sv}", "TDLS_peer",
845 g_variant_new_boolean(item->tdls_peer));
846 g_variant_builder_add(&builder, "{sv}", "DTIM_period",
847 g_variant_new_byte(item->dtim_period));
848 g_variant_builder_add(&builder, "{sv}", "beacon_interval",
849 g_variant_new_uint16(item->beacon_interval));
850 g_variant_builder_add(&builder, "{sv}", "short_slot_time",
851 g_variant_new_boolean(item->short_slot_time));
852 g_variant_builder_add(&builder, "{sv}", "connected_time",
853 g_variant_new_uint32(item->connected_time));
854 g_variant_builder_close(&builder);
856 iter = g_list_next(iter);
859 station = g_variant_builder_end(&builder);
860 net_mesh_complete_get_saved_mesh_network(object, invocation, station, ret);
862 g_object_unref(station);
866 g_variant_builder_init(&builder, G_VARIANT_TYPE_VARDICT);
867 g_variant_builder_add(&builder, "{sv}", "station", g_variant_new_string("7c:dd:90:62:37:cf"));
868 g_variant_builder_add(&builder, "{sv}", "inactive_time", g_variant_new_uint32(1685));
869 g_variant_builder_add(&builder, "{sv}", "rx_bytes", g_variant_new_uint32(34174));
870 g_variant_builder_add(&builder, "{sv}", "rx_packets", g_variant_new_uint32(1181));
871 g_variant_builder_add(&builder, "{sv}", "tx_bytes", g_variant_new_uint32(6877));
872 g_variant_builder_add(&builder, "{sv}", "tx_packets", g_variant_new_uint32(76));
873 g_variant_builder_add(&builder, "{sv}", "tx_retries", g_variant_new_uint32(0));
874 g_variant_builder_add(&builder, "{sv}", "tx_failed", g_variant_new_uint32(0));
875 g_variant_builder_add(&builder, "{sv}", "beacon_loss", g_variant_new_uint32(0));
876 g_variant_builder_add(&builder, "{sv}", "signal", g_variant_new_int32(-64));
877 g_variant_builder_add(&builder, "{sv}", "signal_avg", g_variant_new_int32(-63));
878 g_variant_builder_add(&builder, "{sv}", "tx_bitrate", g_variant_new_uint32(540)); /* 10 times */
879 g_variant_builder_add(&builder, "{sv}", "rx_bitrate", g_variant_new_uint32(55)); /* 10 times */
880 g_variant_builder_add(&builder, "{sv}", "mesh_llid", g_variant_new_uint32(51731));
881 g_variant_builder_add(&builder, "{sv}", "mesh_plid", g_variant_new_uint32(35432));
882 g_variant_builder_add(&builder, "{sv}", "mesh_plink", g_variant_new_uint32(1)); /* 0 : DISCON, 1 : ESTAB */
883 g_variant_builder_add(&builder, "{sv}", "mesh_local_PS_mode", g_variant_new_uint32(1)); /* 0 : INACTIVE, 1 : ACTIVE */
884 g_variant_builder_add(&builder, "{sv}", "mesh_peer_PS_mode", g_variant_new_uint32(1)); /* 0 : INACTIVE, 1 : ACTIVE */
885 g_variant_builder_add(&builder, "{sv}", "mesh_none_peer_PS_mode", g_variant_new_uint32(1)); /* 0 : INACTIVE, 1 : ACTIVE */
886 g_variant_builder_add(&builder, "{sv}", "authorized", g_variant_new_boolean(TRUE));
887 g_variant_builder_add(&builder, "{sv}", "associated", g_variant_new_boolean(TRUE));
888 g_variant_builder_add(&builder, "{sv}", "preamble",g_variant_new_string("long"));
889 g_variant_builder_add(&builder, "{sv}", "WMM_WME", g_variant_new_boolean(TRUE));
890 g_variant_builder_add(&builder, "{sv}", "MFP", g_variant_new_boolean(FALSE));
891 g_variant_builder_add(&builder, "{sv}", "TDLS_peer", g_variant_new_boolean(FALSE));
892 g_variant_builder_add(&builder, "{sv}", "DTIM_period", g_variant_new_uint32(0));
893 g_variant_builder_add(&builder, "{sv}", "beacon_interval", g_variant_new_uint32(1000));
894 g_variant_builder_add(&builder, "{sv}", "short_slot_time", g_variant_new_boolean(TRUE));
895 g_variant_builder_add(&builder, "{sv}", "connected_time", g_variant_new_uint32(256));
896 station = g_variant_builder_end(&builder);
898 net_mesh_complete_get_station_info(object, invocation, station, ret);
900 g_object_unref(station);
905 static gboolean _meshd_dbus_handle_get_mpath_info(NetMesh *object,
906 GDBusMethodInvocation *invocation,
909 int ret = MESHD_ERROR_NONE;
910 GVariantBuilder builder;
911 GVariant* mpath_data;
914 mesh_service *service = (mesh_service *)user_data;
915 mesh_interface_s *info = service->interface_info;
917 /* Clear mesh path list */
918 g_list_free_full(service->mpath_list, _on_mpath_list_destroy);
919 service->mpath_list = NULL;
921 ret = mesh_request_get_mpath_info(
922 info->mesh_interface, &service->mpath_list);
923 if (MESHD_ERROR_NONE != ret) {
924 MESH_LOGE("Failed to mesh_request_get_mpath_info");
926 g_dbus_method_invocation_return_error(invocation,
927 G_DBUS_ERROR, G_DBUS_ERROR_FAILED, "Request Failed");
930 * Example) sh-3.2# iw mesh0 mpath dump
931 * DEST ADDR NEXT HOP IFACE SN METRIC QLEN EXPTIME DTIM DRET FLAGS
932 * 7c:dd:90:62:37:cf 7c:dd:90:62:37:cf mesh0 221 152 0 10 100 0 0x5
934 /* Get mesh path information and make variant data */
935 g_variant_builder_init(&builder, G_VARIANT_TYPE("aa{sv}"));
937 iter = service->mpath_list;
938 while (iter != NULL) {
939 mesh_mpath_info_s *item = (mesh_mpath_info_s*)iter->data;
941 g_variant_builder_open(&builder, G_VARIANT_TYPE_VARDICT);
942 g_variant_builder_add(&builder, "{sv}", "DEST_ADDR",
943 g_variant_new_string(item->dest_addr));
944 g_variant_builder_add(&builder, "{sv}", "NEXT_HOP",
945 g_variant_new_string(item->next_hop));
946 g_variant_builder_add(&builder, "{sv}", "IFACE",
947 g_variant_new_string(item->interface));
948 g_variant_builder_add(&builder, "{sv}", "SN",
949 g_variant_new_uint32(item->sn));
950 g_variant_builder_add(&builder, "{sv}", "METRIC",
951 g_variant_new_uint32(item->metric));
952 g_variant_builder_add(&builder, "{sv}", "QLEN",
953 g_variant_new_uint32(item->qlen));
954 g_variant_builder_add(&builder, "{sv}", "EXPTIME",
955 g_variant_new_uint32(item->exptime));
956 g_variant_builder_add(&builder, "{sv}", "DTIM",
957 g_variant_new_uint32(item->discovery_timeout));
958 g_variant_builder_add(&builder, "{sv}", "DRET",
959 g_variant_new_byte(item->discovery_retries));
960 g_variant_builder_add(&builder, "{sv}", "FLAGS",
961 g_variant_new_byte(item->flags));
962 g_variant_builder_close(&builder);
964 iter = g_list_next(iter);
967 mpath_data = g_variant_builder_end(&builder);
968 net_mesh_complete_get_mpath_info(object, invocation, mpath_data, ret);
970 g_object_unref(mpath_data);
976 static void _meshd_dbus_on_bus_acquired(GDBusConnection *conn, const gchar *name,
980 GError *error = NULL;
981 mesh_service *service = (mesh_service *)user_data;
985 meshd_dbus_object = net_mesh_skeleton_new();
986 if (NULL == meshd_dbus_object) {
987 MESH_LOGE("net_mesh_skeleton_new() Fail");
991 g_signal_connect(meshd_dbus_object, "handle-enable",
992 G_CALLBACK(_meshd_dbus_handle_enable), service);
993 g_signal_connect(meshd_dbus_object, "handle-disable",
994 G_CALLBACK(_meshd_dbus_handle_disable), service);
995 g_signal_connect(meshd_dbus_object, "handle-scan",
996 G_CALLBACK(_meshd_dbus_handle_scan), service);
997 g_signal_connect(meshd_dbus_object, "handle-specific-scan",
998 G_CALLBACK(_meshd_dbus_handle_specific_scan), service);
999 g_signal_connect(meshd_dbus_object, "handle-cancel-scan",
1000 G_CALLBACK(_meshd_dbus_handle_cancel_scan), service);
1001 g_signal_connect(meshd_dbus_object, "handle-get-found-mesh-networks",
1002 G_CALLBACK(_meshd_dbus_handle_get_found_mesh_networks), service);
1003 g_signal_connect(meshd_dbus_object, "handle-enable-mesh",
1004 G_CALLBACK(_meshd_dbus_handle_enable_mesh), service);
1005 g_signal_connect(meshd_dbus_object, "handle-disable-mesh",
1006 G_CALLBACK(_meshd_dbus_handle_disable_mesh), service);
1007 g_signal_connect(meshd_dbus_object, "handle-get-joined-mesh-network",
1008 G_CALLBACK(_meshd_dbus_handle_get_joined_mesh_network), service);
1009 g_signal_connect(meshd_dbus_object, "handle-set-gate",
1010 G_CALLBACK(_meshd_dbus_handle_set_gate), service);
1011 g_signal_connect(meshd_dbus_object, "handle-unset-gate",
1012 G_CALLBACK(_meshd_dbus_handle_unset_gate), service);
1013 g_signal_connect(meshd_dbus_object, "handle-set-softap",
1014 G_CALLBACK(_meshd_dbus_handle_set_softap), service);
1015 g_signal_connect(meshd_dbus_object, "handle-enable-softap",
1016 G_CALLBACK(_meshd_dbus_handle_enable_softap), service);
1017 g_signal_connect(meshd_dbus_object, "handle-disable-softap",
1018 G_CALLBACK(_meshd_dbus_handle_disable_softap), service);
1019 g_signal_connect(meshd_dbus_object, "handle-add-mesh-network",
1020 G_CALLBACK(_meshd_dbus_handle_add_mesh_network), service);
1021 g_signal_connect(meshd_dbus_object, "handle-get-saved-mesh-network",
1022 G_CALLBACK(_meshd_dbus_handle_get_saved_mesh_network), service);
1023 g_signal_connect(meshd_dbus_object, "handle-select-saved-mesh-network",
1024 G_CALLBACK(_meshd_dbus_handle_select_saved_mesh_network), service);
1025 g_signal_connect(meshd_dbus_object, "handle-forget-saved-mesh-network",
1026 G_CALLBACK(_meshd_dbus_handle_forget_saved_mesh_network), service);
1027 g_signal_connect(meshd_dbus_object, "handle-set-interfaces",
1028 G_CALLBACK(_meshd_dbus_handle_set_interfaces), service);
1029 g_signal_connect(meshd_dbus_object, "handle-get-station-info",
1030 G_CALLBACK(_meshd_dbus_handle_get_station_info), service);
1031 g_signal_connect(meshd_dbus_object, "handle-get-mpath-info",
1032 G_CALLBACK(_meshd_dbus_handle_get_mpath_info), service);
1034 ret = g_dbus_interface_skeleton_export(G_DBUS_INTERFACE_SKELETON(meshd_dbus_object),
1035 conn, MESH_DBUS_OBJPATH, &error);
1037 MESH_LOGE("g_dbus_interface_skeleton_export() Fail(%s)", error->message);
1038 g_error_free(error);
1041 ret = _meshd_dbus_subscribe_name_owner_changed(conn);
1042 if (MESHD_ERROR_NONE != ret) {
1043 MESH_LOGE("_meshd_dbus_subscribe_name_owner_changed() Fail(%d)", ret);
1048 static void _meshd_dbus_on_name_lost(GDBusConnection *conn, const gchar *name,
1054 MESH_LOGD("Lost the name %s", name);
1057 static void _meshd_dbus_on_name_acquired(GDBusConnection *conn, const gchar *name,
1063 MESH_LOGD("Acquired the name %s", name);
1066 static gboolean _meshd_dbus_interface_init(mesh_service *service)
1069 meshd_check_null_ret_error("service", service, FALSE);
1071 id = g_bus_own_name(G_BUS_TYPE_SYSTEM,
1072 MESH_DBUS_INTERFACE,
1073 G_BUS_NAME_OWNER_FLAGS_REPLACE,
1074 _meshd_dbus_on_bus_acquired,
1075 _meshd_dbus_on_name_acquired,
1076 _meshd_dbus_on_name_lost,
1080 MESH_LOGE("g_bus_own_name() Fail");
1084 service->dbus_id = id;
1085 service->interface_info = g_new0(mesh_interface_s, 1);
1086 service->scanned_mesh_network = NULL;
1091 static void _meshd_dbus_deinit(mesh_service *service)
1093 mesh_interface_s *info = NULL;
1094 meshd_check_null_ret("service", service);
1096 g_bus_unown_name(service->dbus_id);
1098 info = service->interface_info;
1099 meshd_check_null_ret("info", info);
1100 if (info->bridge_interface)
1101 g_free(info->bridge_interface);
1102 if (info->base_interface)
1103 g_free(info->base_interface);
1104 if (info->mesh_interface)
1105 g_free(info->mesh_interface);
1106 if (info->softap_interface)
1107 g_free(info->softap_interface);
1108 if (info->external_interface)
1109 g_free(info->external_interface);
1111 if (service->joined_network) {
1112 g_free(service->joined_network->mesh_id);
1113 g_free(service->joined_network);
1114 service->joined_network = NULL;
1116 mesh_request_clear_saved_mesh_network(&service->saved_mesh_network);
1118 /* Clear scan list */
1119 g_list_free_full(service->scanned_mesh_network, _on_scan_result_destroy);
1120 service->scanned_mesh_network = NULL;
1122 g_free(service->interface_info);
1123 service->interface_info = NULL;
1126 /**< mesh service interface initialization */
1127 gboolean meshd_service_interface_init(mesh_service *service)
1130 meshd_check_null_ret_error("service", service, FALSE);
1132 /* Initialize dbus interface */
1133 ret = _meshd_dbus_interface_init(service);
1135 MESH_LOGE("zigbee_service_dbus_interface_init failed!!!");
1142 /**< Zigbee service interface de-initialization */
1143 void meshd_service_interface_deinit(mesh_service *service)
1145 meshd_check_null_ret("service", service);
1147 /* De-initialize dbus interface */
1148 _meshd_dbus_deinit(service);