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-peer-monitor.h"
31 #include "mesh-device-monitor.h"
32 #include "mesh-service-interface.h"
33 #include "mesh-generated-code.h"
35 #include "mesh-request.h"
36 #include "mesh-interface.h"
38 static NetMesh *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 NetMesh* meshd_dbus_get_object()
51 return meshd_dbus_object;
54 int64_t meshd_dbus_generate_signal_number()
61 static int _meshd_dbus_client_list_cleanup(GList *client_list)
63 meshd_dbus_client_s *client;
65 meshd_check_null_ret_error("client_list", client_list, FALSE);
67 client = client_list->data;
69 free(client->bus_name);
70 client->bus_name = NULL;
72 g_list_free(client_list);
74 return MESHD_ERROR_NONE;
77 static int _meshd_dbus_client_list_compare_bus_name(const void *a, const void *b)
79 const meshd_dbus_client_s *client = a;
81 return g_strcmp0(client->bus_name, b);
84 static inline GList* _meshd_dbus_client_list_find_client(const gchar *owner)
86 return g_list_find_custom(meshd_dbus_client_list, owner,
87 _meshd_dbus_client_list_compare_bus_name);
90 static void _meshd_dbus_name_owner_changed_cb(GDBusConnection *conn,
91 const gchar *sender_name,
92 const gchar *object_path,
93 const gchar *interface_name,
94 const gchar *signal_name,
100 gchar *name, *old_owner, *new_owner;
103 NOTUSED(sender_name);
104 NOTUSED(object_path);
105 NOTUSED(interface_name);
106 NOTUSED(signal_name);
109 g_variant_get(parameters, "(&s&s&s)", &name, &old_owner, &new_owner);
111 if (0 == strlen(new_owner)) {
112 g_mutex_lock(&meshd_dbus_client_list_mutex);
113 client = _meshd_dbus_client_list_find_client(old_owner);
114 if (client) { /* found bus name in our bus list */
115 MESH_LOGD("bus(%s) stopped", old_owner);
116 meshd_dbus_client_list = g_list_remove_link(meshd_dbus_client_list, client);
118 g_mutex_unlock(&meshd_dbus_client_list_mutex);
121 ret = _meshd_dbus_client_list_cleanup(client);
122 if (MESHD_ERROR_NONE != ret)
123 MESH_LOGE("_meshd_dbus_client_list_cleanup() Fail(%d)", ret);
128 static int _meshd_dbus_subscribe_name_owner_changed(GDBusConnection *conn)
132 id = g_dbus_connection_signal_subscribe(conn,
133 "org.freedesktop.DBus", /* bus name */
134 "org.freedesktop.DBus", /* interface */
135 "NameOwnerChanged", /* member */
136 "/org/freedesktop/DBus", /* path */
138 G_DBUS_SIGNAL_FLAGS_NONE,
139 _meshd_dbus_name_owner_changed_cb,
143 MESH_LOGE("g_dbus_connection_signal_subscribe() Fail");
144 return MESHD_ERROR_IO_ERROR;
147 return MESHD_ERROR_NONE;
150 static gboolean _meshd_dbus_handle_enable(Manager *object,
151 GDBusMethodInvocation *invocation,
154 int ret = MESHD_ERROR_NONE;
155 mesh_service *service = (mesh_service *)user_data;
156 mesh_interface_s *info = service->interface_info;
158 if (service->mesh_activated) {
159 /* Already activated */
160 manager_complete_enable(object, invocation, MESHD_ERROR_NONE);
164 /* Do API response first */
165 manager_complete_enable(object, invocation, ret);
166 service->mesh_activated = TRUE;
168 meshd_check_null_ret_error("info", info, FALSE);
170 /* Register event handler first */
171 ret = mesh_request_register_event_handler();
172 if (MESHD_ERROR_IN_PROGRESS == ret) {
173 MESH_LOGE("Currently set netlink event handler !! [%d]", ret);
174 ret = MESHD_ERROR_NONE;
175 } else if (MESHD_ERROR_NONE != ret) {
176 MESH_LOGE("Failed to register mesh event handler !! [%d]", ret);
179 ret = mesh_interface_initialize(service->interface_info);
180 if (MESHD_ERROR_NONE != ret) {
181 MESH_LOGE("Failed to mesh_interface_initialize [%d]", ret);
186 net_mesh_emit_mesh_enabled(meshd_dbus_get_object(), ret);
191 static gboolean _meshd_dbus_handle_disable(Manager *object,
192 GDBusMethodInvocation *invocation,
195 int ret = MESHD_ERROR_NONE;
196 mesh_service *service = (mesh_service *)user_data;
197 mesh_interface_s *info = service->interface_info;
199 meshd_check_null_ret_error("info", info, FALSE);
201 /* Make response first */
202 manager_complete_disable(object, invocation, ret);
204 ret = mesh_request_unregister_event_handler();
205 if (MESHD_ERROR_NONE != ret)
206 MESH_LOGE("Failed to unregister mesh event handler !! [%d]", ret);
208 /* Terminate daemon */
209 meshd_service_exit(service);
214 static gboolean _meshd_dbus_handle_scan(NetMesh *object,
215 GDBusMethodInvocation *invocation,
218 int ret = MESHD_ERROR_NONE;
219 mesh_service *service = (mesh_service *)user_data;
220 mesh_interface_s *info = service->interface_info;
222 meshd_check_null_ret_error("info", info, FALSE);
224 ret = mesh_request_scan(service);
225 if (MESHD_ERROR_NONE != ret)
226 MESH_LOGE("Failed to mesh_request_scan !");
228 net_mesh_complete_scan(object, invocation, ret);
233 static gboolean _meshd_dbus_handle_specific_scan(NetMesh *object,
234 GDBusMethodInvocation *invocation,
239 int ret = MESHD_ERROR_NONE;
240 mesh_service *service = (mesh_service *)user_data;
241 mesh_interface_s *info = service->interface_info;
243 meshd_check_null_ret_error("info", info, FALSE);
245 ret = mesh_request_specific_scan(service, mesh_id, channel);
246 if (MESHD_ERROR_NONE != ret)
247 MESH_LOGE("Failed to mesh_request_specific_scan !");
249 net_mesh_complete_specific_scan(object, invocation, ret);
254 static gboolean _meshd_dbus_handle_cancel_scan(NetMesh *object,
255 GDBusMethodInvocation *invocation,
258 int ret = MESHD_ERROR_NONE;
259 mesh_service *service = (mesh_service *)user_data;
261 ret = mesh_request_cancel_scan(service);
262 if (MESHD_ERROR_NONE != ret)
263 MESH_LOGE("Failed to mesh_request_cancel_scan");
265 net_mesh_complete_cancel_scan(object, invocation, ret);
270 static void _on_scan_result_destroy(gpointer data)
272 mesh_scan_result_s *scan_item = (mesh_scan_result_s *)data;
275 g_free(scan_item->mesh_id);
276 g_free(scan_item->bssid);
277 g_free(scan_item->object_path);
282 static void _on_peer_info_destroy(gpointer data)
284 mesh_peer_info_s *peer = (mesh_peer_info_s *)data;
286 g_free(peer->address);
290 static void _on_station_list_destroy(gpointer data)
292 mesh_station_info_s *info = (mesh_station_info_s*)data;
300 static void _on_mpath_list_destroy(gpointer data)
302 mesh_mpath_info_s *info = (mesh_mpath_info_s*)data;
305 g_free(info->dest_addr);
306 g_free(info->next_hop);
307 g_free(info->interface);
312 static gboolean _meshd_dbus_handle_get_found_mesh_networks(NetMesh *object,
313 GDBusMethodInvocation *invocation,
316 int ret = MESHD_ERROR_NONE;
317 mesh_service *service = (mesh_service *)user_data;
319 GVariantBuilder builder;
322 mesh_scan_result_s *scan_item = NULL;
324 MESH_LOGD("Request to get scanned mesh network list");
326 ret = mesh_request_get_networks(service);
327 if (MESHD_ERROR_NONE != ret)
328 MESH_LOGE("Failed to mesh_request_get_networks");
330 g_variant_builder_init(&builder, G_VARIANT_TYPE("aa{sv}"));
332 /* scanned_mesh_network would be filled above request */
333 iter = service->scanned_mesh_network;
334 while (iter != NULL) {
335 scan_item = (mesh_scan_result_s*)iter->data;
337 g_variant_builder_open(&builder, G_VARIANT_TYPE_VARDICT);
338 g_variant_builder_add(&builder, "{sv}", "mesh_id",
339 g_variant_new_string(scan_item->mesh_id));
340 g_variant_builder_add(&builder, "{sv}", "bssid",
341 g_variant_new_string(scan_item->bssid));
342 g_variant_builder_add(&builder, "{sv}", "rssi",
343 g_variant_new_int32(scan_item->rssi));
344 g_variant_builder_add(&builder, "{sv}", "channel",
345 g_variant_new_uint32(scan_item->channel));
346 g_variant_builder_add(&builder, "{sv}", "security",
347 g_variant_new_uint32((int)scan_item->security));
348 g_variant_builder_add(&builder, "{sv}", "state",
349 g_variant_new_uint32(scan_item->state));
350 g_variant_builder_close(&builder);
352 iter = g_list_next(iter);
355 networks = g_variant_builder_end(&builder);
357 net_mesh_complete_get_found_mesh_networks(object, invocation, networks, ret);
362 static gboolean _meshd_dbus_handle_enable_mesh(NetMesh *object,
363 GDBusMethodInvocation *invocation,
366 int ret = MESHD_ERROR_NONE;
367 mesh_service *service = (mesh_service *)user_data;
369 /* It handles creating virtual network and bridge */
370 ret = mesh_request_enable_network(service);
371 if (MESHD_ERROR_NONE != ret)
372 MESH_LOGE("Failed to mesh_request_enable_network [%d]", ret);
374 mesh_start_monitor_service(service);
375 #ifdef USE_NETLINK_MONITOR
376 mesh_device_monitor(service);
377 #endif /* USE_NETLINK_MONITOR */
378 net_mesh_complete_enable_mesh(object, invocation, ret);
383 static gboolean _meshd_dbus_handle_disable_mesh(NetMesh *object,
384 GDBusMethodInvocation *invocation,
387 int ret = MESHD_ERROR_NONE;
388 mesh_service *service = (mesh_service *)user_data;
389 mesh_interface_s *info = service->interface_info;
391 meshd_check_null_ret_error("info", info, FALSE);
393 if (FALSE == service->mesh_activated) {
394 MESH_LOGD("Mesh network is not activated yet");
395 ret = MESHD_ERROR_OPERATION_FAILED;
396 net_mesh_complete_disable_mesh(object, invocation, ret);
400 ret = mesh_request_disable_network(service);
401 if (MESHD_ERROR_NONE != ret)
402 MESH_LOGE("Failed to disable mesh network !");
404 /* Stop Mesh Node Monitoring Service */
405 mesh_stop_monitor_service(service);
407 net_mesh_complete_disable_mesh(object, invocation, ret);
412 static gboolean _meshd_dbus_handle_is_joined(NetMesh *object,
413 GDBusMethodInvocation *invocation,
416 int ret = MESHD_ERROR_NONE;
417 gboolean state = FALSE;
418 mesh_service *service = (mesh_service *)user_data;
420 ret = mesh_request_get_joined_network(service);
421 if (MESHD_ERROR_NONE == ret) {
422 if (service->joined_network)
426 net_mesh_complete_is_joined(object, invocation, state, ret);
431 static gboolean _meshd_dbus_handle_get_joined_mesh_network(NetMesh *object,
432 GDBusMethodInvocation *invocation,
435 int ret = MESHD_ERROR_NONE;
436 mesh_service *service = (mesh_service *)user_data;
437 mesh_network_info_s *joined = NULL;
439 ret = mesh_request_get_joined_network(service);
440 if (MESHD_ERROR_NONE == ret) {
441 joined = service->joined_network;
443 net_mesh_complete_get_joined_mesh_network(object, invocation,
444 joined->mesh_id, joined->bssid,
445 joined->channel, (int)joined->security,
448 net_mesh_complete_get_joined_mesh_network(object, invocation,
449 "", "", 0, 0, 0, MESHD_ERROR_NO_DATA);
452 net_mesh_complete_get_joined_mesh_network(object, invocation,
453 "", "", 0, 0, 0, ret);
459 static gboolean _meshd_dbus_handle_get_connected_peers(NetMesh *object,
460 GDBusMethodInvocation *invocation,
463 int ret = MESHD_ERROR_NONE;
464 mesh_service *service = (mesh_service *)user_data;
466 GVariantBuilder builder;
469 mesh_peer_info_s *peer = NULL;
471 MESH_LOGD("Request to get connected peers");
473 ret = mesh_request_get_connected_peers(service);
474 if (MESHD_ERROR_NONE != ret)
475 MESH_LOGE("Failed to mesh_request_get_connected_peers");
476 g_variant_builder_init(&builder, G_VARIANT_TYPE("aa{sv}"));
478 iter = service->connected_mesh_peers;
479 while (iter != NULL) {
480 peer = (mesh_peer_info_s*)iter->data;
482 g_variant_builder_open(&builder, G_VARIANT_TYPE_VARDICT);
483 g_variant_builder_add(&builder, "{sv}", "Address",
484 g_variant_new_string(peer->address));
485 g_variant_builder_close(&builder);
487 iter = g_list_next(iter);
490 peer_list = g_variant_builder_end(&builder);
492 net_mesh_complete_get_connected_peers(object, invocation, peer_list, ret);
497 static gboolean _meshd_dbus_handle_set_gate(NetMesh *object,
498 GDBusMethodInvocation *invocation, gboolean stp, gboolean gate_announce,
501 int ret = MESHD_ERROR_NONE;
502 mesh_service *service = (mesh_service *)user_data;
503 mesh_interface_s *info = service->interface_info;
505 MESH_LOGD("STP = %d", stp);
506 MESH_LOGD("gate_announce = %d", gate_announce);
508 /* Set STP and gate_announce */
509 ret = mesh_request_set_mesh_gate(info->bridge_interface,
510 info->mesh_interface, info->external_interface);
511 if (MESHD_ERROR_NONE != ret)
512 MESH_LOGE("Failed to mesh_request_set_mesh_gate [%d]", ret);
514 net_mesh_complete_set_gate(object, invocation, ret);
519 static gboolean _meshd_dbus_handle_unset_gate(NetMesh *object,
520 GDBusMethodInvocation *invocation,
523 int ret = MESHD_ERROR_NONE;
524 mesh_service *service = (mesh_service *)user_data;
525 mesh_interface_s *info = service->interface_info;
527 ret = mesh_request_unset_mesh_gate(info->bridge_interface,
528 info->mesh_interface, info->external_interface);
529 if (MESHD_ERROR_NONE != ret)
530 MESH_LOGE("Failed to mesh_request_unset_mesh_gate [%d]", ret);
532 net_mesh_complete_unset_gate(object, invocation, ret);
537 static gboolean _meshd_dbus_handle_set_softap(NetMesh *object,
538 GDBusMethodInvocation *invocation,
539 gchar *ssid, gchar *passphrase,
540 gchar *mode, gint channel, gint visibility, gint max_sta,
541 gint security, gpointer user_data)
543 int ret = MESHD_ERROR_NONE;
544 mesh_service *service = (mesh_service *)user_data;
545 mesh_interface_s *info = service->interface_info;
547 MESH_LOGD("SSID : %s", ssid);
548 MESH_LOGD("mode : %s", mode);
549 MESH_LOGD("channel : %d", channel);
550 MESH_LOGD("visibility: %d", visibility);
551 MESH_LOGD("max_sta : %d", max_sta);
552 MESH_LOGD("security : %d", security);
554 /* Save softAP information */
555 ret = mesh_request_set_softap_config(info->softap_interface,
556 ssid, mode, channel, visibility, max_sta,
557 security, passphrase);
558 if (MESHD_ERROR_NONE != ret)
559 MESH_LOGE("Failed to mesh_request_set_softap_config [%d]", ret);
561 net_mesh_complete_set_softap(object, invocation, ret);
566 static gboolean _meshd_dbus_handle_enable_softap(NetMesh *object,
567 GDBusMethodInvocation *invocation, gpointer user_data)
569 int ret = MESHD_ERROR_NONE;
570 mesh_service *service = (mesh_service *)user_data;
571 mesh_interface_s *info = service->interface_info;
573 /* Check softAP interface and execute it */
574 ret = mesh_request_enable_softap(info->bridge_interface, info->softap_interface);
575 if (MESHD_ERROR_NONE != ret)
576 MESH_LOGE("Failed to mesh_request_enable_softap [%d]", ret);
578 net_mesh_complete_enable_softap(object, invocation, ret);
583 static gboolean _meshd_dbus_handle_disable_softap(NetMesh *object,
584 GDBusMethodInvocation *invocation, gpointer user_data)
586 int ret = MESHD_ERROR_NONE;
587 mesh_service *service = (mesh_service *)user_data;
588 mesh_interface_s *info = service->interface_info;
591 ret = mesh_request_disable_softap(info->bridge_interface, info->softap_interface);
592 if (MESHD_ERROR_NONE != ret)
593 MESH_LOGE("Failed to mesh_request_disable_softap [%d]", ret);
595 net_mesh_complete_disable_softap(object, invocation, ret);
600 static gboolean _meshd_dbus_handle_create_mesh_network(NetMesh *object,
601 GDBusMethodInvocation *invocation,
602 gchar *mesh_id, gint channel, gint security,
605 int ret = MESHD_ERROR_NONE;
606 mesh_service *service = (mesh_service *)user_data;
607 meshd_security_type_e sec = (1 == security) ? MESHD_SECURITY_SAE : MESHD_SECURITY_NONE;
609 ret = mesh_request_create_mesh_network(service, mesh_id, channel, sec);
611 net_mesh_complete_create_mesh_network(object, invocation, ret);
616 static gboolean _meshd_dbus_handle_connect_mesh_network(NetMesh *object,
617 GDBusMethodInvocation *invocation,
618 gchar *mesh_id, gint channel, gint security, gchar *passphrase,
621 int ret = MESHD_ERROR_NONE;
622 mesh_service *service = (mesh_service *)user_data;
623 meshd_security_type_e sec = (1 == security) ? MESHD_SECURITY_SAE : MESHD_SECURITY_NONE;
625 ret = mesh_request_connect_mesh_network(service, mesh_id, channel, sec, passphrase);
627 net_mesh_complete_connect_mesh_network(object, invocation, ret);
631 static gboolean _meshd_dbus_handle_disconnect_mesh_network(NetMesh *object,
632 GDBusMethodInvocation *invocation,
633 gchar *mesh_id, gint channel, gint security,
636 int ret = MESHD_ERROR_NONE;
637 mesh_service *service = (mesh_service *)user_data;
638 meshd_security_type_e sec = (1 == security) ? MESHD_SECURITY_SAE : MESHD_SECURITY_NONE;
640 ret = mesh_request_disconnect_mesh_network(service, mesh_id, channel, sec);
642 net_mesh_complete_disconnect_mesh_network(object, invocation, ret);
647 static gboolean _meshd_dbus_handle_forget_mesh_network(NetMesh *object,
648 GDBusMethodInvocation *invocation,
649 gchar *mesh_id, gint channel, gint security,
652 int ret = MESHD_ERROR_NONE;
653 mesh_service *service = (mesh_service *)user_data;
654 meshd_security_type_e sec = (1 == security) ? MESHD_SECURITY_SAE : MESHD_SECURITY_NONE;
656 ret = mesh_request_remove_mesh_network(service, mesh_id, channel, sec);
658 net_mesh_complete_forget_mesh_network(object, invocation, ret);
663 static gboolean _meshd_dbus_handle_set_interfaces(NetMesh *object,
664 GDBusMethodInvocation *invocation,
665 gchar *mesh, gchar *gate, gchar *softap,
668 int ret = MESHD_ERROR_NONE;
669 mesh_service *service = (mesh_service *)user_data;
670 mesh_interface_s *info = service->interface_info;
672 g_free(info->mesh_interface);
673 info->mesh_interface = g_strdup(mesh);
675 g_free(info->external_interface);
676 info->external_interface = g_strdup(gate);
678 g_free(info->softap_interface);
679 info->softap_interface = g_strdup(softap);
681 MESH_LOGD("Interface configuration for mesh network :");
682 MESH_LOGD(" Base : [%s]", info->base_interface);
683 MESH_LOGD(" Mesh : [%s]", info->mesh_interface);
684 MESH_LOGD(" Bridge : [%s]", info->bridge_interface);
685 MESH_LOGD(" SoftAP : [%s]", info->softap_interface);
686 MESH_LOGD(" External: [%s]", info->external_interface);
688 net_mesh_complete_set_interfaces(object, invocation, ret);
693 static gboolean _meshd_dbus_handle_get_station_info(NetMesh *object,
694 GDBusMethodInvocation *invocation,
697 int ret = MESHD_ERROR_NONE;
699 GVariantBuilder builder;
703 mesh_service *service = (mesh_service *)user_data;
704 mesh_interface_s *info = service->interface_info;
706 /* Clear mesh station list */
707 g_list_free_full(service->station_list, _on_station_list_destroy);
708 service->station_list = NULL;
710 ret = mesh_request_get_station_info(
711 info->mesh_interface, &service->station_list);
712 if (MESHD_ERROR_NONE != ret) {
713 MESH_LOGE("Failed to mesh_request_get_station_info");
715 g_dbus_method_invocation_return_error(invocation,
716 G_DBUS_ERROR, G_DBUS_ERROR_FAILED, "Request Failed");
719 * sh-3.2# iw mesh0 station dump
720 * Station 7c:dd:90:62:37:cf (on mesh0)
721 * inactive time: 1685 ms
730 * signal avg: -63 dBm
731 * tx bitrate: 54.0 MBit/s
732 * rx bitrate: 5.5 MBit/s
736 * mesh local PS mode: ACTIVE
737 * mesh peer PS mode: ACTIVE
738 * mesh non-peer PS mode: ACTIVE
747 * beacon interval:1000
748 * short slot time:yes
749 * connected time: 256 seconds
751 /* Get station information and make variant data */
752 g_variant_builder_init(&builder, G_VARIANT_TYPE("aa{sv}"));
754 iter = service->station_list;
755 while (iter != NULL) {
756 mesh_station_info_s *item = (mesh_station_info_s*)iter->data;
758 g_variant_builder_open(&builder, G_VARIANT_TYPE_VARDICT);
759 g_variant_builder_add(&builder, "{sv}", "bssid",
760 g_variant_new_string(item->bssid));
761 g_variant_builder_add(&builder, "{sv}", "inactive_time",
762 g_variant_new_uint32(item->inactive_time));
763 g_variant_builder_add(&builder, "{sv}", "rx_bytes",
764 g_variant_new_uint64(item->rx_bytes));
765 g_variant_builder_add(&builder, "{sv}", "rx_packets",
766 g_variant_new_uint32(item->rx_packets));
767 g_variant_builder_add(&builder, "{sv}", "tx_bytes",
768 g_variant_new_uint64(item->tx_bytes));
769 g_variant_builder_add(&builder, "{sv}", "tx_packets",
770 g_variant_new_uint32(item->tx_packets));
771 g_variant_builder_add(&builder, "{sv}", "tx_retries",
772 g_variant_new_uint32(item->tx_retries));
773 g_variant_builder_add(&builder, "{sv}", "tx_failed",
774 g_variant_new_uint32(item->tx_failed));
775 g_variant_builder_add(&builder, "{sv}", "beacon_loss",
776 g_variant_new_uint32(item->beacon_loss));
777 g_variant_builder_add(&builder, "{sv}", "beacon_rx",
778 g_variant_new_uint64(item->beacon_rx));
779 g_variant_builder_add(&builder, "{sv}", "rx_drop_misc",
780 g_variant_new_uint64(item->rx_drop_misc));
781 g_variant_builder_add(&builder, "{sv}", "signal",
782 g_variant_new_int32(item->rssi));
783 g_variant_builder_add(&builder, "{sv}", "signal_avg",
784 g_variant_new_int32(item->rssi_avg));
785 g_variant_builder_add(&builder, "{sv}", "tx_bitrate",
786 g_variant_new_uint32(item->tx_bitrate)); /* 10 times */
787 g_variant_builder_add(&builder, "{sv}", "rx_bitrate",
788 g_variant_new_uint32(item->rx_bitrate)); /* 10 times */
789 g_variant_builder_add(&builder, "{sv}", "mesh_llid",
790 g_variant_new_uint16(item->llid));
791 g_variant_builder_add(&builder, "{sv}", "mesh_plid",
792 g_variant_new_uint16(item->plid));
793 g_variant_builder_add(&builder, "{sv}", "mesh_plink",
794 g_variant_new_byte(item->mesh_plink)); /* 0 : DISCON, 1 : ESTAB */
795 g_variant_builder_add(&builder, "{sv}", "local_ps_mode",
796 g_variant_new_uint32(item->local_ps_mode)); /* 0 : INACTIVE, 1 : ACTIVE */
797 g_variant_builder_add(&builder, "{sv}", "peer_ps_mode",
798 g_variant_new_uint32(item->peer_ps_mode)); /* 0 : INACTIVE, 1 : ACTIVE */
799 g_variant_builder_add(&builder, "{sv}", "non_peer_ps_mode",
800 g_variant_new_uint32(item->non_peer_ps_mode)); /* 0 : INACTIVE, 1 : ACTIVE */
801 g_variant_builder_add(&builder, "{sv}", "authorized",
802 g_variant_new_boolean(item->authorized));
803 g_variant_builder_add(&builder, "{sv}", "associated",
804 g_variant_new_boolean(item->associated));
805 g_variant_builder_add(&builder, "{sv}", "preamble",
806 g_variant_new_boolean(item->preamble));
807 g_variant_builder_add(&builder, "{sv}", "WMM_WME",
808 g_variant_new_boolean(item->wme));
809 g_variant_builder_add(&builder, "{sv}", "MFP",
810 g_variant_new_boolean(item->mfp));
811 g_variant_builder_add(&builder, "{sv}", "TDLS_peer",
812 g_variant_new_boolean(item->tdls_peer));
813 g_variant_builder_add(&builder, "{sv}", "DTIM_period",
814 g_variant_new_byte(item->dtim_period));
815 g_variant_builder_add(&builder, "{sv}", "beacon_interval",
816 g_variant_new_uint16(item->beacon_interval));
817 g_variant_builder_add(&builder, "{sv}", "short_slot_time",
818 g_variant_new_boolean(item->short_slot_time));
819 g_variant_builder_add(&builder, "{sv}", "connected_time",
820 g_variant_new_uint32(item->connected_time));
821 g_variant_builder_close(&builder);
823 iter = g_list_next(iter);
826 station = g_variant_builder_end(&builder);
827 net_mesh_complete_get_station_info(object, invocation, station, ret);
829 g_object_unref(station);
835 static gboolean _meshd_dbus_handle_get_mpath_info(NetMesh *object,
836 GDBusMethodInvocation *invocation,
839 int ret = MESHD_ERROR_NONE;
840 GVariantBuilder builder;
841 GVariant* mpath_data;
844 mesh_service *service = (mesh_service *)user_data;
845 mesh_interface_s *info = service->interface_info;
847 /* Clear mesh path list */
848 g_list_free_full(service->mpath_list, _on_mpath_list_destroy);
849 service->mpath_list = NULL;
851 ret = mesh_request_get_mpath_info(
852 info->mesh_interface, &service->mpath_list);
853 if (MESHD_ERROR_NONE != ret) {
854 MESH_LOGE("Failed to mesh_request_get_mpath_info");
856 g_dbus_method_invocation_return_error(invocation,
857 G_DBUS_ERROR, G_DBUS_ERROR_FAILED, "Request Failed");
860 * Example) sh-3.2# iw mesh0 mpath dump
861 * DEST ADDR NEXT HOP IFACE SN METRIC QLEN EXPTIME DTIM DRET FLAGS
862 * 7c:dd:90:62:37:cf 7c:dd:90:62:37:cf mesh0 221 152 0 10 100 0 0x5
864 /* Get mesh path information and make variant data */
865 g_variant_builder_init(&builder, G_VARIANT_TYPE("aa{sv}"));
867 iter = service->mpath_list;
868 while (iter != NULL) {
869 mesh_mpath_info_s *item = (mesh_mpath_info_s*)iter->data;
871 g_variant_builder_open(&builder, G_VARIANT_TYPE_VARDICT);
872 g_variant_builder_add(&builder, "{sv}", "DEST_ADDR",
873 g_variant_new_string(item->dest_addr));
874 g_variant_builder_add(&builder, "{sv}", "NEXT_HOP",
875 g_variant_new_string(item->next_hop));
876 g_variant_builder_add(&builder, "{sv}", "IFACE",
877 g_variant_new_string(item->interface));
878 g_variant_builder_add(&builder, "{sv}", "SN",
879 g_variant_new_uint32(item->sn));
880 g_variant_builder_add(&builder, "{sv}", "METRIC",
881 g_variant_new_uint32(item->metric));
882 g_variant_builder_add(&builder, "{sv}", "QLEN",
883 g_variant_new_uint32(item->qlen));
884 g_variant_builder_add(&builder, "{sv}", "EXPTIME",
885 g_variant_new_uint32(item->exptime));
886 g_variant_builder_add(&builder, "{sv}", "DTIM",
887 g_variant_new_uint32(item->discovery_timeout));
888 g_variant_builder_add(&builder, "{sv}", "DRET",
889 g_variant_new_byte(item->discovery_retries));
890 g_variant_builder_add(&builder, "{sv}", "FLAGS",
891 g_variant_new_byte(item->flags));
892 g_variant_builder_close(&builder);
894 iter = g_list_next(iter);
897 mpath_data = g_variant_builder_end(&builder);
898 net_mesh_complete_get_mpath_info(object, invocation, mpath_data, ret);
900 g_object_unref(mpath_data);
906 static void _meshd_dbus_on_activator_bus_acquired(GDBusConnection *conn,
907 const gchar *name, gpointer user_data)
910 GError *error = NULL;
911 mesh_service *service = (mesh_service *)user_data;
915 meshd_activator_dbus_object = manager_skeleton_new();
916 if (NULL == meshd_activator_dbus_object) {
917 MESH_LOGE("manager_skeleton_new() Fail");
921 g_signal_connect(meshd_activator_dbus_object, "handle-enable",
922 G_CALLBACK(_meshd_dbus_handle_enable), service);
923 g_signal_connect(meshd_activator_dbus_object, "handle-disable",
924 G_CALLBACK(_meshd_dbus_handle_disable), service);
926 ret = g_dbus_interface_skeleton_export(
927 G_DBUS_INTERFACE_SKELETON(meshd_activator_dbus_object),
928 conn, MESH_DBUS_MANAGER_OBJPATH, &error);
930 MESH_LOGE("g_dbus_interface_skeleton_export() Fail(%s)", error->message);
935 static void _meshd_dbus_on_bus_acquired(GDBusConnection *conn, const gchar *name,
939 GError *error = NULL;
940 mesh_service *service = (mesh_service *)user_data;
944 meshd_dbus_object = net_mesh_skeleton_new();
945 if (NULL == meshd_dbus_object) {
946 MESH_LOGE("net_mesh_skeleton_new() Fail");
950 g_signal_connect(meshd_dbus_object, "handle-scan",
951 G_CALLBACK(_meshd_dbus_handle_scan), service);
952 g_signal_connect(meshd_dbus_object, "handle-specific-scan",
953 G_CALLBACK(_meshd_dbus_handle_specific_scan), service);
954 g_signal_connect(meshd_dbus_object, "handle-cancel-scan",
955 G_CALLBACK(_meshd_dbus_handle_cancel_scan), service);
956 g_signal_connect(meshd_dbus_object, "handle-get-found-mesh-networks",
957 G_CALLBACK(_meshd_dbus_handle_get_found_mesh_networks), service);
958 g_signal_connect(meshd_dbus_object, "handle-enable-mesh",
959 G_CALLBACK(_meshd_dbus_handle_enable_mesh), service);
960 g_signal_connect(meshd_dbus_object, "handle-disable-mesh",
961 G_CALLBACK(_meshd_dbus_handle_disable_mesh), service);
962 g_signal_connect(meshd_dbus_object, "handle-is-joined",
963 G_CALLBACK(_meshd_dbus_handle_is_joined), service);
964 g_signal_connect(meshd_dbus_object, "handle-get-joined-mesh-network",
965 G_CALLBACK(_meshd_dbus_handle_get_joined_mesh_network), service);
966 g_signal_connect(meshd_dbus_object, "handle-get-connected-peers",
967 G_CALLBACK(_meshd_dbus_handle_get_connected_peers), service);
968 g_signal_connect(meshd_dbus_object, "handle-set-gate",
969 G_CALLBACK(_meshd_dbus_handle_set_gate), service);
970 g_signal_connect(meshd_dbus_object, "handle-unset-gate",
971 G_CALLBACK(_meshd_dbus_handle_unset_gate), service);
972 g_signal_connect(meshd_dbus_object, "handle-set-softap",
973 G_CALLBACK(_meshd_dbus_handle_set_softap), service);
974 g_signal_connect(meshd_dbus_object, "handle-enable-softap",
975 G_CALLBACK(_meshd_dbus_handle_enable_softap), service);
976 g_signal_connect(meshd_dbus_object, "handle-disable-softap",
977 G_CALLBACK(_meshd_dbus_handle_disable_softap), service);
978 g_signal_connect(meshd_dbus_object, "handle-create-mesh-network",
979 G_CALLBACK(_meshd_dbus_handle_create_mesh_network), service);
980 g_signal_connect(meshd_dbus_object, "handle-connect-mesh-network",
981 G_CALLBACK(_meshd_dbus_handle_connect_mesh_network), service);
982 g_signal_connect(meshd_dbus_object, "handle-disconnect-mesh-network",
983 G_CALLBACK(_meshd_dbus_handle_disconnect_mesh_network), service);
984 g_signal_connect(meshd_dbus_object, "handle-forget-mesh-network",
985 G_CALLBACK(_meshd_dbus_handle_forget_mesh_network), service);
986 g_signal_connect(meshd_dbus_object, "handle-set-interfaces",
987 G_CALLBACK(_meshd_dbus_handle_set_interfaces), service);
988 g_signal_connect(meshd_dbus_object, "handle-get-station-info",
989 G_CALLBACK(_meshd_dbus_handle_get_station_info), service);
990 g_signal_connect(meshd_dbus_object, "handle-get-mpath-info",
991 G_CALLBACK(_meshd_dbus_handle_get_mpath_info), service);
993 ret = g_dbus_interface_skeleton_export(G_DBUS_INTERFACE_SKELETON(meshd_dbus_object),
994 conn, MESH_DBUS_OBJPATH, &error);
996 MESH_LOGE("g_dbus_interface_skeleton_export() Fail(%s)", error->message);
1000 ret = _meshd_dbus_subscribe_name_owner_changed(conn);
1001 if (MESHD_ERROR_NONE != ret) {
1002 MESH_LOGE("_meshd_dbus_subscribe_name_owner_changed() Fail(%d)", ret);
1007 static void _meshd_dbus_on_name_lost(GDBusConnection *conn, const gchar *name,
1013 MESH_LOGD("Lost the name %s", name);
1016 static void _meshd_dbus_on_name_acquired(GDBusConnection *conn, const gchar *name,
1022 MESH_LOGD("Acquired the name %s", name);
1025 static gboolean _meshd_dbus_interface_init(mesh_service *service)
1028 guint activation_dbus_id;
1029 meshd_check_null_ret_error("service", service, FALSE);
1031 id = g_bus_own_name(G_BUS_TYPE_SYSTEM,
1032 MESH_DBUS_INTERFACE,
1033 G_BUS_NAME_OWNER_FLAGS_REPLACE,
1034 _meshd_dbus_on_bus_acquired,
1035 _meshd_dbus_on_name_acquired,
1036 _meshd_dbus_on_name_lost,
1040 MESH_LOGE("g_bus_own_name() Fail");
1044 /* Get D-Bus owner to activate mesh service daemon */
1045 activation_dbus_id = g_bus_own_name(G_BUS_TYPE_SYSTEM,
1046 MESH_DBUS_INTERFACE".manager",
1047 G_BUS_NAME_OWNER_FLAGS_REPLACE,
1048 _meshd_dbus_on_activator_bus_acquired,
1054 service->dbus_id = id;
1055 service->activation_dbus_id = activation_dbus_id;
1056 service->interface_info = g_new0(mesh_interface_s, 1);
1057 service->scanned_mesh_network = NULL;
1059 /* Initialize DBus sendor logic */
1060 meshd_dbus_start(service);
1065 static void _meshd_dbus_deinit(mesh_service *service)
1067 mesh_interface_s *info = NULL;
1068 meshd_check_null_ret("service", service);
1070 /* De-Initialize DBus sendor logic */
1071 meshd_dbus_stop(service);
1073 g_bus_unown_name(service->dbus_id);
1074 g_bus_unown_name(service->activation_dbus_id);
1076 info = service->interface_info;
1077 meshd_check_null_ret("info", info);
1078 if (info->bridge_interface)
1079 g_free(info->bridge_interface);
1080 if (info->base_interface)
1081 g_free(info->base_interface);
1082 if (info->mesh_interface)
1083 g_free(info->mesh_interface);
1084 if (info->softap_interface)
1085 g_free(info->softap_interface);
1086 if (info->external_interface)
1087 g_free(info->external_interface);
1089 if (service->joined_network) {
1090 g_free(service->joined_network->mesh_id);
1091 g_free(service->joined_network->bssid);
1092 g_free(service->joined_network);
1093 service->joined_network = NULL;
1096 /* Clear scan list */
1097 if (service->scanned_mesh_network)
1098 g_list_free_full(service->scanned_mesh_network, _on_scan_result_destroy);
1099 service->scanned_mesh_network = NULL;
1101 /* Clear connected peers list */
1102 if (service->connected_mesh_peers)
1103 g_list_free_full(service->connected_mesh_peers, _on_peer_info_destroy);
1104 service->connected_mesh_peers = NULL;
1106 /* Clear mesh path list */
1107 if (service->mpath_list)
1108 g_list_free_full(service->mpath_list, _on_mpath_list_destroy);
1109 service->mpath_list = NULL;
1111 /* Clear mesh station list */
1112 if (service->station_list)
1113 g_list_free_full(service->station_list, _on_station_list_destroy);
1114 service->station_list = NULL;
1116 g_free(service->interface_info);
1117 service->interface_info = NULL;
1120 /**< Mesh service interface initialization */
1121 gboolean meshd_service_interface_init(mesh_service *service)
1124 meshd_check_null_ret_error("service", service, FALSE);
1126 /* Initialize dbus interface */
1127 ret = _meshd_dbus_interface_init(service);
1129 MESH_LOGE("_meshd_dbus_interface_init failed!!!");
1136 /**< Mesh service interface de-initialization */
1137 void meshd_service_interface_deinit(mesh_service *service)
1139 meshd_check_null_ret("service", service);
1141 /* De-initialize dbus interface */
1142 _meshd_dbus_deinit(service);