2 * Copyright (c) 2017 Samsung Electronics Co., Ltd All Rights Reserved
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
18 #include "mesh-util.h"
19 #include "mesh-gdbus.h"
20 #include "mesh-request.h"
24 static GDBusProxy *_gproxy_connman = NULL;
25 static GDBusProxy *_gproxy_connman_mesh = NULL;
26 static GDBusProxy *_gproxy_connman_technology = NULL;
28 static int _meshd_close_gdbus_call(mesh_service *service);
30 static int __channel_to_frequency(int channel, enum nl80211_band band)
36 case NL80211_BAND_2GHZ:
39 else if (channel < 14)
40 return 2407 + channel * 5;
42 case NL80211_BAND_5GHZ:
43 if (channel >= 182 && channel <= 196)
44 return 4000 + channel * 5;
46 return 5000 + channel * 5;
56 static int __frequency_to_channel(int freq)
61 return (freq - 2407) / 5;
62 else if (freq >= 4910 && freq <= 4980)
63 return (freq - 4000) / 5;
64 else if (freq <= 45000)
65 return (freq - 5000) / 5;
66 else if (freq >= 58320 && freq <= 64800)
67 return (freq - 56160) / 2160;
72 static GDBusProxy *_proxy_get_connman(mesh_service *service)
74 GDBusProxy *proxy = NULL;
75 meshd_check_null_ret_error("service", service, NULL);
77 if (NULL == _gproxy_connman) {
78 proxy = g_dbus_proxy_new_sync(service->connection,
79 G_DBUS_PROXY_FLAGS_NONE, NULL,
82 CONNMAN_INTERFACE_MANAGER,
85 proxy = _gproxy_connman;
90 static GDBusProxy *_proxy_get_connman_mesh(mesh_service *service)
92 GDBusProxy *proxy = NULL;
93 meshd_check_null_ret_error("service", service, NULL);
95 if (NULL == _gproxy_connman_mesh) {
96 proxy = g_dbus_proxy_new_sync(service->connection,
97 G_DBUS_PROXY_FLAGS_NONE, NULL,
99 CONNMAN_OBJECT_PATH_MESH,
100 CONNMAN_INTERFACE_MESH,
103 proxy = _gproxy_connman_mesh;
108 static GDBusProxy *_proxy_get_connman_technology(mesh_service *service)
110 GDBusProxy *proxy = NULL;
111 meshd_check_null_ret_error("service", service, NULL);
113 if (NULL == _gproxy_connman_technology) {
114 proxy = g_dbus_proxy_new_sync(service->connection,
115 G_DBUS_PROXY_FLAGS_NONE, NULL,
117 CONNMAN_OBJECT_PATH_TECH_MESH,
118 CONNMAN_INTERFACE_TECH,
121 proxy = _gproxy_connman_technology;
126 static void _dbus_name_owner_notify(GObject *object, GParamSpec *pspec,
129 GDBusProxy *proxy = G_DBUS_PROXY(object);
130 gchar *name_owner = g_dbus_proxy_get_name_owner(proxy);
131 mesh_service *service = (mesh_service*)user_data;
135 if (NULL == name_owner) {
136 MESH_LOGE("name_owner is not exists !");
137 _meshd_close_gdbus_call(service);
143 static int _meshd_create_gdbus_call(mesh_service *service)
146 GError *error = NULL;
149 return MESHD_ERROR_INVALID_PARAMETER;
151 if (NULL != service->connection)
152 return MESHD_ERROR_ALREADY_REGISTERED;
154 service->connection = g_bus_get_sync(G_BUS_TYPE_SYSTEM, NULL, &error);
155 if (service->connection == NULL) {
157 MESH_LOGE("Failed to connect to the D-BUS daemon [%s]", error->message);
160 return MESHD_ERROR_IO_ERROR;
163 id = g_signal_connect(service->connection, "notify::g-name-owner",
164 G_CALLBACK(_dbus_name_owner_notify), service);
166 MESH_LOGE("g_signal_connect() Fail");
167 g_object_unref(service->connection);
168 service->connection = NULL;
169 return MESHD_ERROR_IO_ERROR;
172 return MESHD_ERROR_NONE;
175 static int _meshd_close_gdbus_call(mesh_service *service)
177 /* CHECK: is connection ref count required? */
178 g_object_unref(service->connection);
179 service->connection = NULL;
181 return MESHD_ERROR_NONE;
184 static void _meshd_signal_handler(GDBusConnection *connection,
185 const gchar *sender_name, const gchar *object_path, const gchar *interface_name,
186 const gchar *signal_name, GVariant *parameters, gpointer user_data)
188 mesh_service *service = (mesh_service*)user_data;
190 meshd_check_null_ret("user_data", user_data);
191 //meshd_check_null_ret("event_handler", service->event_handler);
193 NOTUSED(sender_name);
194 NOTUSED(object_path);
195 NOTUSED(interface_name);
196 NOTUSED(signal_name);
201 MESH_LOGD("signal received = %s", signal_name);
202 if (0 == g_strcmp0(signal_name, "ScanDone")) {
203 /* TODO: Handle event */
204 mesh_notify_scan_done();
208 static void _meshd_subscribe_event(mesh_service *service)
212 id = g_dbus_connection_signal_subscribe(
213 (GDBusConnection *)service->connection,
214 CONNMAN_SERVER_NAME, CONNMAN_INTERFACE_MANAGER,
215 "ScanDone", "/", NULL,
216 G_DBUS_CALL_FLAGS_NONE, _meshd_signal_handler, service, NULL);
218 MESH_LOGE("g_dbus_connection_signal_subscribe(ScanDone) Fail(%d)", errno);
221 service->dbus_sub_ids = g_list_append(service->dbus_sub_ids, GUINT_TO_POINTER(id));
222 MESH_LOGD("[Signal subscribe] : ScanDone (%d)", id);
224 /* End of subscription */
227 int meshd_dbus_start(mesh_service *service)
231 rv = _meshd_create_gdbus_call(service);
232 if (MESHD_ERROR_NONE != rv)
235 service->ca = g_cancellable_new();
237 /* Create all required proxies here */
238 _gproxy_connman = _proxy_get_connman(service);
239 meshd_check_null_ret_error("_gproxy_connman", _gproxy_connman,
240 MESHD_ERROR_IO_ERROR);
241 g_dbus_proxy_set_default_timeout(
242 G_DBUS_PROXY(_gproxy_connman), MESH_DBUS_PROXY_TIMEOUT);
244 _gproxy_connman_mesh = _proxy_get_connman_mesh(service);
245 meshd_check_null_ret_error("_gproxy_connman_mesh", _gproxy_connman_mesh,
246 MESHD_ERROR_IO_ERROR);
247 g_dbus_proxy_set_default_timeout(
248 G_DBUS_PROXY(_gproxy_connman_mesh), MESH_DBUS_PROXY_TIMEOUT);
250 _gproxy_connman_technology = _proxy_get_connman_technology(service);
251 meshd_check_null_ret_error("_gproxy_connman_technology", _gproxy_connman_technology,
252 MESHD_ERROR_IO_ERROR);
253 g_dbus_proxy_set_default_timeout(
254 G_DBUS_PROXY(_gproxy_connman_technology), MESH_DBUS_PROXY_TIMEOUT);
256 /* Subscribe events */
257 _meshd_subscribe_event(service);
259 return MESHD_ERROR_NONE;
262 int meshd_dbus_stop(mesh_service *service)
267 return MESHD_ERROR_INVALID_PARAMETER;
269 /* Unref all proxies here */
270 if (_gproxy_connman) {
271 g_object_unref(_gproxy_connman);
272 _gproxy_connman = NULL;
274 if (_gproxy_connman_mesh) {
275 g_object_unref(_gproxy_connman_mesh);
276 _gproxy_connman_mesh = NULL;
278 if (_gproxy_connman_technology) {
279 g_object_unref(_gproxy_connman_technology);
280 _gproxy_connman_technology = NULL;
283 g_cancellable_cancel(service->ca);
284 g_object_unref(service->ca);
287 rv = _meshd_close_gdbus_call(service);
291 int mesh_ipc_create_mesh_interface(mesh_service *service)
293 int ret = MESHD_ERROR_NONE;
294 GVariant *variant = NULL;
295 GError *error = NULL;
296 GVariant *var_dict = NULL;
298 mesh_interface_s *info = NULL;
300 meshd_check_null_ret_error("service", service, MESHD_ERROR_INVALID_PARAMETER);
301 meshd_check_null_ret_error("connection", service->connection,
302 MESHD_ERROR_INVALID_PARAMETER);
303 meshd_check_null_ret_error("_gproxy_connman_technology",
304 _gproxy_connman_technology, MESHD_ERROR_IO_ERROR);
306 info = service->interface_info;
308 g_variant_dict_init(&dict, NULL);
309 g_variant_dict_insert(&dict, "Ifname", "s", info->mesh_interface);
310 g_variant_dict_insert(&dict, "ParentIfname", "s", info->base_interface);
311 g_variant_dict_insert(&dict, "BridgeIfname", "s", info->bridge_interface);
312 var_dict = g_variant_dict_end(&dict);
314 variant = g_dbus_proxy_call_sync(_gproxy_connman_technology, "MeshCommands",
315 g_variant_new("(sv)", "MeshInterfaceAdd", var_dict),
316 G_DBUS_CALL_FLAGS_NONE,
319 MESH_LOGD("Successfully requested. [MeshInterfaceAdd]");
321 ret = MESHD_ERROR_IO_ERROR;
322 MESH_LOGE("Failed DBus call [%s]", error->message);
324 /* Interface not exists */
325 if (g_strrstr(error->message, "No such device"))
326 ret = MESHD_ERROR_INVALID_PARAMETER;
333 int mesh_ipc_remove_mesh_interface(mesh_service *service)
335 GVariant *variant = NULL;
336 GError *error = NULL;
337 GVariant *var_dict = NULL;
339 mesh_interface_s *info = NULL;
341 meshd_check_null_ret_error("service", service, MESHD_ERROR_INVALID_PARAMETER);
342 meshd_check_null_ret_error("connection", service->connection,
343 MESHD_ERROR_INVALID_PARAMETER);
344 meshd_check_null_ret_error("_gproxy_connman_technology",
345 _gproxy_connman_technology, MESHD_ERROR_IO_ERROR);
347 info = service->interface_info;
349 g_variant_dict_init(&dict, NULL);
350 g_variant_dict_insert(&dict, "Ifname", "s", info->mesh_interface);
351 var_dict = g_variant_dict_end(&dict);
353 variant = g_dbus_proxy_call_sync(_gproxy_connman_technology, "MeshCommands",
354 g_variant_new("(sv)", "MeshInterfaceRemove", var_dict),
355 G_DBUS_CALL_FLAGS_NONE,
358 MESH_LOGD("Successfully requested. [MeshInterfaceRemove]");
360 MESH_LOGE("Failed DBus call [%s]", error->message);
362 return MESHD_ERROR_IO_ERROR;
365 return MESHD_ERROR_NONE;
368 int mesh_ipc_mesh_scan(mesh_service *service)
370 meshd_check_null_ret_error("service", service, MESHD_ERROR_INVALID_PARAMETER);
371 meshd_check_null_ret_error("connection", service->connection,
372 MESHD_ERROR_INVALID_PARAMETER);
373 meshd_check_null_ret_error("_gproxy_connman_technology",
374 _gproxy_connman_technology, MESHD_ERROR_IO_ERROR);
376 g_dbus_proxy_call(_gproxy_connman_technology, "Scan",
378 G_DBUS_CALL_FLAGS_NONE,
379 -1, NULL, NULL, NULL);
381 MESH_LOGD("Successfully requested. [Scan]");
383 return MESHD_ERROR_NONE;
386 int mesh_ipc_mesh_specific_scan(mesh_service *service, gchar *mesh_id,
389 GVariant *variant = NULL;
390 GError *error = NULL;
391 GVariant *var_dict = NULL;
394 enum nl80211_band band = (channel <= 14) ? NL80211_BAND_2GHZ : NL80211_BAND_5GHZ;
395 gushort freq = __channel_to_frequency(channel, band);
397 meshd_check_null_ret_error("service", service, MESHD_ERROR_INVALID_PARAMETER);
398 meshd_check_null_ret_error("connection", service->connection,
399 MESHD_ERROR_INVALID_PARAMETER);
400 meshd_check_null_ret_error("_gproxy_connman_technology",
401 _gproxy_connman_technology, MESHD_ERROR_IO_ERROR);
403 g_variant_dict_init(&dict, NULL);
404 g_variant_dict_insert(&dict, "Name", "s", mesh_id);
405 g_variant_dict_insert(&dict, "Frequency", "q", freq);
406 var_dict = g_variant_dict_end(&dict);
408 variant = g_dbus_proxy_call_sync(_gproxy_connman_technology, "MeshCommands",
409 g_variant_new("(sv)", "MeshSpecificScan", var_dict),
410 G_DBUS_CALL_FLAGS_NONE,
413 MESH_LOGD("Successfully requested. [MeshSpecificScan]");
415 MESH_LOGE("Failed DBus call [%s]", error->message);
417 return MESHD_ERROR_IO_ERROR;
420 return MESHD_ERROR_NONE;
423 int mesh_ipc_mesh_cancel_scan(mesh_service *service)
425 GVariant *variant = NULL;
426 GError *error = NULL;
427 GVariant *var_dict = NULL;
430 meshd_check_null_ret_error("service", service, MESHD_ERROR_INVALID_PARAMETER);
431 meshd_check_null_ret_error("connection", service->connection,
432 MESHD_ERROR_INVALID_PARAMETER);
433 meshd_check_null_ret_error("_gproxy_connman_technology",
434 _gproxy_connman_technology, MESHD_ERROR_IO_ERROR);
436 g_variant_dict_init(&dict, NULL);
437 var_dict = g_variant_dict_end(&dict);
439 variant = g_dbus_proxy_call_sync(_gproxy_connman_technology, "MeshCommands",
440 g_variant_new("(sv)", "AbortScan", var_dict),
441 G_DBUS_CALL_FLAGS_NONE,
444 MESH_LOGD("Successfully requested. [AbortScan]");
446 MESH_LOGE("Failed DBus call [%s]", error->message);
448 return MESHD_ERROR_IO_ERROR;
451 return MESHD_ERROR_NONE;
454 static void _on_scan_result_destroy(gpointer data)
456 mesh_scan_result_s *scan_item = (mesh_scan_result_s *)data;
459 g_free(scan_item->mesh_id);
460 g_free(scan_item->bssid);
461 g_free(scan_item->object_path);
465 static void _on_peer_info_destroy(gpointer data)
467 mesh_peer_info_s *peer = (mesh_peer_info_s *)data;
469 g_free(peer->address);
472 static void _get_joined_network(mesh_service *service, GVariant *variant)
474 GVariantIter *peer = NULL;
475 GVariantIter *property = NULL;
477 GVariant *val = NULL;
480 const gchar* obj_path = NULL;
481 const gchar* buf = NULL;
483 g_variant_get(variant, "(a(oa{sv}))", &peer);
484 while ((child = g_variant_iter_next_value(peer))) {
485 mesh_network_info_s *joined_info = NULL;
486 gboolean valid_state = TRUE;
488 g_variant_get(child, "(oa{sv})", &obj_path, &property);
489 MESH_LOGD(" Object: [%s]", obj_path);
490 if (NULL == obj_path) {
491 MESH_LOGE("Null object");
495 /* Create an information structure for joined network */
496 joined_info = g_try_new0(mesh_network_info_s, 1);
497 if (NULL == joined_info) {
498 MESH_LOGE("Failed to allocate !");
502 while (g_variant_iter_loop(property, "{sv}", &key, &val)) {
503 if (strcasecmp(key, "Name") == 0) {
504 buf = g_variant_get_string(val, &len);
505 joined_info->mesh_id = g_strdup(buf);
507 else if (strcasecmp(key, "Address") == 0) {
508 buf = g_variant_get_string(val, &len);
509 joined_info->bssid = g_strdup(buf);
511 else if (strcasecmp(key, "State") == 0) {
512 buf = g_variant_get_string(val, &len);
513 MESH_LOGD(" State : %s", buf);
515 /* Skip ignorable state */
516 if (g_strcmp0(buf, "idle") == 0
517 || g_strcmp0(buf, "disconnect") == 0
518 || g_strcmp0(buf, "failure") == 0) {
523 else if (strcasecmp(key, "Frequency") == 0) {
524 joined_info->channel = __frequency_to_channel(g_variant_get_uint16(val));
528 /* Skip ignorable state */
529 if (FALSE == valid_state) {
530 g_free(joined_info->mesh_id);
531 g_free(joined_info->bssid);
535 MESH_LOGD(" Mesh ID : %s", joined_info->mesh_id);
536 MESH_LOGD(" BSSID : %s", joined_info->bssid);
537 MESH_LOGD(" Channel : %d", joined_info->channel);
538 service->joined_network = joined_info;
540 g_variant_iter_free(property);
542 /* If found, stop loop iteration */
545 g_variant_iter_free(peer);
548 static void _get_mesh_peers(mesh_service *service, GVariant *variant)
550 GVariantIter *peer = NULL;
551 GVariantIter *property = NULL;
553 GVariant *val = NULL;
556 const gchar* obj_path = NULL;
558 g_variant_get(variant, "(a(oa{sv}))", &peer);
559 while ((child = g_variant_iter_next_value(peer))) {
560 mesh_scan_result_s *scan_info = NULL;
562 scan_info = g_try_new0(mesh_scan_result_s, 1);
563 if (NULL == scan_info) {
564 MESH_LOGE("Failed to allocate !");
568 g_variant_get(child, "(oa{sv})", &obj_path, &property);
569 if (NULL == obj_path) {
570 MESH_LOGE("Null object");
574 MESH_LOGD(" Obj path : [%s]", obj_path);
575 scan_info->object_path = g_strdup(obj_path);
577 while (g_variant_iter_loop(property, "{sv}", &key, &val)) {
578 if (strcasecmp(key, "Name") == 0) {
579 const char *buf = g_variant_get_string(val, &len);
580 scan_info->mesh_id = g_strdup(buf);
581 MESH_LOGD(" Mesh ID : %s", scan_info->mesh_id);
583 else if (strcasecmp(key, "Address") == 0) {
584 const char *buf = g_variant_get_string(val, &len);
585 scan_info->bssid = g_strdup(buf);
586 MESH_LOGD(" BSSID : %s", scan_info->bssid);
588 else if (strcasecmp(key, "State") == 0) {
589 const char *buf = g_variant_get_string(val, &len);
590 MESH_LOGD(" State : %s", buf);
592 else if (strcasecmp(key, "Security") == 0) {
593 const char *buf = g_variant_get_string(val, &len);
594 MESH_LOGD(" Security : %s", buf);
596 else if (strcasecmp(key, "Frequency") == 0) {
597 scan_info->channel = __frequency_to_channel(g_variant_get_uint16(val));
598 MESH_LOGD(" Channel : %d", scan_info->channel);
600 else if (strcasecmp(key, "Favorite") == 0) {
601 const char *buf = g_variant_get_string(val, &len);
602 MESH_LOGD(" Favorite : %s", buf);
604 else if (strcasecmp(key, "Strength") == 0) {
605 scan_info->rssi = (gint)g_variant_get_byte(val);
606 MESH_LOGD(" RSSI : %d", scan_info->rssi);
610 service->scanned_mesh_network =
611 g_list_prepend(service->scanned_mesh_network, scan_info);
613 g_variant_iter_free(property);
615 g_variant_iter_free(peer);
618 static void _get_connected_mesh_peers(mesh_service *service, GVariant *variant)
620 GVariantIter *peer = NULL;
621 GVariantIter *property = NULL;
623 GVariant *val = NULL;
627 g_variant_get(variant, "(a(a{sv}))", &peer);
628 while ((child = g_variant_iter_next_value(peer))) {
629 mesh_peer_info_s *peer_info = NULL;
631 peer_info = g_try_new0(mesh_peer_info_s, 1);
632 if (NULL == peer_info) {
633 MESH_LOGE("Failed to allocate !");
637 g_variant_get(child, "(a{sv})", &property);
638 while (g_variant_iter_loop(property, "{sv}", &key, &val)) {
639 if (strcasecmp(key, "PeerAddress") == 0) {
640 const char *buf = g_variant_get_string(val, &len);
641 peer_info->address = g_strdup(buf);
642 MESH_LOGD(" Address : %s", peer_info->address);
646 service->connected_mesh_peers =
647 g_list_prepend(service->connected_mesh_peers, peer_info);
649 g_variant_iter_free(property);
651 g_variant_iter_free(peer);
654 int mesh_ipc_get_mesh_peers(mesh_service *service)
656 GVariant *variant = NULL;
657 GError *error = NULL;
659 meshd_check_null_ret_error("service", service, MESHD_ERROR_INVALID_PARAMETER);
660 meshd_check_null_ret_error("connection", service->connection,
661 MESHD_ERROR_INVALID_PARAMETER);
662 meshd_check_null_ret_error("_gproxy_connman",
663 _gproxy_connman, MESHD_ERROR_IO_ERROR);
665 variant = g_dbus_proxy_call_sync(_gproxy_connman, "GetMeshPeers",
667 G_DBUS_CALL_FLAGS_NONE,
670 MESH_LOGD("Successfully requested. [GetMeshPeers]");
672 if (service->scanned_mesh_network) {
673 g_list_free_full(service->scanned_mesh_network, _on_scan_result_destroy);
674 service->scanned_mesh_network = NULL;
677 _get_mesh_peers(service, variant);
679 /* List item is saved with reversed order for efficiency. */
680 service->scanned_mesh_network =
681 g_list_reverse(service->scanned_mesh_network);
683 MESH_LOGE("Failed DBus call [%s]", error->message);
685 return MESHD_ERROR_IO_ERROR;
688 return MESHD_ERROR_NONE;
691 int mesh_ipc_get_connected_peers(mesh_service *service)
693 GVariant *variant = NULL;
694 GError *error = NULL;
696 meshd_check_null_ret_error("service", service, MESHD_ERROR_INVALID_PARAMETER);
697 meshd_check_null_ret_error("connection", service->connection,
698 MESHD_ERROR_INVALID_PARAMETER);
699 meshd_check_null_ret_error("_gproxy_connman",
700 _gproxy_connman, MESHD_ERROR_IO_ERROR);
702 variant = g_dbus_proxy_call_sync(_gproxy_connman, "GetConnectedMeshPeers",
704 G_DBUS_CALL_FLAGS_NONE,
707 MESH_LOGD("Successfully requested. [GetConnectedMeshPeers]");
709 if (service->connected_mesh_peers) {
710 g_list_free_full(service->connected_mesh_peers, _on_peer_info_destroy);
711 service->connected_mesh_peers = NULL;
714 _get_connected_mesh_peers(service, variant);
716 /* List item is saved with reversed order for efficiency. */
717 service->connected_mesh_peers =
718 g_list_reverse(service->connected_mesh_peers);
720 MESH_LOGE("Failed DBus call [%s]", error->message);
722 return MESHD_ERROR_IO_ERROR;
725 return MESHD_ERROR_NONE;
728 int mesh_ipc_get_joined_mesh_network(mesh_service *service)
730 GVariant *variant = NULL;
731 GError *error = NULL;
733 meshd_check_null_ret_error("service", service, MESHD_ERROR_INVALID_PARAMETER);
734 meshd_check_null_ret_error("connection", service->connection,
735 MESHD_ERROR_INVALID_PARAMETER);
736 meshd_check_null_ret_error("_gproxy_connman",
737 _gproxy_connman, MESHD_ERROR_IO_ERROR);
739 variant = g_dbus_proxy_call_sync(_gproxy_connman, "GetMeshPeers",
741 G_DBUS_CALL_FLAGS_NONE,
744 MESH_LOGD("Successfully requested. [GetMeshPeers]");
746 if (service->joined_network) {
747 g_free(service->joined_network->mesh_id);
748 g_free(service->joined_network->bssid);
749 g_free(service->joined_network);
750 service->joined_network = NULL;
753 _get_joined_network(service, variant);
755 MESH_LOGE("Failed DBus call [%s]", error->message);
757 return MESHD_ERROR_IO_ERROR;
760 return MESHD_ERROR_NONE;
763 int mesh_ipc_create_network(mesh_service *service, gchar *mesh_id, gint channel,
766 GVariant *variant = NULL;
767 GError *error = NULL;
768 GVariant *var_dict = NULL;
769 GVariantBuilder builder;
770 const gchar* secu = (security == 0) ? "none" : "SAE";
772 enum nl80211_band band = (channel <= 14) ? NL80211_BAND_2GHZ : NL80211_BAND_5GHZ;
773 gushort freq = __channel_to_frequency(channel, band);
775 meshd_check_null_ret_error("service", service, MESHD_ERROR_INVALID_PARAMETER);
776 meshd_check_null_ret_error("connection", service->connection,
777 MESHD_ERROR_INVALID_PARAMETER);
778 meshd_check_null_ret_error("_gproxy_connman_technology",
779 _gproxy_connman_technology, MESHD_ERROR_IO_ERROR);
781 g_variant_builder_init(&builder, G_VARIANT_TYPE("a{sv}"));
782 g_variant_builder_open(&builder, G_VARIANT_TYPE("a{sv}"));
784 g_variant_builder_open(&builder, G_VARIANT_TYPE("{sv}"));
785 g_variant_builder_add(&builder, "s", "Name");
786 g_variant_builder_add(&builder, "v", g_variant_new_string(mesh_id));
787 g_variant_builder_close(&builder); /* {sv} */
789 g_variant_builder_open(&builder, G_VARIANT_TYPE("{sv}"));
790 g_variant_builder_add(&builder, "s", "Frequency");
791 g_variant_builder_add(&builder, "v", g_variant_new_uint16(freq));
792 g_variant_builder_close(&builder); /* {sv} */
794 g_variant_builder_open(&builder, G_VARIANT_TYPE("{sv}"));
795 g_variant_builder_add(&builder, "s", "Security");
796 g_variant_builder_add(&builder, "v", g_variant_new_string(secu));
797 g_variant_builder_close(&builder); /* {sv} */
799 g_variant_builder_close(&builder); /* a{sv} */
801 var_dict = g_variant_builder_end(&builder);
803 variant = g_dbus_proxy_call_sync(_gproxy_connman_technology, "MeshCommands",
804 g_variant_new("(sv)", "MeshCreateNetwork", var_dict),
805 G_DBUS_CALL_FLAGS_NONE,
808 MESH_LOGD("Successfully requested. [MeshCreateNetwork]");
810 MESH_LOGE("Failed DBus call [%s]", error->message);
812 return MESHD_ERROR_IO_ERROR;
815 return MESHD_ERROR_NONE;
818 int mesh_ipc_connect_network(mesh_service *service, mesh_scan_result_s *info)
820 int ret = MESHD_ERROR_NONE;
821 GVariant *variant = NULL;
822 GError *error = NULL;
824 meshd_check_null_ret_error("service", service, MESHD_ERROR_INVALID_PARAMETER);
825 meshd_check_null_ret_error("info", info, MESHD_ERROR_INVALID_PARAMETER);
827 variant = g_dbus_connection_call_sync(service->connection,
830 CONNMAN_INTERFACE_MESH,
833 G_DBUS_CALL_FLAGS_NONE,
836 MESH_LOGD("Successfully requested. [Connect]");
838 ret = MESHD_ERROR_IO_ERROR;
839 LOGE("Failed DBus call [%s]", error->message);
841 if (g_strrstr(error->message, "Already exists"))
842 ret = MESHD_ERROR_ALREADY_REGISTERED;
844 ret = MESHD_ERROR_IO_ERROR;
852 int mesh_ipc_disconnect_network(mesh_service *service, mesh_scan_result_s *info)
854 GVariant *variant = NULL;
855 GError *error = NULL;
857 meshd_check_null_ret_error("service", service, MESHD_ERROR_INVALID_PARAMETER);
858 meshd_check_null_ret_error("info", info, MESHD_ERROR_INVALID_PARAMETER);
860 variant = g_dbus_connection_call_sync(service->connection,
863 CONNMAN_INTERFACE_MESH,
866 G_DBUS_CALL_FLAGS_NONE,
869 MESH_LOGD("Successfully requested. [Disconnect]");
871 LOGE("Failed DBus call [%s]", error->message);
873 return MESHD_ERROR_IO_ERROR;
876 return MESHD_ERROR_NONE;
879 int mesh_ipc_remove_network(mesh_service *service, mesh_scan_result_s *info)
881 GVariant *variant = NULL;
882 GError *error = NULL;
884 meshd_check_null_ret_error("service", service, MESHD_ERROR_INVALID_PARAMETER);
885 meshd_check_null_ret_error("info", info, MESHD_ERROR_INVALID_PARAMETER);
887 variant = g_dbus_connection_call_sync(service->connection,
890 CONNMAN_INTERFACE_MESH,
893 G_DBUS_CALL_FLAGS_NONE,
896 MESH_LOGD("Successfully requested. [Remove]");
898 LOGE("Failed DBus call [%s]", error->message);
900 return MESHD_ERROR_IO_ERROR;
903 return MESHD_ERROR_NONE;