dbus.c 43 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812
  1. /*
  2. *
  3. * Embedded Linux library
  4. *
  5. * Copyright (C) 2011-2014 Intel Corporation. All rights reserved.
  6. *
  7. * This library is free software; you can redistribute it and/or
  8. * modify it under the terms of the GNU Lesser General Public
  9. * License as published by the Free Software Foundation; either
  10. * version 2.1 of the License, or (at your option) any later version.
  11. *
  12. * This library is distributed in the hope that it will be useful,
  13. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  14. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  15. * Lesser General Public License for more details.
  16. *
  17. * You should have received a copy of the GNU Lesser General Public
  18. * License along with this library; if not, write to the Free Software
  19. * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
  20. *
  21. */
  22. #ifdef HAVE_CONFIG_H
  23. #include <config.h>
  24. #endif
  25. #define _GNU_SOURCE
  26. #include <stdio.h>
  27. #include <fcntl.h>
  28. #include <unistd.h>
  29. #include <stdlib.h>
  30. #include <string.h>
  31. #include <sys/socket.h>
  32. #include <sys/un.h>
  33. #include <errno.h>
  34. #include "util.h"
  35. #include "io.h"
  36. #include "idle.h"
  37. #include "queue.h"
  38. #include "hashmap.h"
  39. #include "dbus.h"
  40. #include "private.h"
  41. #include "useful.h"
  42. #include "dbus-private.h"
  43. #define DEFAULT_SYSTEM_BUS_ADDRESS "unix:path=/var/run/dbus/system_bus_socket"
  44. #define DBUS_SERVICE_DBUS "org.freedesktop.DBus"
  45. #define DBUS_PATH_DBUS "/org/freedesktop/DBus"
  46. #define DBUS_MAXIMUM_MATCH_RULE_LENGTH 1024
  47. enum auth_state {
  48. WAITING_FOR_OK,
  49. WAITING_FOR_AGREE_UNIX_FD,
  50. SETUP_DONE
  51. };
  52. struct l_dbus_ops {
  53. char version;
  54. bool (*send_message)(struct l_dbus *bus,
  55. struct l_dbus_message *message);
  56. struct l_dbus_message *(*recv_message)(struct l_dbus *bus);
  57. void (*free)(struct l_dbus *bus);
  58. struct _dbus_name_ops name_ops;
  59. struct _dbus_filter_ops filter_ops;
  60. uint32_t (*name_acquire)(struct l_dbus *dbus, const char *name,
  61. bool allow_replacement, bool replace_existing,
  62. bool queue, l_dbus_name_acquire_func_t callback,
  63. void *user_data);
  64. };
  65. struct l_dbus {
  66. struct l_io *io;
  67. char *guid;
  68. bool negotiate_unix_fd;
  69. bool support_unix_fd;
  70. bool is_ready;
  71. char *unique_name;
  72. unsigned int next_id;
  73. uint32_t next_serial;
  74. struct l_queue *message_queue;
  75. struct l_hashmap *message_list;
  76. struct l_hashmap *signal_list;
  77. l_dbus_ready_func_t ready_handler;
  78. l_dbus_destroy_func_t ready_destroy;
  79. void *ready_data;
  80. l_dbus_disconnect_func_t disconnect_handler;
  81. l_dbus_destroy_func_t disconnect_destroy;
  82. void *disconnect_data;
  83. l_dbus_debug_func_t debug_handler;
  84. l_dbus_destroy_func_t debug_destroy;
  85. void *debug_data;
  86. struct _dbus_object_tree *tree;
  87. struct _dbus_name_cache *name_cache;
  88. struct _dbus_filter *filter;
  89. bool name_notify_enabled;
  90. const struct l_dbus_ops *driver;
  91. };
  92. struct l_dbus_classic {
  93. struct l_dbus super;
  94. void *auth_command;
  95. enum auth_state auth_state;
  96. struct l_hashmap *match_strings;
  97. int *fd_buf;
  98. unsigned int num_fds;
  99. };
  100. struct message_callback {
  101. uint32_t serial;
  102. struct l_dbus_message *message;
  103. l_dbus_message_func_t callback;
  104. l_dbus_destroy_func_t destroy;
  105. void *user_data;
  106. };
  107. struct signal_callback {
  108. unsigned int id;
  109. l_dbus_message_func_t callback;
  110. l_dbus_destroy_func_t destroy;
  111. void *user_data;
  112. };
  113. static void message_queue_destroy(void *data)
  114. {
  115. struct message_callback *callback = data;
  116. l_dbus_message_unref(callback->message);
  117. if (callback->destroy)
  118. callback->destroy(callback->user_data);
  119. l_free(callback);
  120. }
  121. static void message_list_destroy(void *value)
  122. {
  123. message_queue_destroy(value);
  124. }
  125. static void signal_list_destroy(void *value)
  126. {
  127. struct signal_callback *callback = value;
  128. if (callback->destroy)
  129. callback->destroy(callback->user_data);
  130. l_free(callback);
  131. }
  132. static bool message_write_handler(struct l_io *io, void *user_data)
  133. {
  134. struct l_dbus *dbus = user_data;
  135. struct l_dbus_message *message;
  136. struct message_callback *callback;
  137. const void *header, *body;
  138. size_t header_size, body_size;
  139. callback = l_queue_pop_head(dbus->message_queue);
  140. if (!callback)
  141. return false;
  142. message = callback->message;
  143. if (_dbus_message_get_type(message) == DBUS_MESSAGE_TYPE_METHOD_CALL &&
  144. callback->callback == NULL)
  145. l_dbus_message_set_no_reply(message, true);
  146. _dbus_message_set_serial(message, callback->serial);
  147. if (!dbus->driver->send_message(dbus, message)) {
  148. message_queue_destroy(callback);
  149. return false;
  150. }
  151. header = _dbus_message_get_header(message, &header_size);
  152. body = _dbus_message_get_body(message, &body_size);
  153. l_util_hexdump_two(false, header, header_size, body, body_size,
  154. dbus->debug_handler, dbus->debug_data);
  155. if (callback->callback == NULL) {
  156. message_queue_destroy(callback);
  157. goto done;
  158. }
  159. l_hashmap_insert(dbus->message_list,
  160. L_UINT_TO_PTR(callback->serial), callback);
  161. done:
  162. if (l_queue_isempty(dbus->message_queue))
  163. return false;
  164. /* Only continue sending messges if the connection is ready */
  165. return dbus->is_ready;
  166. }
  167. static void handle_method_return(struct l_dbus *dbus,
  168. struct l_dbus_message *message)
  169. {
  170. struct message_callback *callback;
  171. uint32_t reply_serial;
  172. reply_serial = _dbus_message_get_reply_serial(message);
  173. if (reply_serial == 0)
  174. return;
  175. callback = l_hashmap_remove(dbus->message_list,
  176. L_UINT_TO_PTR(reply_serial));
  177. if (!callback)
  178. return;
  179. if (callback->callback)
  180. callback->callback(message, callback->user_data);
  181. message_queue_destroy(callback);
  182. }
  183. static void handle_error(struct l_dbus *dbus, struct l_dbus_message *message)
  184. {
  185. struct message_callback *callback;
  186. uint32_t reply_serial;
  187. reply_serial = _dbus_message_get_reply_serial(message);
  188. if (reply_serial == 0)
  189. return;
  190. callback = l_hashmap_remove(dbus->message_list,
  191. L_UINT_TO_PTR(reply_serial));
  192. if (!callback)
  193. return;
  194. if (callback->callback)
  195. callback->callback(message, callback->user_data);
  196. message_queue_destroy(callback);
  197. }
  198. static void process_signal(const void *key, void *value, void *user_data)
  199. {
  200. struct signal_callback *callback = value;
  201. struct l_dbus_message *message = user_data;
  202. if (callback->callback)
  203. callback->callback(message, callback->user_data);
  204. }
  205. static void handle_signal(struct l_dbus *dbus, struct l_dbus_message *message)
  206. {
  207. l_hashmap_foreach(dbus->signal_list, process_signal, message);
  208. }
  209. static bool message_read_handler(struct l_io *io, void *user_data)
  210. {
  211. struct l_dbus *dbus = user_data;
  212. struct l_dbus_message *message;
  213. const void *header, *body;
  214. size_t header_size, body_size;
  215. enum dbus_message_type msgtype;
  216. message = dbus->driver->recv_message(dbus);
  217. if (!message)
  218. return true;
  219. header = _dbus_message_get_header(message, &header_size);
  220. body = _dbus_message_get_body(message, &body_size);
  221. l_util_hexdump_two(true, header, header_size, body, body_size,
  222. dbus->debug_handler, dbus->debug_data);
  223. msgtype = _dbus_message_get_type(message);
  224. switch (msgtype) {
  225. case DBUS_MESSAGE_TYPE_METHOD_RETURN:
  226. handle_method_return(dbus, message);
  227. break;
  228. case DBUS_MESSAGE_TYPE_ERROR:
  229. handle_error(dbus, message);
  230. break;
  231. case DBUS_MESSAGE_TYPE_SIGNAL:
  232. handle_signal(dbus, message);
  233. break;
  234. case DBUS_MESSAGE_TYPE_METHOD_CALL:
  235. if (!_dbus_object_tree_dispatch(dbus->tree, dbus, message)) {
  236. struct l_dbus_message *error;
  237. error = l_dbus_message_new_error(message,
  238. "org.freedesktop.DBus.Error.NotFound",
  239. "No matching method found");
  240. l_dbus_send(dbus, error);
  241. }
  242. break;
  243. }
  244. l_dbus_message_unref(message);
  245. return true;
  246. }
  247. static uint32_t send_message(struct l_dbus *dbus, bool priority,
  248. struct l_dbus_message *message,
  249. l_dbus_message_func_t function,
  250. void *user_data, l_dbus_destroy_func_t destroy)
  251. {
  252. struct message_callback *callback;
  253. enum dbus_message_type type;
  254. const char *path;
  255. type = _dbus_message_get_type(message);
  256. if ((type == DBUS_MESSAGE_TYPE_METHOD_RETURN ||
  257. type == DBUS_MESSAGE_TYPE_ERROR) &&
  258. _dbus_message_get_reply_serial(message) == 0) {
  259. l_dbus_message_unref(message);
  260. return 0;
  261. }
  262. /* Default empty signature for method return messages */
  263. if (type == DBUS_MESSAGE_TYPE_METHOD_RETURN &&
  264. !l_dbus_message_get_signature(message))
  265. l_dbus_message_set_arguments(message, "");
  266. callback = l_new(struct message_callback, 1);
  267. callback->serial = dbus->next_serial++;
  268. callback->message = message;
  269. callback->callback = function;
  270. callback->destroy = destroy;
  271. callback->user_data = user_data;
  272. if (priority) {
  273. l_queue_push_head(dbus->message_queue, callback);
  274. l_io_set_write_handler(dbus->io, message_write_handler,
  275. dbus, NULL);
  276. return callback->serial;
  277. }
  278. path = l_dbus_message_get_path(message);
  279. if (path)
  280. _dbus_object_tree_signals_flush(dbus, path);
  281. l_queue_push_tail(dbus->message_queue, callback);
  282. if (dbus->is_ready)
  283. l_io_set_write_handler(dbus->io, message_write_handler,
  284. dbus, NULL);
  285. return callback->serial;
  286. }
  287. static void bus_ready(struct l_dbus *dbus)
  288. {
  289. dbus->is_ready = true;
  290. if (dbus->ready_handler)
  291. dbus->ready_handler(dbus->ready_data);
  292. l_io_set_read_handler(dbus->io, message_read_handler, dbus, NULL);
  293. /* Check for messages added before the connection was ready */
  294. if (l_queue_isempty(dbus->message_queue))
  295. return;
  296. l_io_set_write_handler(dbus->io, message_write_handler, dbus, NULL);
  297. }
  298. static void hello_callback(struct l_dbus_message *message, void *user_data)
  299. {
  300. struct l_dbus *dbus = user_data;
  301. const char *signature;
  302. const char *unique_name;
  303. signature = l_dbus_message_get_signature(message);
  304. if (!signature || strcmp(signature, "s")) {
  305. close(l_io_get_fd(dbus->io));
  306. return;
  307. }
  308. if (!l_dbus_message_get_arguments(message, "s", &unique_name)) {
  309. close(l_io_get_fd(dbus->io));
  310. return;
  311. }
  312. dbus->unique_name = l_strdup(unique_name);
  313. bus_ready(dbus);
  314. }
  315. static bool auth_write_handler(struct l_io *io, void *user_data)
  316. {
  317. struct l_dbus_classic *classic = user_data;
  318. struct l_dbus *dbus = &classic->super;
  319. ssize_t written, len;
  320. int fd;
  321. fd = l_io_get_fd(io);
  322. if (!classic->auth_command)
  323. return false;
  324. len = strlen(classic->auth_command);
  325. if (!len)
  326. return false;
  327. written = L_TFR(send(fd, classic->auth_command, len, 0));
  328. if (written < 0)
  329. return false;
  330. l_util_hexdump(false, classic->auth_command, written,
  331. dbus->debug_handler, dbus->debug_data);
  332. if (written < len) {
  333. memmove(classic->auth_command, classic->auth_command + written,
  334. len + 1 - written);
  335. return true;
  336. }
  337. l_free(classic->auth_command);
  338. classic->auth_command = NULL;
  339. if (classic->auth_state == SETUP_DONE) {
  340. struct l_dbus_message *message;
  341. l_io_set_read_handler(dbus->io, message_read_handler,
  342. dbus, NULL);
  343. message = l_dbus_message_new_method_call(dbus,
  344. DBUS_SERVICE_DBUS,
  345. DBUS_PATH_DBUS,
  346. L_DBUS_INTERFACE_DBUS,
  347. "Hello");
  348. l_dbus_message_set_arguments(message, "");
  349. send_message(dbus, true, message, hello_callback, dbus, NULL);
  350. return true;
  351. }
  352. return false;
  353. }
  354. static bool auth_read_handler(struct l_io *io, void *user_data)
  355. {
  356. struct l_dbus_classic *classic = user_data;
  357. struct l_dbus *dbus = &classic->super;
  358. char buffer[64];
  359. char *ptr, *end;
  360. ssize_t offset, len;
  361. int fd;
  362. fd = l_io_get_fd(io);
  363. ptr = buffer;
  364. offset = 0;
  365. while (1) {
  366. len = L_TFR(recv(fd, ptr + offset,
  367. sizeof(buffer) - offset,
  368. MSG_DONTWAIT));
  369. if (len < 0) {
  370. if (errno != EAGAIN)
  371. return false;
  372. break;
  373. }
  374. offset += len;
  375. }
  376. ptr = buffer;
  377. len = offset;
  378. if (!ptr || len < 3)
  379. return true;
  380. end = strstr(ptr, "\r\n");
  381. if (!end)
  382. return true;
  383. if (end - ptr + 2 != len)
  384. return true;
  385. l_util_hexdump(true, ptr, len, dbus->debug_handler, dbus->debug_data);
  386. *end = '\0';
  387. switch (classic->auth_state) {
  388. case WAITING_FOR_OK:
  389. if (!strncmp(ptr, "OK ", 3)) {
  390. enum auth_state state;
  391. const char *command;
  392. if (dbus->negotiate_unix_fd) {
  393. command = "NEGOTIATE_UNIX_FD\r\n";
  394. state = WAITING_FOR_AGREE_UNIX_FD;
  395. } else {
  396. command = "BEGIN\r\n";
  397. state = SETUP_DONE;
  398. }
  399. l_free(dbus->guid);
  400. dbus->guid = l_strdup(ptr + 3);
  401. classic->auth_command = l_strdup(command);
  402. classic->auth_state = state;
  403. break;
  404. } else if (!strncmp(ptr, "REJECTED ", 9)) {
  405. static const char *command = "AUTH ANONYMOUS\r\n";
  406. dbus->negotiate_unix_fd = true;
  407. classic->auth_command = l_strdup(command);
  408. classic->auth_state = WAITING_FOR_OK;
  409. }
  410. break;
  411. case WAITING_FOR_AGREE_UNIX_FD:
  412. if (!strncmp(ptr, "AGREE_UNIX_FD", 13)) {
  413. static const char *command = "BEGIN\r\n";
  414. dbus->support_unix_fd = true;
  415. classic->auth_command = l_strdup(command);
  416. classic->auth_state = SETUP_DONE;
  417. break;
  418. } else if (!strncmp(ptr, "ERROR", 5)) {
  419. static const char *command = "BEGIN\r\n";
  420. dbus->support_unix_fd = false;
  421. classic->auth_command = l_strdup(command);
  422. classic->auth_state = SETUP_DONE;
  423. break;
  424. }
  425. break;
  426. case SETUP_DONE:
  427. break;
  428. }
  429. l_io_set_write_handler(io, auth_write_handler, dbus, NULL);
  430. return true;
  431. }
  432. static void disconnect_handler(struct l_io *io, void *user_data)
  433. {
  434. struct l_dbus *dbus = user_data;
  435. dbus->is_ready = false;
  436. l_util_debug(dbus->debug_handler, dbus->debug_data, "disconnect");
  437. if (dbus->disconnect_handler)
  438. dbus->disconnect_handler(dbus->disconnect_data);
  439. }
  440. static void dbus_init(struct l_dbus *dbus, int fd)
  441. {
  442. dbus->io = l_io_new(fd);
  443. l_io_set_close_on_destroy(dbus->io, true);
  444. l_io_set_disconnect_handler(dbus->io, disconnect_handler, dbus, NULL);
  445. dbus->is_ready = false;
  446. dbus->next_id = 1;
  447. dbus->next_serial = 1;
  448. dbus->message_queue = l_queue_new();
  449. dbus->message_list = l_hashmap_new();
  450. dbus->signal_list = l_hashmap_new();
  451. dbus->tree = _dbus_object_tree_new();
  452. }
  453. static void classic_free(struct l_dbus *dbus)
  454. {
  455. struct l_dbus_classic *classic =
  456. l_container_of(dbus, struct l_dbus_classic, super);
  457. unsigned int i;
  458. for (i = 0; i < classic->num_fds; i++)
  459. close(classic->fd_buf[i]);
  460. l_free(classic->fd_buf);
  461. l_free(classic->auth_command);
  462. l_hashmap_destroy(classic->match_strings, l_free);
  463. l_free(classic);
  464. }
  465. static bool classic_send_message(struct l_dbus *dbus,
  466. struct l_dbus_message *message)
  467. {
  468. int fd = l_io_get_fd(dbus->io);
  469. struct msghdr msg;
  470. struct iovec iov[2], *iovpos;
  471. ssize_t r;
  472. int *fds = NULL;
  473. uint32_t num_fds = 0;
  474. struct cmsghdr *cmsg;
  475. int iovlen;
  476. iov[0].iov_base = _dbus_message_get_header(message, &iov[0].iov_len);
  477. iov[1].iov_base = _dbus_message_get_body(message, &iov[1].iov_len);
  478. if (dbus->support_unix_fd)
  479. fds = _dbus_message_get_fds(message, &num_fds);
  480. iovpos = iov;
  481. iovlen = 2;
  482. while (1) {
  483. memset(&msg, 0, sizeof(msg));
  484. msg.msg_iov = iovpos;
  485. msg.msg_iovlen = iovlen;
  486. if (num_fds) {
  487. msg.msg_control =
  488. alloca(CMSG_SPACE(num_fds * sizeof(int)));
  489. msg.msg_controllen = CMSG_LEN(num_fds * sizeof(int));
  490. cmsg = CMSG_FIRSTHDR(&msg);
  491. cmsg->cmsg_len = msg.msg_controllen;
  492. cmsg->cmsg_level = SOL_SOCKET;
  493. cmsg->cmsg_type = SCM_RIGHTS;
  494. memcpy(CMSG_DATA(cmsg), fds, num_fds * sizeof(int));
  495. }
  496. r = L_TFR(sendmsg(fd, &msg, 0));
  497. if (r < 0)
  498. return false;
  499. while ((size_t) r >= iovpos->iov_len) {
  500. r -= iovpos->iov_len;
  501. iovpos++;
  502. iovlen--;
  503. if (!iovlen)
  504. break;
  505. }
  506. if (!iovlen)
  507. break;
  508. iovpos->iov_base += r;
  509. iovpos->iov_len -= r;
  510. /* The FDs have been transmitted, don't retransmit */
  511. num_fds = 0;
  512. }
  513. return true;
  514. }
  515. static struct l_dbus_message *classic_recv_message(struct l_dbus *dbus)
  516. {
  517. struct l_dbus_classic *classic =
  518. l_container_of(dbus, struct l_dbus_classic, super);
  519. int fd = l_io_get_fd(dbus->io);
  520. struct dbus_header hdr;
  521. struct msghdr msg;
  522. struct iovec iov[2], *iovpos;
  523. struct cmsghdr *cmsg;
  524. ssize_t len, r;
  525. void *header, *body;
  526. size_t header_size, body_size;
  527. union {
  528. uint8_t bytes[CMSG_SPACE(16 * sizeof(int))];
  529. struct cmsghdr align;
  530. } fd_buf;
  531. int *fds = NULL;
  532. uint32_t num_fds = 0;
  533. int iovlen;
  534. struct l_dbus_message *message;
  535. unsigned int i;
  536. len = recv(fd, &hdr, DBUS_HEADER_SIZE, MSG_PEEK | MSG_DONTWAIT);
  537. if (len != DBUS_HEADER_SIZE)
  538. return NULL;
  539. header_size = align_len(DBUS_HEADER_SIZE + hdr.dbus1.field_length, 8);
  540. header = l_malloc(header_size);
  541. body_size = hdr.dbus1.body_length;
  542. body = l_malloc(body_size);
  543. iov[0].iov_base = header;
  544. iov[0].iov_len = header_size;
  545. iov[1].iov_base = body;
  546. iov[1].iov_len = body_size;
  547. iovpos = iov;
  548. iovlen = 2;
  549. while (1) {
  550. memset(&msg, 0, sizeof(msg));
  551. msg.msg_iov = iovpos;
  552. msg.msg_iovlen = iovlen;
  553. msg.msg_control = &fd_buf;
  554. msg.msg_controllen = sizeof(fd_buf);
  555. r = L_TFR(recvmsg(fd, &msg,
  556. MSG_CMSG_CLOEXEC | MSG_WAITALL));
  557. if (r < 0)
  558. goto cmsg_fail;
  559. for (cmsg = CMSG_FIRSTHDR(&msg); cmsg;
  560. cmsg = CMSG_NXTHDR(&msg, cmsg)) {
  561. if (cmsg->cmsg_level != SOL_SOCKET ||
  562. cmsg->cmsg_type != SCM_RIGHTS)
  563. continue;
  564. num_fds = (cmsg->cmsg_len - CMSG_LEN(0)) / sizeof(int);
  565. fds = (void *) CMSG_DATA(cmsg);
  566. /* Set FD_CLOEXEC on all file descriptors */
  567. for (i = 0; i < num_fds; i++) {
  568. long flags;
  569. flags = fcntl(fds[i], F_GETFD, NULL);
  570. if (flags < 0)
  571. continue;
  572. if (!(flags & FD_CLOEXEC))
  573. fcntl(fds[i], F_SETFD,
  574. flags | FD_CLOEXEC);
  575. }
  576. classic->fd_buf = l_realloc(classic->fd_buf,
  577. (classic->num_fds + num_fds) *
  578. sizeof(int));
  579. memcpy(classic->fd_buf + classic->num_fds, fds,
  580. num_fds * sizeof(int));
  581. classic->num_fds += num_fds;
  582. }
  583. while ((size_t) r >= iovpos->iov_len) {
  584. r -= iovpos->iov_len;
  585. iovpos++;
  586. iovlen--;
  587. if (!iovlen)
  588. break;
  589. }
  590. if (!iovlen)
  591. break;
  592. iovpos->iov_base += r;
  593. iovpos->iov_len -= r;
  594. }
  595. if (hdr.endian != DBUS_NATIVE_ENDIAN) {
  596. l_util_debug(dbus->debug_handler,
  597. dbus->debug_data, "Endianness incorrect");
  598. goto bad_msg;
  599. }
  600. if (hdr.version != 1) {
  601. l_util_debug(dbus->debug_handler,
  602. dbus->debug_data, "Protocol version incorrect");
  603. goto bad_msg;
  604. }
  605. num_fds = _dbus_message_unix_fds_from_header(header, header_size);
  606. if (num_fds > classic->num_fds)
  607. goto bad_msg;
  608. message = dbus_message_build(header, header_size, body, body_size,
  609. classic->fd_buf, num_fds);
  610. if (message && num_fds) {
  611. if (classic->num_fds > num_fds) {
  612. memmove(classic->fd_buf, classic->fd_buf + num_fds,
  613. (classic->num_fds - num_fds) * sizeof(int));
  614. classic->num_fds -= num_fds;
  615. } else {
  616. l_free(classic->fd_buf);
  617. classic->fd_buf = NULL;
  618. classic->num_fds = 0;
  619. }
  620. }
  621. if (message)
  622. return message;
  623. bad_msg:
  624. cmsg_fail:
  625. for (i = 0; i < classic->num_fds; i++)
  626. close(classic->fd_buf[i]);
  627. l_free(classic->fd_buf);
  628. classic->fd_buf = NULL;
  629. classic->num_fds = 0;
  630. l_free(header);
  631. l_free(body);
  632. return NULL;
  633. }
  634. static bool classic_add_match(struct l_dbus *dbus, unsigned int id,
  635. const struct _dbus_filter_condition *rule,
  636. int rule_len)
  637. {
  638. struct l_dbus_classic *classic =
  639. l_container_of(dbus, struct l_dbus_classic, super);
  640. char *match_str;
  641. struct l_dbus_message *message;
  642. match_str = _dbus_filter_rule_to_str(rule, rule_len);
  643. l_hashmap_insert(classic->match_strings, L_UINT_TO_PTR(id), match_str);
  644. message = l_dbus_message_new_method_call(dbus,
  645. DBUS_SERVICE_DBUS,
  646. DBUS_PATH_DBUS,
  647. L_DBUS_INTERFACE_DBUS,
  648. "AddMatch");
  649. l_dbus_message_set_arguments(message, "s", match_str);
  650. send_message(dbus, false, message, NULL, NULL, NULL);
  651. return true;
  652. }
  653. static bool classic_remove_match(struct l_dbus *dbus, unsigned int id)
  654. {
  655. struct l_dbus_classic *classic =
  656. l_container_of(dbus, struct l_dbus_classic, super);
  657. char *match_str = l_hashmap_remove(classic->match_strings,
  658. L_UINT_TO_PTR(id));
  659. struct l_dbus_message *message;
  660. if (!match_str)
  661. return false;
  662. message = l_dbus_message_new_method_call(dbus,
  663. DBUS_SERVICE_DBUS,
  664. DBUS_PATH_DBUS,
  665. L_DBUS_INTERFACE_DBUS,
  666. "RemoveMatch");
  667. l_dbus_message_set_arguments(message, "s", match_str);
  668. send_message(dbus, false, message, NULL, NULL, NULL);
  669. l_free(match_str);
  670. return true;
  671. }
  672. static void name_owner_changed_cb(struct l_dbus_message *message,
  673. void *user_data)
  674. {
  675. struct l_dbus *dbus = user_data;
  676. char *name, *old, *new;
  677. if (!l_dbus_message_get_arguments(message, "sss", &name, &old, &new))
  678. return;
  679. _dbus_name_cache_notify(dbus->name_cache, name, new);
  680. }
  681. struct get_name_owner_request {
  682. struct l_dbus_message *message;
  683. struct l_dbus *dbus;
  684. };
  685. static void get_name_owner_reply_cb(struct l_dbus_message *reply,
  686. void *user_data)
  687. {
  688. struct get_name_owner_request *req = user_data;
  689. const char *name, *owner;
  690. /* No name owner yet */
  691. if (l_dbus_message_is_error(reply))
  692. return;
  693. /* Shouldn't happen */
  694. if (!l_dbus_message_get_arguments(reply, "s", &owner))
  695. return;
  696. /* Shouldn't happen */
  697. if (!l_dbus_message_get_arguments(req->message, "s", &name))
  698. return;
  699. _dbus_name_cache_notify(req->dbus->name_cache, name, owner);
  700. }
  701. static bool classic_get_name_owner(struct l_dbus *bus, const char *name)
  702. {
  703. struct get_name_owner_request *req;
  704. /* Name resolution is not performed for DBUS_SERVICE_DBUS */
  705. if (!strcmp(name, DBUS_SERVICE_DBUS))
  706. return false;
  707. req = l_new(struct get_name_owner_request, 1);
  708. req->dbus = bus;
  709. req->message = l_dbus_message_new_method_call(bus,
  710. DBUS_SERVICE_DBUS,
  711. DBUS_PATH_DBUS,
  712. L_DBUS_INTERFACE_DBUS,
  713. "GetNameOwner");
  714. l_dbus_message_set_arguments(req->message, "s", name);
  715. send_message(bus, false, req->message, get_name_owner_reply_cb,
  716. req, l_free);
  717. if (!bus->name_notify_enabled) {
  718. static struct _dbus_filter_condition rule[] = {
  719. { L_DBUS_MATCH_TYPE, "signal" },
  720. { L_DBUS_MATCH_SENDER, DBUS_SERVICE_DBUS },
  721. { L_DBUS_MATCH_PATH, DBUS_PATH_DBUS },
  722. { L_DBUS_MATCH_INTERFACE, L_DBUS_INTERFACE_DBUS },
  723. { L_DBUS_MATCH_MEMBER, "NameOwnerChanged" },
  724. };
  725. if (!bus->filter)
  726. bus->filter = _dbus_filter_new(bus,
  727. &bus->driver->filter_ops,
  728. bus->name_cache);
  729. _dbus_filter_add_rule(bus->filter, rule, L_ARRAY_SIZE(rule),
  730. name_owner_changed_cb, bus);
  731. bus->name_notify_enabled = true;
  732. }
  733. return true;
  734. }
  735. struct name_request {
  736. l_dbus_name_acquire_func_t callback;
  737. void *user_data;
  738. struct l_dbus *dbus;
  739. };
  740. enum dbus_name_flag {
  741. DBUS_NAME_FLAG_ALLOW_REPLACEMENT = 0x1,
  742. DBUS_NAME_FLAG_REPLACE_EXISTING = 0x2,
  743. DBUS_NAME_FLAG_DO_NOT_QUEUE = 0x4,
  744. };
  745. enum dbus_name_reply {
  746. DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER = 1,
  747. DBUS_REQUEST_NAME_REPLY_IN_QUEUE = 2,
  748. DBUS_REQUEST_NAME_REPLY_EXISTS = 3,
  749. DBUS_REQUEST_NAME_REPLY_ALREADY_OWNER = 4,
  750. };
  751. static void request_name_reply_cb(struct l_dbus_message *reply, void *user_data)
  752. {
  753. struct name_request *req = user_data;
  754. bool success = false, queued = false;
  755. uint32_t retval;
  756. if (!req->callback)
  757. return;
  758. /* No name owner yet */
  759. if (l_dbus_message_is_error(reply))
  760. goto call_back;
  761. /* Shouldn't happen */
  762. if (!l_dbus_message_get_arguments(reply, "u", &retval))
  763. goto call_back;
  764. success = (retval == DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER) ||
  765. (retval == DBUS_REQUEST_NAME_REPLY_ALREADY_OWNER) ||
  766. (retval == DBUS_REQUEST_NAME_REPLY_IN_QUEUE);
  767. queued = (retval == DBUS_REQUEST_NAME_REPLY_IN_QUEUE);
  768. call_back:
  769. req->callback(req->dbus, success, queued, req->user_data);
  770. }
  771. static uint32_t classic_name_acquire(struct l_dbus *dbus, const char *name,
  772. bool allow_replacement,
  773. bool replace_existing, bool queue,
  774. l_dbus_name_acquire_func_t callback,
  775. void *user_data)
  776. {
  777. struct name_request *req;
  778. struct l_dbus_message *message;
  779. uint32_t flags = 0;
  780. req = l_new(struct name_request, 1);
  781. req->dbus = dbus;
  782. req->user_data = user_data;
  783. req->callback = callback;
  784. message = l_dbus_message_new_method_call(dbus, DBUS_SERVICE_DBUS,
  785. DBUS_PATH_DBUS,
  786. L_DBUS_INTERFACE_DBUS,
  787. "RequestName");
  788. if (allow_replacement)
  789. flags |= DBUS_NAME_FLAG_ALLOW_REPLACEMENT;
  790. if (replace_existing)
  791. flags |= DBUS_NAME_FLAG_REPLACE_EXISTING;
  792. if (!queue)
  793. flags |= DBUS_NAME_FLAG_DO_NOT_QUEUE;
  794. l_dbus_message_set_arguments(message, "su", name, flags);
  795. return send_message(dbus, false, message, request_name_reply_cb,
  796. req, free);
  797. }
  798. static const struct l_dbus_ops classic_ops = {
  799. .version = 1,
  800. .send_message = classic_send_message,
  801. .recv_message = classic_recv_message,
  802. .free = classic_free,
  803. .name_ops = {
  804. .get_name_owner = classic_get_name_owner,
  805. },
  806. .filter_ops = {
  807. .add_match = classic_add_match,
  808. .remove_match = classic_remove_match,
  809. },
  810. .name_acquire = classic_name_acquire,
  811. };
  812. static struct l_dbus *setup_dbus1(int fd, const char *guid)
  813. {
  814. static const unsigned char creds = 0x00;
  815. char uid[6], hexuid[12], *ptr = hexuid;
  816. struct l_dbus *dbus;
  817. struct l_dbus_classic *classic;
  818. ssize_t written;
  819. unsigned int i;
  820. if (snprintf(uid, sizeof(uid), "%d", geteuid()) < 1) {
  821. close(fd);
  822. return NULL;
  823. }
  824. for (i = 0; i < strlen(uid); i++)
  825. ptr += sprintf(ptr, "%02x", uid[i]);
  826. /* Send special credentials-passing nul byte */
  827. written = L_TFR(send(fd, &creds, 1, 0));
  828. if (written < 1) {
  829. close(fd);
  830. return NULL;
  831. }
  832. classic = l_new(struct l_dbus_classic, 1);
  833. dbus = &classic->super;
  834. dbus->driver = &classic_ops;
  835. classic->match_strings = l_hashmap_new();
  836. dbus_init(dbus, fd);
  837. dbus->guid = l_strdup(guid);
  838. classic->auth_command = l_strdup_printf("AUTH EXTERNAL %s\r\n", hexuid);
  839. classic->auth_state = WAITING_FOR_OK;
  840. dbus->negotiate_unix_fd = true;
  841. dbus->support_unix_fd = false;
  842. l_io_set_read_handler(dbus->io, auth_read_handler, dbus, NULL);
  843. l_io_set_write_handler(dbus->io, auth_write_handler, dbus, NULL);
  844. return dbus;
  845. }
  846. static struct l_dbus *setup_unix(char *params)
  847. {
  848. char *path = NULL, *guid = NULL;
  849. bool abstract = false;
  850. struct sockaddr_un addr;
  851. size_t len;
  852. int fd;
  853. while (params) {
  854. char *key = strsep(&params, ",");
  855. char *value;
  856. if (!key)
  857. break;
  858. value = strchr(key, '=');
  859. if (!value)
  860. continue;
  861. *value++ = '\0';
  862. if (!strcmp(key, "path")) {
  863. path = value;
  864. abstract = false;
  865. } else if (!strcmp(key, "abstract")) {
  866. path = value;
  867. abstract = true;
  868. } else if (!strcmp(key, "guid"))
  869. guid = value;
  870. }
  871. if (!path)
  872. return NULL;
  873. fd = socket(PF_UNIX, SOCK_STREAM | SOCK_CLOEXEC, 0);
  874. if (fd < 0)
  875. return NULL;
  876. memset(&addr, 0, sizeof(addr));
  877. addr.sun_family = AF_UNIX;
  878. len = strlen(path);
  879. if (abstract) {
  880. if (len > sizeof(addr.sun_path) - 1) {
  881. close(fd);
  882. return NULL;
  883. }
  884. addr.sun_path[0] = '\0';
  885. strncpy(addr.sun_path + 1, path, sizeof(addr.sun_path) - 2);
  886. len++;
  887. } else {
  888. if (len > sizeof(addr.sun_path)) {
  889. close(fd);
  890. return NULL;
  891. }
  892. strncpy(addr.sun_path, path, sizeof(addr.sun_path) - 1);
  893. }
  894. if (connect(fd, (struct sockaddr *) &addr,
  895. sizeof(addr.sun_family) + len) < 0) {
  896. close(fd);
  897. return NULL;
  898. }
  899. return setup_dbus1(fd, guid);
  900. }
  901. static struct l_dbus *setup_address(const char *address)
  902. {
  903. struct l_dbus *dbus = NULL;
  904. char *address_copy;
  905. address_copy = strdupa(address);
  906. while (address_copy) {
  907. char *transport = strsep(&address_copy, ";");
  908. char *params;
  909. if (!transport)
  910. break;
  911. params = strchr(transport, ':');
  912. if (params)
  913. *params++ = '\0';
  914. if (!strcmp(transport, "unix")) {
  915. /* Function will modify params string */
  916. dbus = setup_unix(params);
  917. break;
  918. }
  919. }
  920. return dbus;
  921. }
  922. LIB_EXPORT struct l_dbus *l_dbus_new(const char *address)
  923. {
  924. if (unlikely(!address))
  925. return NULL;
  926. return setup_address(address);
  927. }
  928. LIB_EXPORT struct l_dbus *l_dbus_new_default(enum l_dbus_bus bus)
  929. {
  930. const char *address;
  931. switch (bus) {
  932. case L_DBUS_SYSTEM_BUS:
  933. address = getenv("DBUS_SYSTEM_BUS_ADDRESS");
  934. if (!address)
  935. address = DEFAULT_SYSTEM_BUS_ADDRESS;
  936. break;
  937. case L_DBUS_SESSION_BUS:
  938. address = getenv("DBUS_SESSION_BUS_ADDRESS");
  939. if (!address)
  940. return NULL;
  941. break;
  942. default:
  943. return NULL;
  944. }
  945. return setup_address(address);
  946. }
  947. LIB_EXPORT void l_dbus_destroy(struct l_dbus *dbus)
  948. {
  949. if (unlikely(!dbus))
  950. return;
  951. if (dbus->ready_destroy)
  952. dbus->ready_destroy(dbus->ready_data);
  953. _dbus_filter_free(dbus->filter);
  954. _dbus_name_cache_free(dbus->name_cache);
  955. l_hashmap_destroy(dbus->signal_list, signal_list_destroy);
  956. l_hashmap_destroy(dbus->message_list, message_list_destroy);
  957. l_queue_destroy(dbus->message_queue, message_queue_destroy);
  958. l_io_destroy(dbus->io);
  959. if (dbus->disconnect_destroy)
  960. dbus->disconnect_destroy(dbus->disconnect_data);
  961. if (dbus->debug_destroy)
  962. dbus->debug_destroy(dbus->debug_data);
  963. l_free(dbus->guid);
  964. l_free(dbus->unique_name);
  965. _dbus_object_tree_free(dbus->tree);
  966. dbus->driver->free(dbus);
  967. }
  968. LIB_EXPORT bool l_dbus_set_ready_handler(struct l_dbus *dbus,
  969. l_dbus_ready_func_t function,
  970. void *user_data, l_dbus_destroy_func_t destroy)
  971. {
  972. if (unlikely(!dbus))
  973. return false;
  974. if (dbus->ready_destroy)
  975. dbus->ready_destroy(dbus->ready_data);
  976. dbus->ready_handler = function;
  977. dbus->ready_destroy = destroy;
  978. dbus->ready_data = user_data;
  979. return true;
  980. }
  981. LIB_EXPORT bool l_dbus_set_disconnect_handler(struct l_dbus *dbus,
  982. l_dbus_disconnect_func_t function,
  983. void *user_data, l_dbus_destroy_func_t destroy)
  984. {
  985. if (unlikely(!dbus))
  986. return false;
  987. if (dbus->disconnect_destroy)
  988. dbus->disconnect_destroy(dbus->disconnect_data);
  989. dbus->disconnect_handler = function;
  990. dbus->disconnect_destroy = destroy;
  991. dbus->disconnect_data = user_data;
  992. return true;
  993. }
  994. LIB_EXPORT bool l_dbus_set_debug(struct l_dbus *dbus,
  995. l_dbus_debug_func_t function,
  996. void *user_data, l_dbus_destroy_func_t destroy)
  997. {
  998. if (unlikely(!dbus))
  999. return false;
  1000. if (dbus->debug_destroy)
  1001. dbus->debug_destroy(dbus->debug_data);
  1002. dbus->debug_handler = function;
  1003. dbus->debug_destroy = destroy;
  1004. dbus->debug_data = user_data;
  1005. /* l_io_set_debug(dbus->io, function, user_data, NULL); */
  1006. return true;
  1007. }
  1008. LIB_EXPORT uint32_t l_dbus_send_with_reply(struct l_dbus *dbus,
  1009. struct l_dbus_message *message,
  1010. l_dbus_message_func_t function,
  1011. void *user_data,
  1012. l_dbus_destroy_func_t destroy)
  1013. {
  1014. if (unlikely(!dbus || !message))
  1015. return 0;
  1016. return send_message(dbus, false, message, function, user_data, destroy);
  1017. }
  1018. LIB_EXPORT uint32_t l_dbus_send(struct l_dbus *dbus,
  1019. struct l_dbus_message *message)
  1020. {
  1021. if (unlikely(!dbus || !message))
  1022. return 0;
  1023. return send_message(dbus, false, message, NULL, NULL, NULL);
  1024. }
  1025. static bool remove_entry(void *data, void *user_data)
  1026. {
  1027. struct message_callback *callback = data;
  1028. uint32_t serial = L_PTR_TO_UINT(user_data);
  1029. if (callback->serial == serial) {
  1030. message_queue_destroy(callback);
  1031. return true;
  1032. }
  1033. return false;
  1034. }
  1035. LIB_EXPORT bool l_dbus_cancel(struct l_dbus *dbus, uint32_t serial)
  1036. {
  1037. struct message_callback *callback;
  1038. unsigned int count;
  1039. if (unlikely(!dbus || !serial))
  1040. return false;
  1041. callback = l_hashmap_remove(dbus->message_list, L_UINT_TO_PTR(serial));
  1042. if (callback) {
  1043. message_queue_destroy(callback);
  1044. return true;
  1045. }
  1046. count = l_queue_foreach_remove(dbus->message_queue, remove_entry,
  1047. L_UINT_TO_PTR(serial));
  1048. if (!count)
  1049. return false;
  1050. return true;
  1051. }
  1052. LIB_EXPORT unsigned int l_dbus_register(struct l_dbus *dbus,
  1053. l_dbus_message_func_t function,
  1054. void *user_data, l_dbus_destroy_func_t destroy)
  1055. {
  1056. struct signal_callback *callback;
  1057. if (unlikely(!dbus))
  1058. return 0;
  1059. callback = l_new(struct signal_callback, 1);
  1060. callback->id = dbus->next_id++;
  1061. callback->callback = function;
  1062. callback->destroy = destroy;
  1063. callback->user_data = user_data;
  1064. l_hashmap_insert(dbus->signal_list,
  1065. L_UINT_TO_PTR(callback->id), callback);
  1066. return callback->id;
  1067. }
  1068. LIB_EXPORT bool l_dbus_unregister(struct l_dbus *dbus, unsigned int id)
  1069. {
  1070. struct signal_callback *callback;
  1071. if (unlikely(!dbus || !id))
  1072. return false;
  1073. callback = l_hashmap_remove(dbus->signal_list, L_UINT_TO_PTR(id));
  1074. if (!callback)
  1075. return false;
  1076. signal_list_destroy(callback);
  1077. return true;
  1078. }
  1079. LIB_EXPORT uint32_t l_dbus_method_call(struct l_dbus *dbus,
  1080. const char *destination, const char *path,
  1081. const char *interface, const char *method,
  1082. l_dbus_message_func_t setup,
  1083. l_dbus_message_func_t function,
  1084. void *user_data, l_dbus_destroy_func_t destroy)
  1085. {
  1086. struct l_dbus_message *message;
  1087. if (unlikely(!dbus))
  1088. return 0;
  1089. message = l_dbus_message_new_method_call(dbus, destination, path,
  1090. interface, method);
  1091. if (setup)
  1092. setup(message, user_data);
  1093. else
  1094. l_dbus_message_set_arguments(message, "");
  1095. return send_message(dbus, false, message, function, user_data, destroy);
  1096. }
  1097. uint8_t _dbus_get_version(struct l_dbus *dbus)
  1098. {
  1099. return dbus->driver->version;
  1100. }
  1101. int _dbus_get_fd(struct l_dbus *dbus)
  1102. {
  1103. return l_io_get_fd(dbus->io);
  1104. }
  1105. struct _dbus_object_tree *_dbus_get_tree(struct l_dbus *dbus)
  1106. {
  1107. return dbus->tree;
  1108. }
  1109. /**
  1110. * l_dbus_register_interface:
  1111. * @dbus: D-Bus connection as returned by @l_dbus_new*
  1112. * @interface: interface name string
  1113. * @setup_func: function that sets up the methods, signals and properties by
  1114. * using the #dbus-service.h API.
  1115. * @destroy: optional destructor to be called every time an instance of this
  1116. * interface is being removed from an object on this bus.
  1117. * @handle_old_style_properties: whether to automatically handle SetProperty and
  1118. * GetProperties for any properties registered by
  1119. * @setup_func.
  1120. *
  1121. * Registers an interface. If successful the interface can then be added
  1122. * to any number of objects with @l_dbus_object_add_interface.
  1123. *
  1124. * Returns: whether the interface was successfully registered
  1125. **/
  1126. LIB_EXPORT bool l_dbus_register_interface(struct l_dbus *dbus,
  1127. const char *interface,
  1128. l_dbus_interface_setup_func_t setup_func,
  1129. l_dbus_destroy_func_t destroy,
  1130. bool handle_old_style_properties)
  1131. {
  1132. if (unlikely(!dbus))
  1133. return false;
  1134. if (unlikely(!dbus->tree))
  1135. return false;
  1136. return _dbus_object_tree_register_interface(dbus->tree, interface,
  1137. setup_func, destroy,
  1138. handle_old_style_properties);
  1139. }
  1140. LIB_EXPORT bool l_dbus_unregister_interface(struct l_dbus *dbus,
  1141. const char *interface)
  1142. {
  1143. if (unlikely(!dbus))
  1144. return false;
  1145. if (unlikely(!dbus->tree))
  1146. return false;
  1147. return _dbus_object_tree_unregister_interface(dbus->tree, interface);
  1148. }
  1149. /**
  1150. * l_dbus_register_object:
  1151. * @dbus: D-Bus connection
  1152. * @path: new object path
  1153. * @user_data: user pointer to be passed to @destroy if any
  1154. * @destroy: optional destructor to be called when object dropped from the tree
  1155. * @...: NULL-terminated list of 0 or more interfaces to be present on the
  1156. * object from the moment of creation. For every interface the interface
  1157. * name string is expected followed by the @user_data pointer same as
  1158. * would be passed as @l_dbus_object_add_interface's last two parameters.
  1159. *
  1160. * Create a new D-Bus object on the tree visible to D-Bus peers. For example:
  1161. * success = l_dbus_register_object(bus, "/org/example/ExampleManager",
  1162. * NULL, NULL,
  1163. * "org.example.Manager",
  1164. * manager_data,
  1165. * NULL);
  1166. *
  1167. * Returns: whether the object path was successfully registered
  1168. **/
  1169. LIB_EXPORT bool l_dbus_register_object(struct l_dbus *dbus, const char *path,
  1170. void *user_data,
  1171. l_dbus_destroy_func_t destroy, ...)
  1172. {
  1173. va_list args;
  1174. const char *interface;
  1175. void *if_user_data;
  1176. bool r = true;
  1177. if (unlikely(!dbus))
  1178. return false;
  1179. if (unlikely(!dbus->tree))
  1180. return false;
  1181. if (!_dbus_object_tree_new_object(dbus->tree, path, user_data, destroy))
  1182. return false;
  1183. va_start(args, destroy);
  1184. while ((interface = va_arg(args, const char *))) {
  1185. if_user_data = va_arg(args, void *);
  1186. if (!_dbus_object_tree_add_interface(dbus->tree, path,
  1187. interface,
  1188. if_user_data)) {
  1189. _dbus_object_tree_object_destroy(dbus->tree, path);
  1190. r = false;
  1191. break;
  1192. }
  1193. }
  1194. va_end(args);
  1195. return r;
  1196. }
  1197. LIB_EXPORT bool l_dbus_unregister_object(struct l_dbus *dbus,
  1198. const char *object)
  1199. {
  1200. if (unlikely(!dbus))
  1201. return false;
  1202. if (unlikely(!dbus->tree))
  1203. return false;
  1204. return _dbus_object_tree_object_destroy(dbus->tree, object);
  1205. }
  1206. /**
  1207. * l_dbus_object_add_interface:
  1208. * @dbus: D-Bus connection
  1209. * @object: object path as passed to @l_dbus_register_object
  1210. * @interface: interface name as passed to @l_dbus_register_interface
  1211. * @user_data: user data pointer to be passed to any method and property
  1212. * callbacks provided by the @setup_func and to the @destroy
  1213. * callback as passed to @l_dbus_register_interface
  1214. *
  1215. * Creates an instance of given interface at the given path in the
  1216. * connection's object tree. If no object was registered at this path
  1217. * before @l_dbus_register_object gets called automatically.
  1218. *
  1219. * The addition of an interface to the object may trigger a query of
  1220. * all the properties on this interface and
  1221. * #org.freedesktop.DBus.ObjectManager.InterfacesAdded signals.
  1222. *
  1223. * Returns: whether the interface was successfully added.
  1224. **/
  1225. LIB_EXPORT bool l_dbus_object_add_interface(struct l_dbus *dbus,
  1226. const char *object,
  1227. const char *interface,
  1228. void *user_data)
  1229. {
  1230. if (unlikely(!dbus))
  1231. return false;
  1232. if (unlikely(!dbus->tree))
  1233. return false;
  1234. return _dbus_object_tree_add_interface(dbus->tree, object, interface,
  1235. user_data);
  1236. }
  1237. LIB_EXPORT bool l_dbus_object_remove_interface(struct l_dbus *dbus,
  1238. const char *object,
  1239. const char *interface)
  1240. {
  1241. if (unlikely(!dbus))
  1242. return false;
  1243. if (unlikely(!dbus->tree))
  1244. return false;
  1245. return _dbus_object_tree_remove_interface(dbus->tree, object,
  1246. interface);
  1247. }
  1248. LIB_EXPORT void *l_dbus_object_get_data(struct l_dbus *dbus, const char *object,
  1249. const char *interface)
  1250. {
  1251. if (unlikely(!dbus))
  1252. return false;
  1253. if (unlikely(!dbus->tree))
  1254. return false;
  1255. return _dbus_object_tree_get_interface_data(dbus->tree, object,
  1256. interface);
  1257. }
  1258. LIB_EXPORT bool l_dbus_object_manager_enable(struct l_dbus *dbus,
  1259. const char *root)
  1260. {
  1261. if (unlikely(!dbus))
  1262. return false;
  1263. if (unlikely(!dbus->tree))
  1264. return false;
  1265. return _dbus_object_tree_add_interface(dbus->tree, root,
  1266. L_DBUS_INTERFACE_OBJECT_MANAGER,
  1267. dbus);
  1268. }
  1269. LIB_EXPORT unsigned int l_dbus_add_disconnect_watch(struct l_dbus *dbus,
  1270. const char *name,
  1271. l_dbus_watch_func_t disconnect_func,
  1272. void *user_data,
  1273. l_dbus_destroy_func_t destroy)
  1274. {
  1275. return l_dbus_add_service_watch(dbus, name, NULL, disconnect_func,
  1276. user_data, destroy);
  1277. }
  1278. LIB_EXPORT unsigned int l_dbus_add_service_watch(struct l_dbus *dbus,
  1279. const char *name,
  1280. l_dbus_watch_func_t connect_func,
  1281. l_dbus_watch_func_t disconnect_func,
  1282. void *user_data,
  1283. l_dbus_destroy_func_t destroy)
  1284. {
  1285. if (!name)
  1286. return 0;
  1287. if (!dbus->name_cache)
  1288. dbus->name_cache = _dbus_name_cache_new(dbus,
  1289. &dbus->driver->name_ops);
  1290. return _dbus_name_cache_add_watch(dbus->name_cache, name, connect_func,
  1291. disconnect_func, user_data,
  1292. destroy);
  1293. }
  1294. LIB_EXPORT bool l_dbus_remove_watch(struct l_dbus *dbus, unsigned int id)
  1295. {
  1296. if (!dbus->name_cache)
  1297. return false;
  1298. return _dbus_name_cache_remove_watch(dbus->name_cache, id);
  1299. }
  1300. /**
  1301. * l_dbus_add_signal_watch:
  1302. * @dbus: D-Bus connection
  1303. * @sender: bus name to match the signal sender against or NULL to
  1304. * match any sender
  1305. * @path: object path to match the signal path against or NULL to
  1306. * match any path
  1307. * @interface: interface name to match the signal interface against
  1308. * or NULL to match any interface
  1309. * @member: name to match the signal name against or NULL to match any
  1310. * signal
  1311. * @...: a list of further conditions to be met by the signal followed
  1312. * by three more mandatory parameters:
  1313. * enum l_dbus_match_type list_end_marker,
  1314. * l_dbus_message_func callback,
  1315. * void *user_data,
  1316. * The value L_DBUS_MATCH_NONE must be passed as the end of list
  1317. * marker, followed by the signal match callback and user_data.
  1318. * In the list, every condition is a pair of parameters:
  1319. * enum l_dbus_match_type match_type, const char *value.
  1320. *
  1321. * Subscribe to a group of signals based on a set of conditions that
  1322. * compare the signal's header fields and string arguments against given
  1323. * values. For example:
  1324. * signal_id = l_dbus_add_signal_watch(bus, "org.example", "/"
  1325. * "org.example.Manager",
  1326. * "PropertyChanged",
  1327. * L_DBUS_MATCH_ARGUMENT(0),
  1328. * "ExampleProperty",
  1329. * L_DBUS_MATCH_NONE
  1330. * manager_property_change_cb,
  1331. * NULL);
  1332. *
  1333. * Returns: a non-zero signal filter identifier that can be passed to
  1334. * l_dbus_remove_signal_watch to remove this filter rule, or
  1335. * zero on failure.
  1336. **/
  1337. LIB_EXPORT unsigned int l_dbus_add_signal_watch(struct l_dbus *dbus,
  1338. const char *sender,
  1339. const char *path,
  1340. const char *interface,
  1341. const char *member, ...)
  1342. {
  1343. struct _dbus_filter_condition *rule;
  1344. int rule_len;
  1345. va_list args;
  1346. const char *value;
  1347. l_dbus_message_func_t signal_func;
  1348. enum l_dbus_match_type type;
  1349. void *user_data;
  1350. unsigned int id;
  1351. va_start(args, member);
  1352. rule_len = 0;
  1353. while ((type = va_arg(args, enum l_dbus_match_type)) !=
  1354. L_DBUS_MATCH_NONE)
  1355. rule_len++;
  1356. va_end(args);
  1357. rule = l_new(struct _dbus_filter_condition, rule_len + 5);
  1358. rule_len = 0;
  1359. rule[rule_len].type = L_DBUS_MATCH_TYPE;
  1360. rule[rule_len++].value = "signal";
  1361. if (sender) {
  1362. rule[rule_len].type = L_DBUS_MATCH_SENDER;
  1363. rule[rule_len++].value = sender;
  1364. }
  1365. if (path) {
  1366. rule[rule_len].type = L_DBUS_MATCH_PATH;
  1367. rule[rule_len++].value = path;
  1368. }
  1369. if (interface) {
  1370. rule[rule_len].type = L_DBUS_MATCH_INTERFACE;
  1371. rule[rule_len++].value = interface;
  1372. }
  1373. if (member) {
  1374. rule[rule_len].type = L_DBUS_MATCH_MEMBER;
  1375. rule[rule_len++].value = member;
  1376. }
  1377. va_start(args, member);
  1378. while (true) {
  1379. type = va_arg(args, enum l_dbus_match_type);
  1380. if (type == L_DBUS_MATCH_NONE)
  1381. break;
  1382. value = va_arg(args, const char *);
  1383. rule[rule_len].type = type;
  1384. rule[rule_len++].value = value;
  1385. }
  1386. signal_func = va_arg(args, l_dbus_message_func_t);
  1387. user_data = va_arg(args, void *);
  1388. va_end(args);
  1389. if (!dbus->filter) {
  1390. if (!dbus->name_cache)
  1391. dbus->name_cache = _dbus_name_cache_new(dbus,
  1392. &dbus->driver->name_ops);
  1393. dbus->filter = _dbus_filter_new(dbus,
  1394. &dbus->driver->filter_ops,
  1395. dbus->name_cache);
  1396. }
  1397. id = _dbus_filter_add_rule(dbus->filter, rule, rule_len,
  1398. signal_func, user_data);
  1399. l_free(rule);
  1400. return id;
  1401. }
  1402. LIB_EXPORT bool l_dbus_remove_signal_watch(struct l_dbus *dbus, unsigned int id)
  1403. {
  1404. if (!dbus->filter)
  1405. return false;
  1406. return _dbus_filter_remove_rule(dbus->filter, id);
  1407. }
  1408. /**
  1409. * l_dbus_name_acquire:
  1410. * @dbus: D-Bus connection
  1411. * @name: Well-known bus name to be acquired
  1412. * @allow_replacement: Whether to allow another peer's name request to
  1413. * take the name ownership away from this connection
  1414. * @replace_existing: Whether to allow D-Bus to take the name's ownership
  1415. * away from another peer in case the name is already
  1416. * owned and allows replacement. Ignored if name is
  1417. * currently free.
  1418. * @queue: Whether to allow the name request to be queued by D-Bus in
  1419. * case it cannot be acquired now, rather than to return a failure.
  1420. * @callback: Callback to receive the request result when done.
  1421. *
  1422. * Acquire a well-known bus name (service name) on the bus.
  1423. *
  1424. * Returns: a non-zero request serial that can be passed to l_dbus_cancel
  1425. * while waiting for the callback or zero if the callback has
  1426. * has happened while l_dbus_name_acquire was running.
  1427. **/
  1428. LIB_EXPORT uint32_t l_dbus_name_acquire(struct l_dbus *dbus, const char *name,
  1429. bool allow_replacement, bool replace_existing,
  1430. bool queue, l_dbus_name_acquire_func_t callback,
  1431. void *user_data)
  1432. {
  1433. return dbus->driver->name_acquire(dbus, name, allow_replacement,
  1434. replace_existing, queue,
  1435. callback, user_data);
  1436. }