2 * Copyright (c) 2020 Samsung Electronics Co., Ltd.
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 <uwb-log-def.h>
19 #include <uwb-error-def.h>
21 #include <GdbusError.h>
22 #include <UwbDbusIfaceAdapter.h>
24 using namespace UwbManagerNamespace;
26 #define ret_err_if_nullptr(value) do { \
27 if ((value) == nullptr) { \
28 __dbus_return_err(UWB_ERROR_OPERATION_FAILED, invocation); \
29 __UWB_LOG_FUNC_EXIT__; \
34 #define ret_err_if_non_zero(value) do { \
36 __dbus_return_err(UWB_ERROR_OPERATION_FAILED, invocation); \
37 __UWB_LOG_FUNC_EXIT__; \
42 #define DBUS_DEBUG_VARIANT(parameters) \
44 gchar *parameters_debug_str = NULL;\
46 parameters_debug_str = g_variant_print(parameters, TRUE);\
47 UWB_LOGI("signal params [%s]", parameters_debug_str ? parameters_debug_str : "NULL");\
48 g_free(parameters_debug_str);\
51 static void __dbus_return_err(uwb_error_e ret, GDBusMethodInvocation *invocation)
53 GdbusError gdbus_error;
55 gchar* dbus_error_name = NULL;
60 gdbus_error.setGerror(ret, &err);
61 dbus_error_name = g_dbus_error_encode_gerror(err);
62 UWB_LOGI("g_dbus_method_invocation_return_gerror with [%s]", dbus_error_name);
63 g_free(dbus_error_name);
64 g_dbus_method_invocation_return_gerror(invocation, err);
69 static gboolean __handle_test(
70 UwbGdbuslibManager *gdbus_manager,
71 GDBusMethodInvocation *invocation,
74 __UWB_LOG_FUNC_ENTER__;
76 UwbDbusIfaceAdapter *iface_adapter = (UwbDbusIfaceAdapter *)user_data;
77 ret_err_if_nullptr(iface_adapter);
79 auto handler = iface_adapter->getTest();
80 ret_err_if_nullptr(handler);
83 ret_err_if_non_zero(ret);
85 uwb_gdbuslib_manager_complete_test(gdbus_manager, invocation);
87 __UWB_LOG_FUNC_EXIT__;
91 static gboolean __handle_reset(
92 UwbGdbuslibManager *gdbus_manager,
93 GDBusMethodInvocation *invocation,
96 __UWB_LOG_FUNC_ENTER__;
99 UwbDbusIfaceAdapter *iface_adapter = (UwbDbusIfaceAdapter *)user_data;
100 ret_err_if_nullptr(iface_adapter);
102 auto handler = iface_adapter->getReset();
103 ret_err_if_nullptr(handler);
106 ret_err_if_non_zero(ret);
108 uwb_gdbuslib_manager_complete_reset(gdbus_manager, invocation);
110 __UWB_LOG_FUNC_EXIT__;
114 static gboolean __handle_factory_reset(
115 UwbGdbuslibManager *gdbus_manager,
116 GDBusMethodInvocation *invocation,
119 __UWB_LOG_FUNC_ENTER__;
122 UwbDbusIfaceAdapter *iface_adapter = (UwbDbusIfaceAdapter *)user_data;
123 ret_err_if_nullptr(iface_adapter);
125 auto handler = iface_adapter->getFactoryReset();
126 ret_err_if_nullptr(handler);
129 ret_err_if_non_zero(ret);
131 uwb_gdbuslib_manager_complete_factory_reset(gdbus_manager, invocation);
133 __UWB_LOG_FUNC_EXIT__;
137 static gboolean __handle_enable_network(
138 UwbGdbuslibManager *gdbus_manager,
139 GDBusMethodInvocation *invocation,
142 __UWB_LOG_FUNC_ENTER__;
145 UwbDbusIfaceAdapter *iface_adapter = (UwbDbusIfaceAdapter *)user_data;
146 ret_err_if_nullptr(iface_adapter);
148 auto handler = iface_adapter->getEnableNetwork();
149 ret_err_if_nullptr(handler);
152 ret_err_if_non_zero(ret);
154 uwb_gdbuslib_manager_complete_enable_network(gdbus_manager, invocation);
156 __UWB_LOG_FUNC_EXIT__;
160 static gboolean __handle_disable_network(
161 UwbGdbuslibManager *gdbus_manager,
162 GDBusMethodInvocation *invocation,
165 __UWB_LOG_FUNC_ENTER__;
168 UwbDbusIfaceAdapter *iface_adapter = (UwbDbusIfaceAdapter *)user_data;
169 ret_err_if_nullptr(iface_adapter);
171 auto handler = iface_adapter->getDisableNetwork();
172 ret_err_if_nullptr(handler);
175 ret_err_if_non_zero(ret);
177 uwb_gdbuslib_manager_complete_disable_network(gdbus_manager, invocation);
179 __UWB_LOG_FUNC_EXIT__;
183 static gboolean __handle_start_location_engine(
184 UwbGdbuslibManager *gdbus_manager,
185 GDBusMethodInvocation *invocation,
190 __UWB_LOG_FUNC_ENTER__;
193 UwbDbusIfaceAdapter *iface_adapter = (UwbDbusIfaceAdapter *)user_data;
194 ret_err_if_nullptr(iface_adapter);
196 auto handler = iface_adapter->getStartLocationEngine();
197 ret_err_if_nullptr(handler);
199 int ret = handler(server, port);
200 ret_err_if_non_zero(ret);
202 uwb_gdbuslib_manager_complete_start_location_engine(gdbus_manager, invocation);
204 __UWB_LOG_FUNC_EXIT__;
208 static gboolean __handle_stop_location_engine(
209 UwbGdbuslibManager *gdbus_manager,
210 GDBusMethodInvocation *invocation,
213 __UWB_LOG_FUNC_ENTER__;
216 UwbDbusIfaceAdapter *iface_adapter = (UwbDbusIfaceAdapter *)user_data;
217 ret_err_if_nullptr(iface_adapter);
219 auto handler = iface_adapter->getStopLocationEngine();
220 ret_err_if_nullptr(handler);
223 ret_err_if_non_zero(ret);
225 uwb_gdbuslib_manager_complete_stop_location_engine(gdbus_manager, invocation);
227 __UWB_LOG_FUNC_EXIT__;
231 static void __build_node_variant(Node &node, GVariant **node_gvar)
233 GVariantBuilder *builder = g_variant_builder_new(G_VARIANT_TYPE("a{sv}"));
235 g_variant_builder_add(builder, "{sv}", "Distance",
236 g_variant_new_uint64(node.getDistance()));
237 g_variant_builder_add(builder, "{sv}", "PanID",
238 g_variant_new_uint16(node.getPanId()));
239 g_variant_builder_add(builder, "{sv}", "NodeID",
240 g_variant_new_uint64(node.getNodeId()));
241 g_variant_builder_add(builder, "{sv}", "X",
242 g_variant_new_int32(node.getX()));
243 g_variant_builder_add(builder, "{sv}", "Y",
244 g_variant_new_int32(node.getY()));
245 g_variant_builder_add(builder, "{sv}", "Z",
246 g_variant_new_int32(node.getZ()));
248 *node_gvar = g_variant_builder_end(builder);
249 g_variant_builder_unref(builder);
252 static gboolean __handle_get_own_node(
253 UwbGdbuslibManager *gdbus_manager,
254 GDBusMethodInvocation *invocation,
257 __UWB_LOG_FUNC_ENTER__;
260 UwbDbusIfaceAdapter *iface_adapter = (UwbDbusIfaceAdapter *)user_data;
261 ret_err_if_nullptr(iface_adapter);
263 auto handler = iface_adapter->getGetOwnNode();
264 ret_err_if_nullptr(handler);
266 Node &node_ref = handler();
267 GVariant *node_gvar = nullptr;
268 __build_node_variant(node_ref, &node_gvar);
270 uwb_gdbuslib_manager_complete_get_own_node(gdbus_manager, invocation, node_gvar);
272 __UWB_LOG_FUNC_EXIT__;
276 static void __build_network_variant(std::map<int, std::unique_ptr<Node>> &node_map, GVariant **networks_gvar)
278 GVariantBuilder *builder = g_variant_builder_new(G_VARIANT_TYPE("aa{sv}"));
280 for (const auto &elem : node_map) {
281 Node *node_ptr = elem.second.get();
282 g_variant_builder_open(builder, G_VARIANT_TYPE_VARDICT);
283 g_variant_builder_add(builder, "{sv}", "Distance",
284 g_variant_new_uint64(node_ptr->getDistance()));
285 g_variant_builder_add(builder, "{sv}", "PanID",
286 g_variant_new_uint16(node_ptr->getPanId()));
287 g_variant_builder_add(builder, "{sv}", "NodeID",
288 g_variant_new_uint64(node_ptr->getNodeId()));
289 g_variant_builder_add(builder, "{sv}", "X",
290 g_variant_new_int32(node_ptr->getX()));
291 g_variant_builder_add(builder, "{sv}", "Y",
292 g_variant_new_int32(node_ptr->getY()));
293 g_variant_builder_add(builder, "{sv}", "Z",
294 g_variant_new_int32(node_ptr->getZ()));
295 g_variant_builder_add(builder, "{sv}", "Range",
296 g_variant_new_int32(node_ptr->getRange()));
297 g_variant_builder_add(builder, "{sv}", "Aoa",
298 g_variant_new_int32(node_ptr->getAoa()));
299 g_variant_builder_add(builder, "{sv}", "Pdoa",
300 g_variant_new_int32(node_ptr->getPdoa()));
301 g_variant_builder_add(builder, "{sv}", "FilteredRange",
302 g_variant_new_int32((int)node_ptr->getFilteredRange()));
303 g_variant_builder_add(builder, "{sv}", "FilteredAoa",
304 g_variant_new_int32((int)node_ptr->getFilteredAoa()));
305 g_variant_builder_close(builder);
308 *networks_gvar = g_variant_builder_end(builder);
309 g_variant_builder_unref(builder);
312 static gboolean __handle_get_network_info(
313 UwbGdbuslibManager *gdbus_manager,
314 GDBusMethodInvocation *invocation,
317 __UWB_LOG_FUNC_ENTER__;
320 UwbDbusIfaceAdapter *iface_adapter = (UwbDbusIfaceAdapter *)user_data;
321 ret_err_if_nullptr(iface_adapter);
323 auto handler = iface_adapter->getGetNetworkInfo();
324 ret_err_if_nullptr(handler);
326 GVariant *networks_gvar = nullptr;
327 auto &network_map = handler();
328 __build_network_variant(network_map, &networks_gvar);
330 uwb_gdbuslib_manager_complete_get_network_info(gdbus_manager, invocation,
331 (uint16_t)0, networks_gvar);
333 __UWB_LOG_FUNC_EXIT__;
337 static gboolean __handle_set_configurations(
338 UwbGdbuslibManager *gdbus_manager,
339 GDBusMethodInvocation *invocation,
341 GVariant *configurations,
344 __UWB_LOG_FUNC_ENTER__;
347 UwbDbusIfaceAdapter *iface_adapter = (UwbDbusIfaceAdapter *)user_data;
348 ret_err_if_nullptr(iface_adapter);
350 auto handler = iface_adapter->getSetConfigurations();
351 ret_err_if_nullptr(handler);
353 DBUS_DEBUG_VARIANT(configurations);
354 int ret = handler(configurations);
355 ret_err_if_non_zero(ret);
357 uwb_gdbuslib_manager_complete_set_configurations(gdbus_manager, invocation);
359 __UWB_LOG_FUNC_EXIT__;
363 static gboolean __handle_get_configurations(
364 UwbGdbuslibManager *gdbus_manager,
365 GDBusMethodInvocation *invocation,
369 __UWB_LOG_FUNC_ENTER__;
372 UwbDbusIfaceAdapter *iface_adapter = (UwbDbusIfaceAdapter *)user_data;
373 ret_err_if_nullptr(iface_adapter);
375 auto handler = iface_adapter->getGetConfigurations();
376 ret_err_if_nullptr(handler);
378 GVariant *config_gvar = handler();
379 ret_err_if_nullptr(config_gvar);
381 g_variant_ref(config_gvar);
382 DBUS_DEBUG_VARIANT(config_gvar);
383 uwb_gdbuslib_manager_complete_get_configurations(gdbus_manager, invocation, config_gvar);
385 __UWB_LOG_FUNC_EXIT__;
389 static gboolean __handle_set_position(
390 UwbGdbuslibManager *gdbus_manager,
391 GDBusMethodInvocation *invocation,
398 __UWB_LOG_FUNC_ENTER__;
401 UwbDbusIfaceAdapter *iface_adapter = (UwbDbusIfaceAdapter *)user_data;
402 ret_err_if_nullptr(iface_adapter);
404 auto handler = iface_adapter->getSetPosition();
405 ret_err_if_nullptr(handler);
409 uwb_gdbuslib_manager_complete_set_position(gdbus_manager, invocation);
411 __UWB_LOG_FUNC_EXIT__;
415 static gint __ay_to_guchar(GVariant *src, int size, guchar **dst)
417 if (src == nullptr || dst == nullptr || size == 0)
421 g_variant_get(src, "a(y)", &iter);
423 int result_size = g_variant_iter_n_children(iter);
424 if (result_size == 0 || result_size != size)
427 guchar *buffer = (guchar *)g_try_malloc0(result_size);
434 while (g_variant_iter_loop(iter, "(y)", &element)) {
435 *(buffer + pos) = element;
439 g_variant_iter_free(iter);
445 static gboolean __handle_send_message(
446 UwbGdbuslibManager *gdbus_manager,
447 GDBusMethodInvocation *invocation,
452 __UWB_LOG_FUNC_ENTER__;
455 UwbDbusIfaceAdapter *iface_adapter = (UwbDbusIfaceAdapter *)user_data;
456 ret_err_if_nullptr(iface_adapter);
458 auto handler = iface_adapter->getSendMessage();
459 ret_err_if_nullptr(handler);
461 guchar *buffer = nullptr;
462 if (__ay_to_guchar(message, message_length, &buffer) == 0) {
463 __dbus_return_err(UWB_ERROR_INVALID_PARAMETER, invocation);
464 __UWB_LOG_FUNC_EXIT__;
468 int ret = handler(buffer, message_length);
470 ret_err_if_non_zero(ret);
472 uwb_gdbuslib_manager_complete_send_message(gdbus_manager, invocation);
474 __UWB_LOG_FUNC_EXIT__;
478 static gboolean __handle_send_message_to(
479 UwbGdbuslibManager *gdbus_manager,
480 GDBusMethodInvocation *invocation,
486 __UWB_LOG_FUNC_ENTER__;
488 UwbDbusIfaceAdapter *iface_adapter = (UwbDbusIfaceAdapter *)user_data;
489 ret_err_if_nullptr(iface_adapter);
491 auto handler = iface_adapter->getSendMessageTo();
492 ret_err_if_nullptr(handler);
494 guchar *buffer = nullptr;
495 if (__ay_to_guchar(message, message_length, &buffer) == 0) {
496 __dbus_return_err(UWB_ERROR_INVALID_PARAMETER, invocation);
497 __UWB_LOG_FUNC_EXIT__;
501 int ret = handler(node_id, buffer, message_length);
503 ret_err_if_non_zero(ret);
505 uwb_gdbuslib_manager_complete_send_message_to(gdbus_manager, invocation);
507 __UWB_LOG_FUNC_EXIT__;
511 static std::pair<std::string, void *> handlers[] = {
512 std::make_pair(std::string{"handle-test"}, (void *)__handle_test),
513 std::make_pair(std::string{"handle-reset"}, (void *)__handle_reset),
514 std::make_pair(std::string{"handle-factory-reset"}, (void *)__handle_factory_reset),
516 std::make_pair(std::string{"handle-enable-network"}, (void *)__handle_enable_network),
517 std::make_pair(std::string{"handle-disable-network"}, (void *)__handle_disable_network),
519 std::make_pair(std::string{"handle-start-location-engine"}, (void *)__handle_start_location_engine),
520 std::make_pair(std::string{"handle-stop-location-engine"}, (void *)__handle_stop_location_engine),
522 std::make_pair(std::string{"handle-get-own-node"}, (void *)__handle_get_own_node),
523 std::make_pair(std::string{"handle-get-network-info"}, (void *)__handle_get_network_info),
525 std::make_pair(std::string{"handle-set-configurations"}, (void *)__handle_set_configurations),
526 std::make_pair(std::string{"handle-get-configurations"}, (void *)__handle_get_configurations),
528 std::make_pair(std::string{"handle-set-position"}, (void *)__handle_set_position),
530 std::make_pair(std::string{"handle-send-message"}, (void *)__handle_send_message),
531 std::make_pair(std::string{"handle-send-message-to"}, (void *)__handle_send_message_to)
534 void UwbDbusIfaceAdapter::init(GDBusConnection *connection,
535 UwbGdbuslibManager *manager_skeleton)
537 __UWB_LOG_FUNC_ENTER__;
539 /* Register method callbacks as signal callback */
540 for (const auto &handler : handlers)
543 handler.first.c_str(),
544 G_CALLBACK(handler.second),
547 /* Set connection to 'manager' */
548 GDBusObjectManagerServer *manager =
549 g_dbus_object_manager_server_new(this->_uwb_dbus_path_str.c_str());
550 g_dbus_object_manager_server_set_connection(manager, connection);
552 /* Export 'manager' interface on UWB DBUS */
553 GError *error = NULL;
554 gboolean ret = g_dbus_interface_skeleton_export(
555 G_DBUS_INTERFACE_SKELETON(manager_skeleton),
556 connection, this->_uwb_dbus_path_str.c_str(), &error);
559 UWB_LOGE("Can not skeleton_export %s", error->message);
563 __UWB_LOG_FUNC_EXIT__;