dbus.c 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184
  1. // SPDX-License-Identifier: LGPL-2.1-or-later
  2. /*
  3. *
  4. * BlueZ - Bluetooth protocol stack for Linux
  5. *
  6. * Copyright (C) 2018-2019 Intel Corporation. All rights reserved.
  7. *
  8. *
  9. */
  10. #ifdef HAVE_CONFIG_H
  11. #include <config.h>
  12. #endif
  13. #include <ell/ell.h>
  14. #include "mesh/mesh-defs.h"
  15. #include "mesh/node.h"
  16. #include "mesh/manager.h"
  17. #include "mesh/mesh.h"
  18. #include "mesh/error.h"
  19. #include "mesh/dbus.h"
  20. static struct l_dbus *dbus;
  21. struct error_entry {
  22. const char *dbus_err;
  23. const char *default_desc;
  24. };
  25. struct send_info {
  26. struct l_dbus *dbus;
  27. struct l_timeout *timeout;
  28. l_dbus_message_func_t cb;
  29. l_dbus_destroy_func_t destroy;
  30. void *user_data;
  31. uint32_t serial;
  32. };
  33. /*
  34. * Important: The entries in this table follow the order of
  35. * enumerated values in mesh_error (file error.h)
  36. */
  37. static struct error_entry const error_table[] =
  38. {
  39. { NULL, NULL },
  40. { ERROR_INTERFACE ".Failed", "Operation failed" },
  41. { ERROR_INTERFACE ".NotAuthorized", "Permission denied"},
  42. { ERROR_INTERFACE ".NotFound", "Object not found"},
  43. { ERROR_INTERFACE ".InvalidArgs", "Invalid arguments"},
  44. { ERROR_INTERFACE ".InProgress", "Operation already in progress"},
  45. { ERROR_INTERFACE ".Busy", "Busy"},
  46. { ERROR_INTERFACE ".AlreadyExists", "Already exists"},
  47. { ERROR_INTERFACE ".DoesNotExist", "Does not exist"},
  48. { ERROR_INTERFACE ".Canceled", "Operation canceled"},
  49. { ERROR_INTERFACE ".NotImplemented", "Not implemented"},
  50. };
  51. struct l_dbus_message *dbus_error(struct l_dbus_message *msg, int err,
  52. const char *description)
  53. {
  54. int array_len = L_ARRAY_SIZE(error_table);
  55. /* Default to ".Failed" */
  56. if (!err || err >= array_len)
  57. err = MESH_ERROR_FAILED;
  58. if (description)
  59. return l_dbus_message_new_error(msg,
  60. error_table[err].dbus_err,
  61. "%s", description);
  62. else
  63. return l_dbus_message_new_error(msg,
  64. error_table[err].dbus_err,
  65. "%s", error_table[err].default_desc);
  66. }
  67. struct l_dbus *dbus_get_bus(void)
  68. {
  69. return dbus;
  70. }
  71. bool dbus_init(struct l_dbus *bus)
  72. {
  73. /* Network interface */
  74. if (!mesh_dbus_init(bus))
  75. return false;
  76. /* Node interface */
  77. if (!node_dbus_init(bus))
  78. return false;
  79. /* Management interface */
  80. if (!manager_dbus_init(bus))
  81. return false;
  82. dbus = bus;
  83. return true;
  84. }
  85. bool dbus_match_interface(struct l_dbus_message_iter *interfaces,
  86. const char *match)
  87. {
  88. const char *interface;
  89. struct l_dbus_message_iter properties;
  90. while (l_dbus_message_iter_next_entry(interfaces, &interface,
  91. &properties)) {
  92. if (!strcmp(match, interface))
  93. return true;
  94. }
  95. return false;
  96. }
  97. void dbus_append_byte_array(struct l_dbus_message_builder *builder,
  98. const uint8_t *data, int len)
  99. {
  100. int i;
  101. if (!builder)
  102. return;
  103. l_dbus_message_builder_enter_array(builder, "y");
  104. for (i = 0; i < len; i++)
  105. l_dbus_message_builder_append_basic(builder, 'y', data + i);
  106. l_dbus_message_builder_leave_array(builder);
  107. }
  108. void dbus_append_dict_entry_basic(struct l_dbus_message_builder *builder,
  109. const char *key, const char *signature,
  110. const void *data)
  111. {
  112. if (!builder)
  113. return;
  114. l_dbus_message_builder_enter_dict(builder, "sv");
  115. l_dbus_message_builder_append_basic(builder, 's', key);
  116. l_dbus_message_builder_enter_variant(builder, signature);
  117. l_dbus_message_builder_append_basic(builder, signature[0], data);
  118. l_dbus_message_builder_leave_variant(builder);
  119. l_dbus_message_builder_leave_dict(builder);
  120. }
  121. static void send_reply(struct l_dbus_message *message, void *user_data)
  122. {
  123. struct send_info *info = user_data;
  124. l_timeout_remove(info->timeout);
  125. info->cb(message, info->user_data);
  126. if (info->destroy)
  127. info->destroy(info->user_data);
  128. l_free(info);
  129. }
  130. static void send_timeout(struct l_timeout *timeout, void *user_data)
  131. {
  132. struct send_info *info = user_data;
  133. l_dbus_cancel(info->dbus, info->serial);
  134. send_reply(NULL, info);
  135. }
  136. void dbus_send_with_timeout(struct l_dbus *dbus, struct l_dbus_message *msg,
  137. l_dbus_message_func_t cb,
  138. void *user_data,
  139. l_dbus_destroy_func_t destroy,
  140. unsigned int seconds)
  141. {
  142. struct send_info *info = l_new(struct send_info, 1);
  143. info->dbus = dbus;
  144. info->cb = cb;
  145. info->user_data = user_data;
  146. info->destroy = destroy;
  147. info->serial = l_dbus_send_with_reply(dbus, msg, send_reply,
  148. info, NULL);
  149. info->timeout = l_timeout_create(seconds, send_timeout, info, NULL);
  150. }